Extract incremental test modification utils
KT-8487
This commit is contained in:
+3
-1
@@ -17,10 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.jps.build
|
package org.jetbrains.kotlin.jps.build
|
||||||
|
|
||||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
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.jps.incremental.CacheVersionProvider
|
import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider
|
||||||
|
|
||||||
abstract class AbstractIncrementalCacheVersionChangedTest : AbstractIncrementalJpsTest(allowNoFilesWithSuffixInTestData = true) {
|
abstract class AbstractIncrementalCacheVersionChangedTest : AbstractIncrementalJpsTest(allowNoFilesWithSuffixInTestData = true) {
|
||||||
override fun performAdditionalModifications(modifications: List<AbstractIncrementalJpsTest.Modification>) {
|
override fun performAdditionalModifications(modifications: List<Modification>) {
|
||||||
val modifiedFiles = modifications.filterIsInstance<ModifyContent>().map { it.path }
|
val modifiedFiles = modifications.filterIsInstance<ModifyContent>().map { it.path }
|
||||||
val paths = projectDescriptor.dataManager.dataPaths
|
val paths = projectDescriptor.dataManager.dataPaths
|
||||||
val targets = projectDescriptor.allModuleTargets
|
val targets = projectDescriptor.allModuleTargets
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
|
|||||||
import org.jetbrains.kotlin.incremental.LookupSymbol
|
import org.jetbrains.kotlin.incremental.LookupSymbol
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.jps.build.classFilesComparison.assertEqualDirectories
|
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.JpsLookupStorageProvider
|
||||||
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
|
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
|
||||||
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
|
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
|
||||||
@@ -75,9 +79,6 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
|
|
||||||
val DEBUG_LOGGING_ENABLED = System.getProperty("debug.logging.enabled") == "true"
|
val DEBUG_LOGGING_ENABLED = System.getProperty("debug.logging.enabled") == "true"
|
||||||
|
|
||||||
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"
|
private val BUILD_LOG_FILE_NAME = "build.log"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
|
|
||||||
protected var lookupsDuringTest: MutableSet<LookupSymbol> by Delegates.notNull()
|
protected var lookupsDuringTest: MutableSet<LookupSymbol> by Delegates.notNull()
|
||||||
|
|
||||||
protected val mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf()
|
protected var mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf()
|
||||||
|
|
||||||
protected open val experimentalBuildLogFileName = "experimental-ic-build.log"
|
protected open val experimentalBuildLogFileName = "experimental-ic-build.log"
|
||||||
|
|
||||||
@@ -207,68 +208,6 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
return build(CompileScopeTestBuilder.rebuild().allModules(), checkLookups = false)
|
return build(CompileScopeTestBuilder.rebuild().allModules(), checkLookups = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getModificationsToPerform(moduleNames: Collection<String>?): 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)))
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
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 {
|
|
||||||
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() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
private fun rebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
||||||
val outDir = File(getAbsolutePath("out"))
|
val outDir = File(getAbsolutePath("out"))
|
||||||
val outAfterMake = File(getAbsolutePath("out-after-make"))
|
val outAfterMake = File(getAbsolutePath("out-after-make"))
|
||||||
@@ -430,8 +369,8 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
|
|
||||||
private fun performModificationsAndMake(moduleNames: Set<String>?): List<MakeResult> {
|
private fun performModificationsAndMake(moduleNames: Set<String>?): List<MakeResult> {
|
||||||
val results = arrayListOf<MakeResult>()
|
val results = arrayListOf<MakeResult>()
|
||||||
|
val modifications = getModificationsToPerform(testDataDir, moduleNames, allowNoFilesWithSuffixInTestData, TouchPolicy.TIMESTAMP)
|
||||||
|
|
||||||
val modifications = getModificationsToPerform(moduleNames)
|
|
||||||
for (step in modifications) {
|
for (step in modifications) {
|
||||||
step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
|
step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
|
||||||
performAdditionalModifications(step)
|
performAdditionalModifications(step)
|
||||||
@@ -452,16 +391,13 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
|
|
||||||
// null means one module
|
// null means one module
|
||||||
private fun configureModules(): Set<String>? {
|
private fun configureModules(): Set<String>? {
|
||||||
|
fun prepareModuleSources(moduleName: String?) {
|
||||||
fun prepareSources(relativePathToSrc: String, filePrefix: String) {
|
val sourceDirName = moduleName?.let { "$it/src" } ?: "src"
|
||||||
val srcDir = File(workDir, relativePathToSrc)
|
val filePrefix = moduleName?.let { "${it}_" } ?: ""
|
||||||
FileUtil.copyDir(testDataDir, srcDir) {
|
val sourceDestinationDir = File(workDir, sourceDirName)
|
||||||
it.isDirectory || it.name.startsWith(filePrefix) && (it.name.endsWith(".kt") || it.name.endsWith(".java"))
|
val sourcesMapping = copyTestSources(testDataDir, sourceDestinationDir, filePrefix)
|
||||||
}
|
mapWorkingToOriginalFile.putAll(sourcesMapping)
|
||||||
|
preProcessSources(sourceDestinationDir)
|
||||||
srcDir.walk().forEach { mapWorkingToOriginalFile[it] = File(testDataDir, filePrefix + it.name) }
|
|
||||||
|
|
||||||
preProcessSources(srcDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var moduleNames: Set<String>?
|
var moduleNames: Set<String>?
|
||||||
@@ -469,11 +405,11 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
|
|
||||||
val jdk = addJdk("my jdk")
|
val jdk = addJdk("my jdk")
|
||||||
val moduleDependencies = readModuleDependencies()
|
val moduleDependencies = readModuleDependencies()
|
||||||
|
mapWorkingToOriginalFile = hashMapOf()
|
||||||
|
|
||||||
if (moduleDependencies == null) {
|
if (moduleDependencies == null) {
|
||||||
addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk)
|
addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk)
|
||||||
|
prepareModuleSources(moduleName = null)
|
||||||
prepareSources(relativePathToSrc = "src", filePrefix = "")
|
|
||||||
|
|
||||||
moduleNames = null
|
moduleNames = null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -490,8 +426,7 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (module in nameToModule.values) {
|
for (module in nameToModule.values) {
|
||||||
val moduleName = module.name
|
prepareModuleSources(module.name)
|
||||||
prepareSources(relativePathToSrc = "$moduleName/src", filePrefix = moduleName + "_")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleNames = nameToModule.keys
|
moduleNames = nameToModule.keys
|
||||||
@@ -501,6 +436,7 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
return moduleNames
|
return moduleNames
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected open fun preProcessSources(srcDir: File) {
|
protected open fun preProcessSources(srcDir: File) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,51 +484,6 @@ abstract class AbstractIncrementalJpsTest(
|
|||||||
logBuf.append(KotlinTestUtils.replaceHashWithStar(message!!.replace("^$rootPath/".toRegex(), " "))).append('\n')
|
logBuf.append(KotlinTestUtils.replaceHashWithStar(message!!.replace("^$rootPath/".toRegex(), " "))).append('\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract class Modification(val path: String) {
|
|
||||||
abstract fun perform(workDir: File, mapping: MutableMap<File, File>)
|
|
||||||
|
|
||||||
override fun toString(): String = "${javaClass.simpleName} $path"
|
|
||||||
}
|
|
||||||
|
|
||||||
protected 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class TouchFile(path: String) : Modification(path) {
|
|
||||||
override fun perform(workDir: File, mapping: MutableMap<File, File>) {
|
|
||||||
val file = File(workDir, path)
|
|
||||||
|
|
||||||
val oldLastModified = file.lastModified()
|
|
||||||
//Mac OS and some versions of Linux truncate timestamp to nearest second
|
|
||||||
file.setLastModified(Math.max(System.currentTimeMillis(), oldLastModified + 1000))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
|
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
|
||||||
|
|||||||
@@ -21,9 +21,11 @@ import org.jetbrains.jps.builders.BuildTarget
|
|||||||
import org.jetbrains.jps.builders.storage.BuildDataPaths
|
import org.jetbrains.jps.builders.storage.BuildDataPaths
|
||||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||||
import org.jetbrains.kotlin.incremental.CacheVersion
|
import org.jetbrains.kotlin.incremental.CacheVersion
|
||||||
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
|
|
||||||
import org.jetbrains.kotlin.jps.incremental.CacheVersionProvider
|
|
||||||
import org.jetbrains.kotlin.incremental.KOTLIN_CACHE_DIRECTORY_NAME
|
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.jps.incremental.CacheVersionProvider
|
||||||
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
|
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -40,11 +42,11 @@ abstract class AbstractIncrementalLazyCachesTest : AbstractIncrementalJpsTest()
|
|||||||
UsefulTestCase.assertSameLinesWithFile(expectedFile.canonicalPath, actual)
|
UsefulTestCase.assertSameLinesWithFile(expectedFile.canonicalPath, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun performAdditionalModifications(modifications: List<AbstractIncrementalJpsTest.Modification>) {
|
override fun performAdditionalModifications(modifications: List<Modification>) {
|
||||||
super.performAdditionalModifications(modifications)
|
super.performAdditionalModifications(modifications)
|
||||||
|
|
||||||
for (modification in modifications) {
|
for (modification in modifications) {
|
||||||
if (modification !is AbstractIncrementalJpsTest.ModifyContent) continue
|
if (modification !is ModifyContent) continue
|
||||||
|
|
||||||
val name = File(modification.path).name
|
val name = File(modification.path).name
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.jps.build
|
|||||||
|
|
||||||
import com.intellij.openapi.util.SystemInfoRt
|
import com.intellij.openapi.util.SystemInfoRt
|
||||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||||
|
import org.jetbrains.kotlin.jps.build.incrementalModificationUtils.Modification
|
||||||
|
|
||||||
class IncrementalProjectPathCaseChangedTest : AbstractIncrementalJpsTest(checkDumpsCaseInsensitively = true) {
|
class IncrementalProjectPathCaseChangedTest : AbstractIncrementalJpsTest(checkDumpsCaseInsensitively = true) {
|
||||||
fun testProjectPathCaseChanged() {
|
fun testProjectPathCaseChanged() {
|
||||||
@@ -36,7 +37,7 @@ class IncrementalProjectPathCaseChangedTest : AbstractIncrementalJpsTest(checkDu
|
|||||||
super.doTest(testDataPath)
|
super.doTest(testDataPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun performAdditionalModifications(modifications: List<AbstractIncrementalJpsTest.Modification>) {
|
override fun performAdditionalModifications(modifications: List<Modification>) {
|
||||||
val module = myProject.modules[0]
|
val module = myProject.modules[0]
|
||||||
val sourceRoot = module.sourceRoots[0].url
|
val sourceRoot = module.sourceRoots[0].url
|
||||||
assert(sourceRoot.endsWith("/src"))
|
assert(sourceRoot.endsWith("/src"))
|
||||||
|
|||||||
+161
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user