Test versioning of experimental incremental compilation

Original commit: a8b551e518
This commit is contained in:
Alexey Tsvetkov
2015-11-16 16:01:41 +03:00
parent 7ae30369a7
commit 0eb4f20d14
23 changed files with 377 additions and 83 deletions
@@ -16,20 +16,17 @@
package org.jetbrains.kotlin.jps.build
import org.jetbrains.kotlin.jps.incremental.getKotlinCacheVersion
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider
abstract class AbstractIncrementalCacheVersionChangedTest : AbstractIncrementalJpsTest(allowNoFilesWithSuffixInTestData = true) {
override fun performAdditionalModifications(modifications: List<AbstractIncrementalJpsTest.Modification>) {
val targets = projectDescriptor.allModuleTargets
val paths = projectDescriptor.dataManager.dataPaths
for (target in targets) {
val cacheVersion = paths.getKotlinCacheVersion(target)
val cacheVersionFile = cacheVersion.formatVersionFile
if (cacheVersionFile.exists()) {
cacheVersionFile.writeText("777")
}
}
val cacheVersionProvider = CacheVersionProvider(projectDescriptor.dataManager.dataPaths)
val versions = getVersions(cacheVersionProvider, projectDescriptor.allModuleTargets)
val versionFiles = versions.map { it.formatVersionFile }.filter { it.exists() }
versionFiles.forEach { it.writeText("777") }
}
protected open fun getVersions(cacheVersionProvider: CacheVersionProvider, targets: Iterable<ModuleBuildTarget>) =
targets.map { cacheVersionProvider.normalVersion(it) }
}
@@ -77,6 +77,7 @@ public abstract class AbstractIncrementalJpsTest(
private val COMMANDS = listOf("new", "touch", "delete")
private val COMMANDS_AS_REGEX_PART = COMMANDS.joinToString("|")
private val COMMANDS_AS_MESSAGE_PART = COMMANDS.joinToString("/") { "\".$it\"" }
private val BUILD_LOG_FILE_NAME = "build.log"
}
protected open val enableExperimentalIncrementalCompilation = false
@@ -91,6 +92,8 @@ public abstract class AbstractIncrementalJpsTest(
protected val mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf()
protected open val experimentalBuildLogFileName = "experimental-ic-build.log"
private fun enableDebugLogging() {
com.intellij.openapi.diagnostic.Logger.setFactory(javaClass<TestLoggerFactory>())
TestLoggerFactory.dumpLogToStdout("")
@@ -313,6 +316,17 @@ public abstract class AbstractIncrementalJpsTest(
return result
}
protected fun createDefaultBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
incrementalMakeResults.joinToString("\n\n") { it.log }
protected open fun createExperimentalBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
buildString {
incrementalMakeResults.forEachIndexed { i, makeResult ->
append("\n========== Step #${i + 1} ============\n\n")
append(makeResult.log)
}
}
protected open fun doTest(testDataPath: String) {
testDataDir = File(testDataPath)
workDir = FileUtilRt.createTempDirectory(TEMP_DIRECTORY_TO_USE, "jps-build", null)
@@ -322,21 +336,15 @@ public abstract class AbstractIncrementalJpsTest(
val otherMakeResults = performModificationsAndMake(moduleNames)
val buildLogFile = File(testDataDir, "build.log")
val fullBuildLogFile = File(testDataDir, "experimental-ic-build.log")
val buildLogFile = File(testDataDir, BUILD_LOG_FILE_NAME)
val experimentalBuildLog = File(testDataDir, experimentalBuildLogFileName)
if (enableExperimentalIncrementalCompilation && fullBuildLogFile.exists()) {
val logs = buildString {
otherMakeResults.forEachIndexed { i, makeResult ->
append("\n========== Step #${i + 1} ============\n\n")
append(makeResult.log)
}
}
UsefulTestCase.assertSameLinesWithFile(fullBuildLogFile.absolutePath, logs)
if (enableExperimentalIncrementalCompilation && experimentalBuildLog.exists()) {
val logs = createExperimentalBuildLog(otherMakeResults)
UsefulTestCase.assertSameLinesWithFile(experimentalBuildLog.absolutePath, logs)
}
else if (buildLogFile.exists() || !allowNoBuildLogFileInTestData) {
val logs = otherMakeResults.joinToString("\n\n") { it.log }
val logs = createDefaultBuildLog(otherMakeResults)
UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, logs)
}
@@ -414,7 +422,7 @@ public abstract class AbstractIncrementalJpsTest(
return byteArrayOutputStream.toString()
}
private data class MakeResult(val log: String, val makeFailed: Boolean, val mappingsDump: String?)
protected data class MakeResult(val log: String, val makeFailed: Boolean, val mappingsDump: String?)
private fun performModificationsAndMake(moduleNames: Set<String>?): List<MakeResult> {
val results = arrayListOf<MakeResult>()
@@ -17,20 +17,26 @@
package org.jetbrains.kotlin.jps.build
import com.intellij.testFramework.UsefulTestCase
import org.jetbrains.jps.builders.BuildTarget
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.jps.incremental.getCacheDirectoryName
import org.jetbrains.kotlin.jps.incremental.getKotlinCacheVersion
import org.jetbrains.kotlin.jps.incremental.CacheVersion
import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
import org.jetbrains.kotlin.jps.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.utils.Printer
import java.io.File
public abstract class AbstractIncrementalLazyCachesTest : AbstractIncrementalJpsTest() {
protected open val expectedCachesFileName: String
get() = "expected-kotlin-caches.txt"
override fun doTest(testDataPath: String) {
try {
super.doTest(testDataPath)
val actual = dumpKotlinCachesFileNames()
val expectedFile = File(testDataPath, "expected-kotlin-caches.txt")
val expectedFile = File(testDataPath, expectedCachesFileName)
UsefulTestCase.assertSameLinesWithFile(expectedFile.canonicalPath, actual)
}
finally {
@@ -41,28 +47,37 @@ public abstract class AbstractIncrementalLazyCachesTest : AbstractIncrementalJps
override fun performAdditionalModifications(modifications: List<AbstractIncrementalJpsTest.Modification>) {
super.performAdditionalModifications(modifications)
var modified = 0
for (modification in modifications) {
if (!modification.path.endsWith("incremental_compilation_off")) continue
if (modification !is AbstractIncrementalJpsTest.ModifyContent) continue
when (modification) {
is AbstractIncrementalJpsTest.ModifyContent -> {
IncrementalCompilation.disableIncrementalCompilation()
when (File(modification.path).name) {
"incremental-compilation" -> {
if (modification.dataFile.readAsBool()) {
IncrementalCompilation.enableIncrementalCompilation()
}
else {
IncrementalCompilation.disableIncrementalCompilation()
}
}
is AbstractIncrementalJpsTest.DeleteFile -> {
IncrementalCompilation.enableIncrementalCompilation()
}
else -> {
throw IllegalStateException("Unknown modification type: ${modification.javaClass}")
"experimental-compilation" -> {
if (modification.dataFile.readAsBool()) {
IncrementalCompilation.enableExperimental()
}
else {
IncrementalCompilation.disableExperimental()
}
}
}
modified++
}
}
if (modified > 1) {
throw IllegalStateException("Incremental compilation was enabled/disable more than once")
fun File.readAsBool(): Boolean {
val content = this.readText()
return when (content.trim()) {
"on" -> true
"off" -> false
else -> throw IllegalStateException("$this content is expected to be 'on' or 'off'")
}
}
@@ -71,32 +86,44 @@ public abstract class AbstractIncrementalLazyCachesTest : AbstractIncrementalJps
val p = Printer(sb)
val targets = projectDescriptor.allModuleTargets
val paths = projectDescriptor.dataManager.dataPaths
val versionProvider = CacheVersionProvider(paths)
dumpCachesForTarget(p, paths, KotlinDataContainerTarget, versionProvider.dataContainerVersion())
for (target in targets.sortedBy { it.presentableName }) {
p.println(target)
p.pushIndent()
val cacheVersion = paths.getKotlinCacheVersion(target)
if (cacheVersion.formatVersionFile.exists()) {
p.println(cacheVersion.formatVersionFile.name)
}
val dataRoot = paths.getTargetDataRoot(target)
val cacheNames = kotlinCacheNames(dataRoot)
cacheNames.sorted().forEach { p.println(it) }
p.popIndent()
dumpCachesForTarget(p, paths, target, versionProvider.normalVersion(target), versionProvider.experimentalVersion(target))
}
return sb.toString()
}
private fun dumpCachesForTarget(p: Printer, paths: BuildDataPaths, target: BuildTarget<*>, vararg cacheVersions: CacheVersion) {
p.println(target)
p.pushIndent()
val dataRoot = paths.getTargetDataRoot(target)
cacheVersions
.map { it.formatVersionFile }
.filter { it.exists() }
.sortedBy { it.name }
.forEach { p.println(it.relativeTo(dataRoot)) }
val cacheNames = kotlinCacheNames(dataRoot)
cacheNames.sorted().forEach { p.println(it) }
p.popIndent()
}
private fun kotlinCacheNames(dataRoot: File): List<String> {
val cacheDir = File(dataRoot, getCacheDirectoryName())
val fileNames = cacheDir.list() ?: arrayOf()
val cacheFiles = fileNames
.map { File(cacheDir, it) }
.filter { it.isFile && it.extension == BasicMapsOwner.CACHE_EXTENSION }
return cacheFiles.map { it.name }
val result = arrayListOf<String>()
for (file in dataRoot.walk()) {
if (file.isFile && file.extension == BasicMapsOwner.CACHE_EXTENSION) {
result.add(file.relativeTo(dataRoot))
}
}
return result
}
}
@@ -0,0 +1,80 @@
/*
* Copyright 2010-2015 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.kotlin.jps.build;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class DataContainerVersionChangedTestGenerated extends AbstractDataContainerVersionChangedTest {
public void testAllFilesPresentInCacheVersionChanged() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged"), Pattern.compile("^([^\\.]+)$"), true);
}
@TestMetadata("exportedModule")
public void testExportedModule() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/");
doTest(fileName);
}
@TestMetadata("module1Modified")
public void testModule1Modified() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified/");
doTest(fileName);
}
@TestMetadata("module2Modified")
public void testModule2Modified() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module2Modified/");
doTest(fileName);
}
@TestMetadata("moduleWithConstantModified")
public void testModuleWithConstantModified() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/");
doTest(fileName);
}
@TestMetadata("moduleWithInlineModified")
public void testModuleWithInlineModified() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/");
doTest(fileName);
}
@TestMetadata("touchedFile")
public void testTouchedFile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile/");
doTest(fileName);
}
@TestMetadata("untouchedFiles")
public void testUntouchedFiles() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/cacheVersionChanged/untouchedFiles/");
doTest(fileName);
}
}
@@ -16,14 +16,34 @@
package org.jetbrains.kotlin.jps.build
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider
abstract class AbstractExperimentalIncrementalJpsTest : AbstractIncrementalJpsTest() {
override val enableExperimentalIncrementalCompilation = true
}
abstract class AbstractExperimentalIncrementalLazyCachesTest : AbstractIncrementalLazyCachesTest() {
override val enableExperimentalIncrementalCompilation = true
override val expectedCachesFileName: String
get() = "experimental-expected-kotlin-caches.txt"
}
abstract class AbstractExperimentalIncrementalCacheVersionChangedTest : AbstractIncrementalCacheVersionChangedTest() {
override val enableExperimentalIncrementalCompilation = true
override fun getVersions(cacheVersionProvider: CacheVersionProvider, targets: Iterable<ModuleBuildTarget>) =
targets.map { cacheVersionProvider.experimentalVersion(it) }
}
abstract class AbstractDataContainerVersionChangedTest : AbstractExperimentalIncrementalCacheVersionChangedTest() {
override val experimentalBuildLogFileName = "data-container-version-build.log"
override fun createExperimentalBuildLog(incrementalMakeResults: List<MakeResult>) =
createDefaultBuildLog(incrementalMakeResults)
override fun getVersions(cacheVersionProvider: CacheVersionProvider, targets: Iterable<ModuleBuildTarget>) =
listOf(cacheVersionProvider.dataContainerVersion())
}
@@ -1,4 +1,10 @@
Cleaning output files:
out/production/module5/module5/E.class
End of files
Compiling files:
module5/src/module5_E.java
End of files
Cleaning output files:
out/production/module4/module4/D.class
End of files
Compiling files:
@@ -0,0 +1,34 @@
Cleaning output files:
out/production/module5/module5/E.class
End of files
Compiling files:
module5/src/module5_E.java
End of files
Cleaning output files:
out/production/module4/module4/D.class
End of files
Compiling files:
module4/src/module4_d.kt
End of files
Cleaning output files:
out/production/module1/META-INF/module1.kotlin_module
out/production/module1/module1/A.class
out/production/module1/module1/Module1_aKt.class
End of files
Compiling files:
module1/src/module1_a.kt
End of files
Cleaning output files:
out/production/module2/META-INF/module2.kotlin_module
out/production/module2/module2/Module2_bKt.class
End of files
Compiling files:
module2/src/module2_b.kt
End of files
Cleaning output files:
out/production/module3/META-INF/module3.kotlin_module
out/production/module3/module3/Module3_cKt.class
End of files
Compiling files:
module3/src/module3_c.kt
End of files
@@ -0,0 +1,13 @@
Cleaning output files:
out/production/module1/META-INF/module1.kotlin_module
out/production/module1/a/Module1_AKt.class
End of files
Compiling files:
module1/src/module1_A.kt
End of files
Cleaning output files:
out/production/module2/b/B.class
End of files
Compiling files:
module2/src/module2_B.kt
End of files
@@ -0,0 +1,14 @@
Cleaning output files:
out/production/module1/META-INF/module1.kotlin_module
out/production/module1/a/A.class
out/production/module1/a/Module1_AKt.class
End of files
Compiling files:
module1/src/module1_A.kt
End of files
Cleaning output files:
out/production/module2/b/B.class
End of files
Compiling files:
module2/src/module2_B.kt
End of files
@@ -1,5 +1,6 @@
kotlin-data-container
Module 'module' production
format-version.txt
proto.tab
source-to-classes.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -0,0 +1,12 @@
kotlin-data-container
data-container-format-version.txt
counters.tab
file-to-id.tab
id-to-file.tab
lookups.tab
Module 'module' production
experimental-format-version.txt
format-version.txt
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -1,7 +1,8 @@
kotlin-data-container
Module 'module' production
format-version.txt
constants.tab
package-parts.tab
proto.tab
source-to-classes.tab
kotlin/constants.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -0,0 +1,14 @@
kotlin-data-container
data-container-format-version.txt
counters.tab
file-to-id.tab
id-to-file.tab
lookups.tab
Module 'module' production
experimental-format-version.txt
format-version.txt
kotlin/constants.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -1,6 +1,7 @@
kotlin-data-container
Module 'module' production
format-version.txt
package-parts.tab
proto.tab
source-to-classes.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -0,0 +1,13 @@
kotlin-data-container
data-container-format-version.txt
counters.tab
file-to-id.tab
id-to-file.tab
lookups.tab
Module 'module' production
experimental-format-version.txt
format-version.txt
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -1,8 +1,9 @@
kotlin-data-container
Module 'module' production
format-version.txt
inline-functions.tab
inlined-to.tab
package-parts.tab
proto.tab
source-to-classes.tab
kotlin/inline-functions.tab
kotlin/inlined-to.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -0,0 +1,15 @@
kotlin-data-container
data-container-format-version.txt
counters.tab
file-to-id.tab
id-to-file.tab
lookups.tab
Module 'module' production
experimental-format-version.txt
format-version.txt
kotlin/inline-functions.tab
kotlin/inlined-to.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -1,7 +1,8 @@
kotlin-data-container
Module 'module' production
format-version.txt
inline-functions.tab
package-parts.tab
proto.tab
source-to-classes.tab
kotlin/inline-functions.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -0,0 +1,14 @@
kotlin-data-container
data-container-format-version.txt
counters.tab
file-to-id.tab
id-to-file.tab
lookups.tab
Module 'module' production
experimental-format-version.txt
format-version.txt
kotlin/inline-functions.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -1,2 +1,4 @@
kotlin-data-container
Module 'module' production
format-version.txt
Module 'module' tests
@@ -0,0 +1,6 @@
kotlin-data-container
data-container-format-version.txt
Module 'module' production
experimental-format-version.txt
format-version.txt
Module 'module' tests
@@ -1,6 +1,7 @@
kotlin-data-container
Module 'module' production
format-version.txt
package-parts.tab
proto.tab
source-to-classes.tab
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests
@@ -0,0 +1,13 @@
kotlin-data-container
data-container-format-version.txt
counters.tab
file-to-id.tab
id-to-file.tab
lookups.tab
Module 'module' production
experimental-format-version.txt
format-version.txt
kotlin/package-parts.tab
kotlin/proto.tab
kotlin/source-to-classes.tab
Module 'module' tests