Checking incremental cache dump after make. Comparing it with dump after rebuild.

Original commit: 602642715c
This commit is contained in:
Evgeny Gerashchenko
2015-02-03 19:43:07 +03:00
parent 143ab5dad2
commit 75e5ee2fbf
2 changed files with 108 additions and 27 deletions
@@ -47,6 +47,8 @@ import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.storage.BuildDataPaths
import com.intellij.util.io.BooleanDataDescriptor
import java.util.ArrayList
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.utils.Printer
val INLINE_ANNOTATION_DESC = "Lkotlin/inline;"
@@ -100,6 +102,11 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
private val cacheFormatVersion = CacheFormatVersion(targetDataRoot)
TestOnly
public fun dump(): String {
return maps.map { it.dump() }.join("\n\n")
}
public fun saveFileToCache(sourceFiles: Collection<File>, classFile: File): RecompilationDecision {
if (classFile.extension.toLowerCase() != "class") return DO_NOTHING
@@ -231,6 +238,26 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
public fun close() {
storage.close()
}
TestOnly
public fun dump(): String {
return with(StringBuilder()) {
with(Printer(this)) {
println(this@BasicMap.javaClass.getSimpleName())
pushIndent()
for (key in storage.getAllKeysWithExistingMapping().sort()) {
println("$key -> ${dumpValue(storage[key])}")
}
popIndent()
}
this
}.toString()
}
protected abstract fun dumpValue(value: V): String
}
private abstract class ClassFileBasedMap<V> : BasicMap<V>() {
@@ -275,6 +302,10 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
public fun get(className: JvmClassName): ByteArray? {
return storage[className.getInternalName()]
}
override fun dumpValue(value: ByteArray): String {
return java.lang.Long.toHexString(value.md5())
}
}
private inner class ConstantsMap : ClassFileBasedMap<Map<String, Any>>() {
@@ -319,6 +350,19 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
}
return true
}
override fun dumpValue(value: Map<String, Any>): String {
return StringBuilder {
append("{")
for (key in value.keySet().sort()) {
if (length() != 1) {
append(", ")
}
append("$key -> ${value[key]}")
}
append("}")
}.toString()
}
}
private object ConstantsMapExternalizer : DataExternalizer<Map<String, Any>> {
@@ -437,6 +481,19 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
}
return true
}
override fun dumpValue(value: Map<String, Long>): String {
return StringBuilder {
append("{")
for (key in value.keySet().sort()) {
if (length() != 1) {
append(", ")
}
append("$key -> ${java.lang.Long.toHexString(value[key]!!)}")
}
append("}")
}.toString()
}
}
private object InlineFunctionsMapExternalizer : DataExternalizer<Map<String, Long>> {
@@ -484,6 +541,8 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
public fun get(sourceFile: File): String? {
return storage[sourceFile.getAbsolutePath()]
}
override fun dumpValue(value: String) = value
}
private inner class RemovedPackagePartMap : BasicMap<Boolean>() {
@@ -504,6 +563,8 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
public fun clear() {
storage.getAllKeysWithExistingMapping().forEach { storage.remove(it) }
}
override fun dumpValue(value: Boolean) = ""
}
enum class RecompilationDecision {
@@ -36,9 +36,11 @@ import org.jetbrains.jps.incremental.messages.BuildMessage
import kotlin.test.assertFalse
import java.util.regex.Pattern
import kotlin.test.assertEquals
import org.jetbrains.jps.model.java.JpsJavaDependencyExtension
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
import com.intellij.openapi.util.io.FileUtilRt
import org.jetbrains.jps.cmdline.ProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
class object {
@@ -65,7 +67,7 @@ public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
protected open val customTest: Boolean
get() = false
fun buildGetLog(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().all()): String {
fun build(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().all()): MakeResult {
val workDirPath = FileUtil.toSystemIndependentName(workDir.getAbsolutePath())
val logger = MyLogger(workDirPath)
val descriptor = createProjectDescriptor(BuildLoggingManager(logger))
@@ -78,10 +80,10 @@ public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
.map { it.getMessageText() }
.map { it.replaceAll("^.+:\\d+:\\s+", "").trim() }
.joinToString("\n")
return logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n"
return MakeResult(logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n", true, null)
}
else {
return logger.log
return MakeResult(logger.log, false, createMappingsDump(descriptor))
}
} finally {
descriptor.release()
@@ -89,16 +91,16 @@ public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
}
private fun initialMake() {
val log = buildGetLog()
assertFalse(COMPILATION_FAILED in log, "Initial make failed:\n$log")
val makeResult = build()
assertFalse(makeResult.makeFailed, "Initial make failed:\n$makeResult")
}
private fun make(): String {
return buildGetLog()
private fun make(): MakeResult {
return build()
}
private fun rebuild(): String {
return buildGetLog(CompileScopeTestBuilder.rebuild().allModules())
private fun rebuild(): MakeResult {
return build(CompileScopeTestBuilder.rebuild().allModules())
}
private fun getModificationsToPerform(moduleNames: Collection<String>?): List<List<Modification>> {
@@ -160,24 +162,28 @@ public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
}
}
private fun rebuildAndCheckOutput(lastMakeFailed: Boolean) {
private fun rebuildAndCheckOutput(makeOverallResult: MakeResult) {
val outDir = File(getAbsolutePath("out"))
val outAfterMake = File(getAbsolutePath("out-after-make"))
FileUtil.copyDir(outDir, outAfterMake)
val rebuildLog = rebuild()
val rebuildFailed = rebuildLog.contains(COMPILATION_FAILED)
assertEquals(rebuildFailed, lastMakeFailed, "Rebuild failed: $rebuildFailed, last make failed: $lastMakeFailed. Rebuild log: $rebuildLog")
val rebuildResult = rebuild()
assertEquals(rebuildResult.makeFailed, makeOverallResult.makeFailed,
"Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult")
assertEqualDirectories(outDir, outAfterMake, lastMakeFailed)
assertEqualDirectories(outDir, outAfterMake, makeOverallResult.makeFailed)
if (!makeOverallResult.makeFailed) {
TestCase.assertEquals(rebuildResult.mappingsDump, makeOverallResult.mappingsDump)
}
FileUtil.delete(outAfterMake)
}
private fun clearCachesRebuildAndCheckOutput(lastMakeFailed: Boolean) {
private fun clearCachesRebuildAndCheckOutput(makeOverallResult: MakeResult) {
FileUtil.delete(BuildDataPathsImpl(myDataStorageRoot).getDataStorageRoot()!!)
rebuildAndCheckOutput(lastMakeFailed)
rebuildAndCheckOutput(makeOverallResult)
}
private fun readModuleDependencies(): Map<String, List<String>>? {
@@ -207,31 +213,45 @@ public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
val moduleNames = configureModules()
initialMake()
val (log, lastMakeFailed) = performModificationsAndMake(moduleNames)
UsefulTestCase.assertSameLinesWithFile(File(testDataDir, "build.log").getAbsolutePath(), log)
val makeOverallResult = performModificationsAndMake(moduleNames)
UsefulTestCase.assertSameLinesWithFile(File(testDataDir, "build.log").getAbsolutePath(), makeOverallResult.log)
rebuildAndCheckOutput(lastMakeFailed)
clearCachesRebuildAndCheckOutput(lastMakeFailed)
rebuildAndCheckOutput(makeOverallResult)
clearCachesRebuildAndCheckOutput(makeOverallResult)
}
private fun createMappingsDump(project: ProjectDescriptor) =
createKotlinIncrementalCacheDump(project)
private data class MakeLogAndFailureFlag(val log: String, val makeFailed: Boolean)
private fun createKotlinIncrementalCacheDump(project: ProjectDescriptor): String {
return StringBuilder {
for (target in project.getBuildTargetIndex().getAllTargets().sortBy { it.getPresentableName() }) {
append("<target $target>\n")
append(project.dataManager.getKotlinCache(target).dump())
append("</target $target>\n\n\n")
}
}.toString()
}
private fun performModificationsAndMake(moduleNames: Set<String>?): MakeLogAndFailureFlag {
private data class MakeResult(val log: String, val makeFailed: Boolean, val mappingsDump: String?)
private fun performModificationsAndMake(moduleNames: Set<String>?): MakeResult {
val logs = ArrayList<String>()
val modifications = getModificationsToPerform(moduleNames)
var lastCompilationFailed = false
var lastMappingsDump: String? = null
for (step in modifications) {
step.forEach { it.perform(workDir) }
performAdditionalModifications()
val log = make()
lastCompilationFailed = log.contains(COMPILATION_FAILED)
logs.add(log)
val makeResult = make()
logs.add(makeResult.log)
lastCompilationFailed = makeResult.makeFailed
lastMappingsDump = makeResult.mappingsDump
}
return MakeLogAndFailureFlag(logs.join("\n\n"), lastCompilationFailed)
return MakeResult(logs.join("\n\n"), lastCompilationFailed, lastMappingsDump)
}
protected open fun performAdditionalModifications() {