Add function to make a snapshot of current test project

This will allow checking current state of test project and try
to work with it directly.

^KT-45745 In Progress
This commit is contained in:
Yahor Berdnikau
2021-12-08 17:12:00 +01:00
parent 6fed67b36c
commit 1c8a1e656e
4 changed files with 130 additions and 27 deletions
@@ -88,7 +88,7 @@ add a new assertion, add as a reviewer someone from Kotlin build tools team.
##### Additional test helpers
Whenever you need to test combination of different JDKs and Gradle versions - you could use `@GradleWithJdkTest` instead of `@GradleTest`.
- Whenever you need to test combination of different JDKs and Gradle versions - you could use `@GradleWithJdkTest` instead of `@GradleTest`.
Then test method will receive requires JDKs as a second parameter:
```kotlin
@JdkVersions(version = [JavaVersion.VERSION_11, JavaVersion.VERSION_17])
@@ -103,6 +103,8 @@ fun someTest(
}
```
- If you want to copy current state of the test project and play with it separately - you could use `makeSnapshotTo(destinationPath)` function.
##### Common test fixes
Test infrastructure adds following common fixes to all test projects:
@@ -5,10 +5,13 @@
package org.jetbrains.kotlin.gradle.testbase
import java.io.IOException
import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.extension
import kotlin.io.path.relativeTo import kotlin.io.path.isRegularFile
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes
import kotlin.io.path.*
import kotlin.streams.asSequence
import kotlin.streams.toList
@@ -64,4 +67,44 @@ internal fun Iterable<Path>.relativizeTo(basePath: Path): Iterable<Path> = map {
it.relativeTo(basePath)
}
internal fun String.normalizePath() = replace("\\", "/")
internal fun String.normalizePath() = replace("\\", "/")
internal fun Path.copyRecursively(dest: Path) {
Files.walkFileTree(this, object : SimpleFileVisitor<Path>() {
override fun preVisitDirectory(
dir: Path,
attrs: BasicFileAttributes
): FileVisitResult {
dest.resolve(relativize(dir)).createDirectories()
return FileVisitResult.CONTINUE
}
override fun visitFile(
file: Path,
attrs: BasicFileAttributes
): FileVisitResult {
file.copyTo(dest.resolve(relativize(file)))
return FileVisitResult.CONTINUE
}
})
}
internal fun Path.deleteRecursively() {
Files.walkFileTree(this, object : SimpleFileVisitor<Path>() {
override fun visitFile(
file: Path,
fileAttributes: BasicFileAttributes
): FileVisitResult {
file.deleteIfExists()
return FileVisitResult.CONTINUE
}
override fun postVisitDirectory(
dir: Path,
exception: IOException?
): FileVisitResult {
dir.deleteIfExists()
return FileVisitResult.CONTINUE
}
})
}
@@ -12,9 +12,6 @@ import org.jetbrains.kotlin.gradle.BaseGradleIT.Companion.acceptAndroidSdkLicens
import org.jetbrains.kotlin.test.util.KtTestUtil
import java.io.File
import java.nio.file.*
import java.nio.file.Files.copy
import java.nio.file.Files.createDirectories
import java.nio.file.attribute.BasicFileAttributes
import kotlin.io.path.*
import kotlin.test.assertTrue
@@ -474,23 +471,3 @@ private fun Path.addHeapDumpOptions() {
}
}
}
private fun Path.copyRecursively(dest: Path) {
Files.walkFileTree(this, object : SimpleFileVisitor<Path>() {
override fun preVisitDirectory(
dir: Path,
attrs: BasicFileAttributes
): FileVisitResult {
createDirectories(dest.resolve(relativize(dir)))
return FileVisitResult.CONTINUE
}
override fun visitFile(
file: Path,
attrs: BasicFileAttributes
): FileVisitResult {
copy(file, dest.resolve(relativize(file)))
return FileVisitResult.CONTINUE
}
})
}
@@ -0,0 +1,81 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.testbase
import java.nio.file.Paths
import java.nio.file.attribute.PosixFilePermission
import kotlin.io.path.*
/**
* Makes a snapshot of the current state of [TestProject] into [destinationPath].
*
* Method copies all files into `destinationPath/testProjectName/GradleVersion` directory
* and setup buildable project.
*
* To run task with the same build option as test - use `run.sh` (or `run.bat`) script.
*/
fun TestProject.makeSnapshotTo(destinationPath: String) {
val dest = Paths
.get(destinationPath)
.resolve(projectName)
.resolve(gradleVersion.version)
.also {
if (it.exists()) it.deleteRecursively()
it.createDirectories()
}
projectPath.copyRecursively(dest)
dest.resolve("gradle.properties").append(
"""
kotlin_version=${buildOptions.kotlinVersion}
test_fixes_version=${TestVersions.Kotlin.CURRENT}
""".trimIndent()
)
dest.resolve("run.sh").run {
writeText(
"""
#!/usr/bin/env sh
./gradlew ${buildOptions.toArguments(gradleVersion).joinToString(separator = " ")} ${'$'}@
""".trimIndent()
)
setPosixFilePermissions(
setOf(
PosixFilePermission.OWNER_EXECUTE,
PosixFilePermission.OWNER_READ,
PosixFilePermission.OWNER_WRITE,
)
)
}
dest.resolve("run.bat").run {
writeText(
"""
@rem Executing Gradle build
gradlew.bat ${buildOptions.toArguments(gradleVersion).joinToString(separator = " ")} %*
""".trimIndent()
)
}
val wrapperDir = dest.resolve("gradle").resolve("wrapper").apply { createDirectories() }
wrapperDir.resolve("gradle-wrapper.properties").writeText(
"""
distributionUrl=https\://services.gradle.org/distributions/gradle-${gradleVersion.version}-bin.zip
""".trimIndent()
)
// Copied from 'Wrapper' task class implementation
val projectRoot = Paths.get("../../../")
projectRoot.resolve("gradle").resolve("wrapper").resolve("gradle-wrapper.jar").run {
copyTo(wrapperDir.resolve(fileName))
}
projectRoot.resolve("gradlew").run {
copyTo(dest.resolve(fileName))
}
projectRoot.resolve("gradlew.bat").run {
copyTo(dest.resolve(fileName))
}
}