From e1a47deeaece2d78f21851e0957e648d3d113239 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 4 Feb 2014 21:56:23 +0400 Subject: [PATCH] Checking class files contents after make and rebuild. --- .../com/google/common/collect/annotations.xml | 4 + .../jetbrains/jps/builders/annotations.xml | 9 ++ .../jet/jps/build/IncrementalJpsTest.kt | 15 +- .../jet/jps/build/classFilesComparison.kt | 133 ++++++++++++++++++ 4 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt diff --git a/annotations/com/google/common/collect/annotations.xml b/annotations/com/google/common/collect/annotations.xml index ba6fd63e92d..0250409ed73 100644 --- a/annotations/com/google/common/collect/annotations.xml +++ b/annotations/com/google/common/collect/annotations.xml @@ -5,4 +5,8 @@ + + + \ No newline at end of file diff --git a/annotations/org/jetbrains/jps/builders/annotations.xml b/annotations/org/jetbrains/jps/builders/annotations.xml index bfd52dcca30..19c394bedbd 100644 --- a/annotations/org/jetbrains/jps/builders/annotations.xml +++ b/annotations/org/jetbrains/jps/builders/annotations.xml @@ -1,7 +1,16 @@ + + + + + + + + + diff --git a/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt b/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt index aca6d23a63d..0823675e211 100644 --- a/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt +++ b/jps-plugin/test/org/jetbrains/jet/jps/build/IncrementalJpsTest.kt @@ -52,8 +52,7 @@ public class IncrementalJpsTest : JpsBuildTestCase() { super.tearDown() } - fun makeAllGetLog(): String { - val scope = CompileScopeTestBuilder.make().all() + fun buildGetLog(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().all()): String { val logger = MyLogger(FileUtil.toSystemIndependentName(workDir.getAbsolutePath())) val descriptor = createProjectDescriptor(BuildLoggingManager(logger)) try { @@ -67,7 +66,7 @@ public class IncrementalJpsTest : JpsBuildTestCase() { private fun doTest() { addModule("module", array(getAbsolutePath("src")), null, null, addJdk("my jdk")) - makeAllGetLog() + buildGetLog() FileUtil.processFilesRecursively(testDataDir, { if (it!!.getName().endsWith(".new")) { @@ -77,8 +76,16 @@ public class IncrementalJpsTest : JpsBuildTestCase() { true }) - val log = makeAllGetLog() + val log = buildGetLog() UsefulTestCase.assertSameLinesWithFile(File(testDataDir, "build.log").getAbsolutePath(), log) + + val outDir = File(getAbsolutePath("out")) + val outAfterMake = File(getAbsolutePath("out-after-make")) + FileUtil.copyDir(outDir, outAfterMake) + + buildGetLog(CompileScopeTestBuilder.rebuild().allModules()) + + assertEqualDirectories(outDir, outAfterMake, { it.name == "script.xml" }) } override fun doGetProjectDir(): File? = workDir diff --git a/jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt b/jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt new file mode 100644 index 00000000000..8cd431c2296 --- /dev/null +++ b/jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt @@ -0,0 +1,133 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.jps.build + +import java.io.File +import org.junit.Assert.* +import org.jetbrains.asm4.util.TraceClassVisitor +import java.io.PrintWriter +import org.jetbrains.asm4.ClassReader +import java.io.StringWriter +import org.jetbrains.jet.utils.Printer +import com.google.common.io.Files +import com.google.common.hash.Hashing +import com.intellij.openapi.util.io.FileUtil +import com.google.common.collect.Sets +import java.util.HashSet +import com.intellij.openapi.vfs.local.CoreLocalFileSystem +import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass +import org.jetbrains.jet.storage.LockBasedStorageManager +import org.jetbrains.jet.lang.resolve.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor +import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader +import org.jetbrains.jet.descriptors.serialization.BitEncoding +import org.jetbrains.jet.descriptors.serialization.DebugJavaProtoBuf +import com.google.protobuf.ExtensionRegistry +import java.io.ByteArrayInputStream +import org.jetbrains.jet.descriptors.serialization.DebugProtoBuf +import java.util.Arrays + +fun File.hash() = Files.hash(this, Hashing.crc32()) + +fun getDirectoryString(dir: File, interestingPaths: List, ignore: (File) -> Boolean): String { + val buf = StringBuilder() + val p = Printer(buf) + + + fun addDirContent(dir: File) { + p.pushIndent() + + val listFiles = dir.listFiles() + assertNotNull(listFiles) + + val children = listFiles!!.toList().sortBy { it.getName() }.sortBy { it.isDirectory() } + for (child in children) { + if (ignore(child)) { + continue + } + + if (child.isDirectory()) { + p.println(child.name) + addDirContent(child) + } + else { + p.println(child.name, " ", child.hash()) + } + } + + p.popIndent() + } + + + p.println(".") + addDirContent(dir) + + for (path in interestingPaths) { + p.println("================", path, "================") + p.println(fileToStringRepresentation(File(dir, path))) + p.println() + p.println() + } + + return buf.toString() +} + +fun getAllRelativePaths(dir: File, ignore: (File) -> Boolean): Set { + val result = HashSet() + FileUtil.processFilesRecursively(dir) { + if (it!!.isFile() && !ignore(it)) { + result.add(FileUtil.getRelativePath(dir, it)!!) + } + + true + } + + return result +} + +fun assertEqualDirectories(expected: File, actual: File, ignore: (File) -> Boolean) { + val pathsInExpected = getAllRelativePaths(expected, ignore) + val pathsInActual = getAllRelativePaths(actual, ignore) + + val changedPaths = Sets.intersection(pathsInExpected, pathsInActual) + .filter { !Arrays.equals(File(expected, it).readBytes(), File(actual, it).readBytes()) } + .sort() + + val expectedString = getDirectoryString(expected, changedPaths, ignore) + val actualString = getDirectoryString(actual, changedPaths, ignore) + + assertEquals(expectedString, actualString) +} + +fun classFileToString(classFile: File): String { + val out = StringWriter() + val traceVisitor = TraceClassVisitor(PrintWriter(out)) + ClassReader(classFile.readBytes()).accept(traceVisitor, 0) + + // TODO serialize protobuf + return out.toString() +} + +fun fileToStringRepresentation(file: File): String { + return when { + file.name.endsWith(".class") -> { + classFileToString(file) + } + else -> { + file.readText() + } + } +}