diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt index 7891fcdfc3a..7d91b3cdc4e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseIncrementalGradleIT.kt @@ -1,80 +1,37 @@ package org.jetbrains.kotlin.gradle -import com.google.common.io.Files import org.gradle.api.logging.LogLevel import org.jetbrains.kotlin.gradle.incremental.BuildStep import org.jetbrains.kotlin.gradle.incremental.parseTestBuildLog +import org.jetbrains.kotlin.incremental.testingUtils.TouchPolicy +import org.jetbrains.kotlin.incremental.testingUtils.copyTestSources +import org.jetbrains.kotlin.incremental.testingUtils.getModificationsToPerform import org.junit.Assume import java.io.File -import java.util.* import kotlin.test.assertNotNull -import kotlin.test.assertTrue abstract class BaseIncrementalGradleIT : BaseGradleIT() { - open inner class IncrementalTestProject(name: String, wrapperVersion: String = "2.4", minLogLevel: LogLevel = LogLevel.DEBUG) : Project(name, wrapperVersion, minLogLevel) { - var modificationStage: Int = 1 - } - - inner class JpsTestProject(val resourcesBase: File, val relPath: String, wrapperVersion: String = "1.6", minLogLevel: LogLevel = LogLevel.DEBUG) : IncrementalTestProject(File(relPath).name, wrapperVersion, minLogLevel) { + inner class JpsTestProject(val resourcesBase: File, val relPath: String, wrapperVersion: String = "1.6", minLogLevel: LogLevel = LogLevel.DEBUG) : Project(File(relPath).name, wrapperVersion, minLogLevel) { override val resourcesRoot = File(resourcesBase, relPath) + val mapWorkingToOriginalFile = hashMapOf() override fun setupWorkingDir() { val srcDir = File(projectDir, "src") srcDir.mkdirs() - resourcesRoot.walk() - .filter { it.isFile && (it.name.endsWith(".kt") || it.name.endsWith(".java")) } - .forEach { Files.copy(it, File(srcDir, it.name)) } + val sourceMapping = copyTestSources(resourcesRoot, srcDir, filePrefix = "") + mapWorkingToOriginalFile.putAll(sourceMapping) copyDirRecursively(File(resourcesRootFile, "GradleWrapper-$wrapperVersion"), projectDir) copyDirRecursively(File(resourcesRootFile, "incrementalGradleProject"), projectDir) } } - fun IncrementalTestProject.modify(runStage: Int? = null) { - // TODO: multimodule support - val projectSrcDir = File(File(workingDir, projectName), "src") - assertTrue(projectSrcDir.exists()) - val actualStage = runStage ?: modificationStage - - println("<--- Modify stage: ${runStage?.toString() ?: "single"}") - - fun resource2project(f: File) = File(projectSrcDir, f.toRelativeString(resourcesRoot)) - - resourcesRoot.walk().filter { it.isFile }.forEach { - val nameParts = it.name.split(".") - if (nameParts.size > 2) { - val (fileStage, hasStage) = nameParts.last().toIntOr(0) - if (!hasStage || fileStage == actualStage) { - val orig = File(resource2project(it.parentFile), nameParts.dropLast(if (hasStage) 2 else 1).joinToString(".")) - when (if (hasStage) nameParts[nameParts.size - 2] else nameParts.last()) { - "touch" -> { - assert(orig.exists()) - orig.setLastModified(Date().time) - println("<--- Modify: touch $orig") - } - "new" -> { - it.copyTo(orig, overwrite = true) - orig.setLastModified(Date().time) - println("<--- Modify: new $orig from $it") - } - "delete" -> { - assert(orig.exists()) - orig.delete() - println("<--- Modify: delete $orig") - } - } - } - } + fun JpsTestProject.performAndAssertBuildStages(options: BuildOptions = defaultBuildOptions(), weakTesting: Boolean = false) { + // TODO: support multimodule tests + if (resourcesRoot.walk().filter { it.name.equals("dependencies.txt", ignoreCase = true) }.any()) { + Assume.assumeTrue("multimodule tests are not supported yet", false) } - modificationStage = actualStage + 1 - } - - fun IncrementalTestProject.performAndAssertBuildStages(options: BuildOptions = defaultBuildOptions(), weakTesting: Boolean = false) { - - val checkKnown = testIsKnownJpsTestProject(resourcesRoot) - Assume.assumeTrue(checkKnown.second ?: "", checkKnown.first) - build("build", options = options) { assertSuccessful() assertReportExists() @@ -83,27 +40,29 @@ abstract class BaseIncrementalGradleIT : BaseGradleIT() { val buildLogFile = resourcesRoot.listFiles { f: File -> f.name.endsWith("build.log") }?.sortedBy { it.length() }?.firstOrNull() assertNotNull(buildLogFile, "*build.log file not found" ) - val buildLog = parseTestBuildLog(buildLogFile!!) - assertTrue(buildLog.any()) + val buildLogSteps = parseTestBuildLog(buildLogFile!!) + val modifications = getModificationsToPerform(resourcesRoot, + moduleNames = null, + allowNoFilesWithSuffixInTestData = false, + touchPolicy = TouchPolicy.CHECKSUM) - println("<--- Build log size: ${buildLog.size}") - buildLog.forEach { - println("<--- Build log stage: ${if (it.compileSucceeded) "succeeded" else "failed"}: kotlin: ${it.compiledKotlinFiles} java: ${it.compiledJavaFiles}") + assert(modifications.size == buildLogSteps.size) { + "Modifications count (${modifications.size}) != expected build log steps count (${buildLogSteps.size})" } - if (buildLog.size == 1) { - modify() - buildAndAssertStageResults(buildLog.first(), weakTesting = weakTesting) + println("<--- Expected build log size: ${buildLogSteps.size}") + buildLogSteps.forEach { + println("<--- Expected build log stage: ${if (it.compileSucceeded) "succeeded" else "failed"}: kotlin: ${it.compiledKotlinFiles} java: ${it.compiledJavaFiles}") } - else { - buildLog.forEachIndexed { stage, stageResults -> - modify(stage + 1) - buildAndAssertStageResults(stageResults, weakTesting = weakTesting) - } + + + for ((modificationStep, buildLogStep) in modifications.zip(buildLogSteps)) { + modificationStep.forEach { it.perform(projectDir, mapWorkingToOriginalFile) } + buildAndAssertStageResults(buildLogStep, weakTesting = weakTesting) } } - fun IncrementalTestProject.buildAndAssertStageResults(expected: BuildStep, options: BuildOptions = defaultBuildOptions(), weakTesting: Boolean = false) { + fun JpsTestProject.buildAndAssertStageResults(expected: BuildStep, options: BuildOptions = defaultBuildOptions(), weakTesting: Boolean = false) { build("build", options = options) { if (expected.compileSucceeded) { assertSuccessful() @@ -117,43 +76,6 @@ abstract class BaseIncrementalGradleIT : BaseGradleIT() { } } - -private val supportedSourceExtensions = arrayListOf("kt", "java") -private val supportedModifyExtensions = arrayListOf("new", "delete") -private val unsupportedModifyExtensions = arrayListOf("touch") - -private fun String.toIntOr(defaultVal: Int): Pair { - try { - return Pair(toInt(), true) - } - catch (e: NumberFormatException) { - return Pair(defaultVal, false) - } -} - fun isJpsTestProject(projectRoot: File): Boolean = projectRoot.listFiles { f: File -> f.name.endsWith("build.log") }?.any() ?: false -fun testIsKnownJpsTestProject(projectRoot: File): Pair { - var hasKnownSources = false - projectRoot.walk().filter { it.isFile }.forEach { - if (it.name.equals("dependencies.txt", ignoreCase = true)) - return@testIsKnownJpsTestProject Pair(false, "multimodule tests are not supported yet") - val nameParts = it.name.split(".") - if (nameParts.size > 1) { - val (fileStage, hasStage) = nameParts.last().toIntOr(0) - val modifyExt = nameParts[nameParts.size - (if (hasStage) 2 else 1)] - val ext = nameParts[nameParts.size - (if (hasStage) 3 else 2)] - if (modifyExt in unsupportedModifyExtensions) - return@testIsKnownJpsTestProject Pair(false, "unsupported modification extension ${it.name}") - if (modifyExt in supportedModifyExtensions && ext !in supportedSourceExtensions) - return@testIsKnownJpsTestProject Pair(false, "unknown staged file ${it.name}") - } - if (!hasKnownSources && it.extension in supportedSourceExtensions) { - hasKnownSources = true - } - } - return if (hasKnownSources) Pair(true, null) - else Pair(false, "no known sources found") -} - diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIncrementalFromJpsIT.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIncrementalFromJpsIT.kt deleted file mode 100644 index 60091621a37..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIncrementalFromJpsIT.kt +++ /dev/null @@ -1,98 +0,0 @@ -package org.jetbrains.kotlin.gradle - -import org.junit.Test -import java.io.File - -class KotlinGradleIncrementalFromJpsIT(): BaseIncrementalGradleIT() { - - companion object { - val jpsResourcesPath = File("../../../jps-plugin/testData/incremental") - } - - override fun defaultBuildOptions(): BuildOptions = BuildOptions(withDaemon = true) - - @Test - fun testClassSignatureChanged() { - val project = JpsTestProject(jpsResourcesPath, "pureKotlin/classSignatureChanged", "2.4") - - project.build("build") { - assertSuccessful() - assertReportExists() - assertCompiledKotlinSources("src/class.kt", "src/usage.kt") - } - - project.modify() - - project.build("build") { - assertSuccessful() - assertCompiledKotlinSources("src/class.kt", "src/usage.kt") - } - } - - @Test - fun testKotlinInJavaFunRenamed() { - val project = JpsTestProject(jpsResourcesPath, "withJava/kotlinUsedInJava/funRenamed", "2.4") - - project.build("build") { - assertSuccessful() - assertReportExists() - assertCompiledKotlinSources("src/fun.kt") - assertCompiledJavaSources("src/WillBeUnresolved.java") - } - - project.modify() - - project.build("build") { - assertCompiledKotlinSources("src/fun.kt") - assertFailed() - } - } - - @Test - fun testJavaInKotlinChangeSignature() { - val project = JpsTestProject(jpsResourcesPath, "withJava/javaUsedInKotlin/changeSignature", "2.4") - - project.build("build") { - assertSuccessful() - assertReportExists() - assertCompiledKotlinSources("src/usage.kt") - assertCompiledJavaSources("src/JavaClass.java") - } - - project.modify() - - project.build("build") { - assertSuccessful() - assertCompiledKotlinSources("src/usage.kt") - assertCompiledJavaSources("src/JavaClass.java") - } - } - - @Test - fun testClassSignatureChangedAuto() { - val project = JpsTestProject(jpsResourcesPath, "pureKotlin/classSignatureChanged", "2.4") - - project.performAndAssertBuildStages() - } - - @Test - fun testAnnotationListChanged() { - val project = JpsTestProject(jpsResourcesPath, "classHierarchyAffected/annotationListChanged", "2.4") - - project.performAndAssertBuildStages() - } - - @Test - fun testClassBecameFinal() { - val project = JpsTestProject(jpsResourcesPath, "classHierarchyAffected/classBecameFinal", "2.4") - - project.performAndAssertBuildStages() - } - - @Test - fun testSupertypesListChanged() { - val project = JpsTestProject(jpsResourcesPath, "classHierarchyAffected/supertypesListChanged", "2.4") - - project.performAndAssertBuildStages() - } -}