Move incremental test modification utils to build-common

KT-8487

Original commit: 8df209b436
This commit is contained in:
Alexey Tsvetkov
2016-02-11 15:46:26 +03:00
parent 5bb64ee283
commit 0e2f3ab201
6 changed files with 11 additions and 170 deletions
@@ -17,8 +17,8 @@
package org.jetbrains.kotlin.jps.build
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.Modification
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.ModifyContent
import org.jetbrains.kotlin.incremental.testingUtils.Modification
import org.jetbrains.kotlin.incremental.testingUtils.ModifyContent
import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider
abstract class AbstractIncrementalCacheVersionChangedTest : AbstractIncrementalJpsTest(allowNoFilesWithSuffixInTestData = true) {
@@ -46,11 +46,11 @@ import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.incremental.LookupSymbol
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.testingUtils.Modification
import org.jetbrains.kotlin.incremental.testingUtils.TouchPolicy
import org.jetbrains.kotlin.incremental.testingUtils.copyTestSources
import org.jetbrains.kotlin.incremental.testingUtils.getModificationsToPerform
import org.jetbrains.kotlin.jps.build.classFilesComparison.assertEqualDirectories
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.Modification
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.TouchPolicy
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.copyTestSources
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.getModificationsToPerform
import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageProvider
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.incremental.CacheVersion
import org.jetbrains.kotlin.incremental.KOTLIN_CACHE_DIRECTORY_NAME
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.Modification
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.ModifyContent
import org.jetbrains.kotlin.incremental.testingUtils.Modification
import org.jetbrains.kotlin.incremental.testingUtils.ModifyContent
import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
import org.jetbrains.kotlin.utils.Printer
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.jps.build
import com.intellij.openapi.util.SystemInfoRt
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.Modification
import org.jetbrains.kotlin.incremental.testingUtils.Modification
class IncrementalProjectPathCaseChangedTest : AbstractIncrementalJpsTest(checkDumpsCaseInsensitively = true) {
fun testProjectPathCaseChanged() {
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.jps.build
import org.jetbrains.kotlin.incremental.testingUtils.Modification
open class IncrementalRenameModuleTest : AbstractIncrementalJpsTest() {
fun testRenameModule() {
doTest("jps-plugin/testData/incremental/custom/renameModule/")
@@ -1,161 +0,0 @@
/*
* Copyright 2010-2016 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.incrementalModificationUtils
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.jps.builders.JpsBuildTestCase
import java.io.File
import java.util.*
private val COMMANDS = listOf("new", "touch", "delete")
private val COMMANDS_AS_REGEX_PART = COMMANDS.joinToString("|")
private val COMMANDS_AS_MESSAGE_PART = COMMANDS.joinToString("/") { "\".$it\"" }
enum class TouchPolicy {
TIMESTAMP,
CHECKSUM
}
fun copyTestSources(testDataDir: File, sourceDestinationDir: File, filePrefix: String): Map<File, File> {
val mapping = hashMapOf<File, File>()
FileUtil.copyDir(testDataDir, sourceDestinationDir) {
it.isDirectory || it.name.startsWith(filePrefix) && (it.name.endsWith(".kt") || it.name.endsWith(".java"))
}
sourceDestinationDir.walk().forEach { mapping[it] = File(testDataDir, filePrefix + it.name) }
return mapping
}
fun getModificationsToPerform(
testDataDir: File,
moduleNames: Collection<String>?,
allowNoFilesWithSuffixInTestData: Boolean,
touchPolicy: TouchPolicy
): List<List<Modification>> {
fun getModificationsForIteration(newSuffix: String, touchSuffix: String, deleteSuffix: String): List<Modification> {
fun getDirPrefix(fileName: String): String {
val underscore = fileName.indexOf("_")
if (underscore != -1) {
val module = fileName.substring(0, underscore)
assert(moduleNames != null) { "File name has module prefix, but multi-module environment is absent" }
assert(module in moduleNames!!) { "Module not found for file with prefix: $fileName" }
return "$module/src"
}
assert(moduleNames == null) { "Test is multi-module, but file has no module prefix: $fileName" }
return "src"
}
val modifications = ArrayList<Modification>()
for (file in testDataDir.listFiles()!!) {
val fileName = file.name
if (fileName.endsWith(newSuffix)) {
modifications.add(ModifyContent(getDirPrefix(fileName) + "/" + fileName.removeSuffix(newSuffix), file))
}
if (fileName.endsWith(touchSuffix)) {
modifications.add(TouchFile(getDirPrefix(fileName) + "/" + fileName.removeSuffix(touchSuffix), touchPolicy))
}
if (fileName.endsWith(deleteSuffix)) {
modifications.add(DeleteFile(getDirPrefix(fileName) + "/" + fileName.removeSuffix(deleteSuffix)))
}
}
return modifications
}
val haveFilesWithoutNumbers = testDataDir.listFiles { it -> it.name.matches(".+\\.($COMMANDS_AS_REGEX_PART)$".toRegex()) }?.isNotEmpty() ?: false
val haveFilesWithNumbers = testDataDir.listFiles { it -> it.name.matches(".+\\.($COMMANDS_AS_REGEX_PART)\\.\\d+$".toRegex()) }?.isNotEmpty() ?: false
if (haveFilesWithoutNumbers && haveFilesWithNumbers) {
JpsBuildTestCase.fail("Bad test data format: files ending with both unnumbered and numbered $COMMANDS_AS_MESSAGE_PART were found")
}
if (!haveFilesWithoutNumbers && !haveFilesWithNumbers) {
if (allowNoFilesWithSuffixInTestData) {
return listOf(listOf())
}
else {
JpsBuildTestCase.fail("Bad test data format: no files ending with $COMMANDS_AS_MESSAGE_PART found")
}
}
if (haveFilesWithoutNumbers) {
return listOf(getModificationsForIteration(".new", ".touch", ".delete"))
}
else {
return (1..10)
.map { getModificationsForIteration(".new.$it", ".touch.$it", ".delete.$it") }
.filter { it.isNotEmpty() }
}
}
abstract class Modification(val path: String) {
abstract fun perform(workDir: File, mapping: MutableMap<File, File>)
override fun toString(): String = "${javaClass.simpleName} $path"
}
class ModifyContent(path: String, val dataFile: File) : Modification(path) {
override fun perform(workDir: File, mapping: MutableMap<File, File>) {
val file = File(workDir, path)
val oldLastModified = file.lastModified()
file.delete()
dataFile.copyTo(file)
val newLastModified = file.lastModified()
if (newLastModified <= oldLastModified) {
//Mac OS and some versions of Linux truncate timestamp to nearest second
file.setLastModified(oldLastModified + 1000)
}
mapping[file] = dataFile
}
}
class TouchFile(path: String, private val touchPolicy: TouchPolicy) : Modification(path) {
override fun perform(workDir: File, mapping: MutableMap<File, File>) {
val file = File(workDir, path)
when (touchPolicy) {
TouchPolicy.TIMESTAMP -> {
val oldLastModified = file.lastModified()
//Mac OS and some versions of Linux truncate timestamp to nearest second
file.setLastModified(Math.max(System.currentTimeMillis(), oldLastModified + 1000))
}
TouchPolicy.CHECKSUM -> {
file.appendText(" ")
}
}
}
}
class DeleteFile(path: String) : Modification(path) {
override fun perform(workDir: File, mapping: MutableMap<File, File>) {
val fileToDelete = File(workDir, path)
if (!fileToDelete.delete()) {
throw AssertionError("Couldn't delete $fileToDelete")
}
mapping.remove(fileToDelete)
}
}