[Native][tests] Refactoring: Use typed compilations and artifacts
^KT-50775
This commit is contained in:
+16
-19
@@ -9,11 +9,13 @@ import com.intellij.testFramework.TestDataFile
|
|||||||
import org.jetbrains.kotlin.klib.AbstractKlibABITestCase
|
import org.jetbrains.kotlin.klib.AbstractKlibABITestCase
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.WithTestRunnerExtras
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.WithTestRunnerExtras
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilation
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.ExecutableCompilation
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationDependencies
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.ExistingLibraryDependency
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.LibraryCompilation
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.Executable
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationDependencyType.Library
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccessfullyCompiled
|
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestExecutable
|
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestExecutable
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeHome
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeHome
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets
|
||||||
@@ -27,10 +29,6 @@ import java.io.File
|
|||||||
|
|
||||||
@Tag("klib")
|
@Tag("klib")
|
||||||
abstract class AbstractNativeKlibABITest : AbstractNativeSimpleTest() {
|
abstract class AbstractNativeKlibABITest : AbstractNativeSimpleTest() {
|
||||||
private val compilationResults: MutableMap<File, TestCompilationResult.Success> by lazy {
|
|
||||||
mutableMapOf(stdlibFile to TestCompilationResult.ExistingArtifact(stdlibFile))
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun runTest(@TestDataFile testPath: String): Unit = AbstractKlibABITestCase.doTest(
|
protected fun runTest(@TestDataFile testPath: String): Unit = AbstractKlibABITestCase.doTest(
|
||||||
testDir = getAbsoluteFile(testPath),
|
testDir = getAbsoluteFile(testPath),
|
||||||
buildDir = buildDir,
|
buildDir = buildDir,
|
||||||
@@ -48,15 +46,15 @@ abstract class AbstractNativeKlibABITest : AbstractNativeSimpleTest() {
|
|||||||
|
|
||||||
val testCase = createTestCase(module, COMPILER_ARGS_FOR_KLIB)
|
val testCase = createTestCase(module, COMPILER_ARGS_FOR_KLIB)
|
||||||
|
|
||||||
val compilation = TestCompilation.createForKlib(
|
val compilation = LibraryCompilation(
|
||||||
settings = testRunSettings,
|
settings = testRunSettings,
|
||||||
freeCompilerArgs = testCase.freeCompilerArgs,
|
freeCompilerArgs = testCase.freeCompilerArgs,
|
||||||
sourceModules = testCase.modules,
|
sourceModules = testCase.modules,
|
||||||
dependencies = createCompilationDependencies(moduleDependencies),
|
dependencies = createExistingDependencies(moduleDependencies),
|
||||||
expectedKlibFile = klibFile,
|
expectedArtifact = TestCompilationArtifact.KLIB(klibFile),
|
||||||
)
|
)
|
||||||
|
|
||||||
compilationResults[klibFile] = compilation.result.assertSuccess() // <-- trigger compilation
|
compilation.result.assertSuccess() // <-- trigger compilation
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildBinaryAndRun(allDependencies: Collection<File>) {
|
private fun buildBinaryAndRun(allDependencies: Collection<File>) {
|
||||||
@@ -72,16 +70,16 @@ abstract class AbstractNativeKlibABITest : AbstractNativeSimpleTest() {
|
|||||||
|
|
||||||
val testCase = createTestCase(module, COMPILER_ARGS_FOR_EXECUTABLE)
|
val testCase = createTestCase(module, COMPILER_ARGS_FOR_EXECUTABLE)
|
||||||
|
|
||||||
val compilation = TestCompilation.createForExecutable(
|
val compilation = ExecutableCompilation(
|
||||||
settings = testRunSettings,
|
settings = testRunSettings,
|
||||||
freeCompilerArgs = testCase.freeCompilerArgs,
|
freeCompilerArgs = testCase.freeCompilerArgs,
|
||||||
sourceModules = testCase.modules,
|
sourceModules = testCase.modules,
|
||||||
extras = testCase.extras,
|
extras = testCase.extras,
|
||||||
dependencies = createCompilationDependencies(allDependencies),
|
dependencies = createExistingDependencies(allDependencies),
|
||||||
expectedExecutableFile = executableFile
|
expectedArtifact = Executable(executableFile)
|
||||||
)
|
)
|
||||||
|
|
||||||
val compilationResult = compilation.result.assertSuccessfullyCompiled() // <-- trigger compilation
|
val compilationResult = compilation.result.assertSuccess() // <-- trigger compilation
|
||||||
val executable = TestExecutable(executableFile, compilationResult.loggedData)
|
val executable = TestExecutable(executableFile, compilationResult.loggedData)
|
||||||
|
|
||||||
runExecutableAndVerify(testCase, executable) // <-- run executable and verify
|
runExecutableAndVerify(testCase, executable) // <-- run executable and verify
|
||||||
@@ -106,9 +104,8 @@ abstract class AbstractNativeKlibABITest : AbstractNativeSimpleTest() {
|
|||||||
initialize(null)
|
initialize(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCompilationDependencies(dependencies: Collection<File>) = TestCompilationDependencies(
|
private fun createExistingDependencies(dependencies: Collection<File>) =
|
||||||
libraries = dependencies.map(TestCompilation.Companion::createForExistingArtifact)
|
dependencies.map { ExistingLibraryDependency(TestCompilationArtifact.KLIB(it), Library) }
|
||||||
)
|
|
||||||
|
|
||||||
private val buildDir: File get() = testRunSettings.get<SimpleTestDirectories>().testBuildDir
|
private val buildDir: File get() = testRunSettings.get<SimpleTestDirectories>().testBuildDir
|
||||||
private val stdlibFile: File get() = testRunSettings.get<KotlinNativeHome>().dir.resolve("klib/common/stdlib")
|
private val stdlibFile: File get() = testRunSettings.get<KotlinNativeHome>().dir.resolve("klib/common/stdlib")
|
||||||
|
|||||||
+95
-198
@@ -8,133 +8,21 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.compilation
|
|||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.*
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.*
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilation.Companion.resultingArtifactPath
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.Executable
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.KLIB
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationDependencyType.*
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.*
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.*
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.CacheKind.Companion.rootCacheDir
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.CacheKind.Companion.rootCacheDir
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.ArgsBuilder
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.buildArgs
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.flatMapToSet
|
import org.jetbrains.kotlin.konan.blackboxtest.support.util.flatMapToSet
|
||||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal interface TestCompilation {
|
internal abstract class TestCompilation<A : TestCompilationArtifact> {
|
||||||
val result: TestCompilationResult
|
abstract val result: TestCompilationResult<out A>
|
||||||
|
|
||||||
companion object {
|
|
||||||
val TestCompilation.resultingArtifactPath: String
|
|
||||||
get() = result.assertSuccess().resultingArtifact.path
|
|
||||||
|
|
||||||
fun createForKlib(
|
|
||||||
settings: Settings,
|
|
||||||
freeCompilerArgs: TestCompilerArgs,
|
|
||||||
sourceModules: Collection<TestModule>,
|
|
||||||
dependencies: TestCompilationDependencies,
|
|
||||||
expectedKlibFile: File
|
|
||||||
): TestCompilation = TestCompilationImpl.create(
|
|
||||||
settings = settings,
|
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
|
||||||
sourceModules = sourceModules,
|
|
||||||
dependencies = dependencies,
|
|
||||||
expectedArtifactFile = expectedKlibFile,
|
|
||||||
specificCompilerArgs = TestCompilationImpl.compilerArgsForKlib()
|
|
||||||
)
|
|
||||||
|
|
||||||
fun createForExecutable(
|
|
||||||
settings: Settings,
|
|
||||||
freeCompilerArgs: TestCompilerArgs,
|
|
||||||
sourceModules: Collection<TestModule>,
|
|
||||||
extras: Extras,
|
|
||||||
dependencies: TestCompilationDependencies,
|
|
||||||
expectedExecutableFile: File
|
|
||||||
): TestCompilation = TestCompilationImpl.create(
|
|
||||||
settings = settings,
|
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
|
||||||
sourceModules = sourceModules,
|
|
||||||
dependencies = dependencies,
|
|
||||||
expectedArtifactFile = expectedExecutableFile,
|
|
||||||
specificCompilerArgs = TestCompilationImpl.compilerArgsForExecutable(settings.get(), extras)
|
|
||||||
)
|
|
||||||
|
|
||||||
fun createForExistingArtifact(resultingArtifact: File): TestCompilation =
|
|
||||||
object : TestCompilation {
|
|
||||||
override val result = TestCompilationResult.ExistingArtifact(resultingArtifact)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed interface TestCompilationResult {
|
internal abstract class BaseCompilation<A : TestCompilationArtifact>(
|
||||||
sealed interface ImmediateResult : TestCompilationResult {
|
|
||||||
val loggedData: LoggedData
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed interface Success : TestCompilationResult {
|
|
||||||
val resultingArtifact: File
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed interface Failure : ImmediateResult
|
|
||||||
|
|
||||||
data class ExistingArtifact(override val resultingArtifact: File) : Success
|
|
||||||
data class CompiledArtifact(override val resultingArtifact: File, override val loggedData: LoggedData.CompilerCall) :
|
|
||||||
ImmediateResult, Success
|
|
||||||
|
|
||||||
data class CompilerFailure(override val loggedData: LoggedData.CompilerCall) : Failure
|
|
||||||
data class UnexpectedFailure(override val loggedData: LoggedData.CompilerCallUnexpectedFailure) : Failure
|
|
||||||
data class DependencyFailures(val causes: Set<Failure>) : TestCompilationResult
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun TestCompilationResult.assertSuccess(): Success = when (this) {
|
|
||||||
is Success -> this
|
|
||||||
is Failure -> fail { describeFailure() }
|
|
||||||
is DependencyFailures -> fail { describeDependencyFailures() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun TestCompilationResult.assertSuccessfullyCompiled(): CompiledArtifact = when (val result = assertSuccess()) {
|
|
||||||
is CompiledArtifact -> result
|
|
||||||
is ExistingArtifact -> fail { "Test compilation result contains pre-existing artifact: ${result.resultingArtifact}" }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Failure.describeFailure() = loggedData.withErrorMessage(
|
|
||||||
when (this@describeFailure) {
|
|
||||||
is CompilerFailure -> "Compilation failed."
|
|
||||||
is UnexpectedFailure -> "Compilation failed with unexpected exception."
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun DependencyFailures.describeDependencyFailures() =
|
|
||||||
buildString {
|
|
||||||
appendLine("Compilation aborted due to errors in dependency compilations (${causes.size} items). See details below.")
|
|
||||||
appendLine()
|
|
||||||
causes.forEachIndexed { index, cause ->
|
|
||||||
append("#").append(index + 1).append(". ")
|
|
||||||
appendLine(cause.describeFailure())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The dependencies of a particular [TestCompilation].
|
|
||||||
*
|
|
||||||
* [libraries] - the [TestCompilation]s (modules) that should yield KLIBs to be consumed as dependency libraries in the current compilation.
|
|
||||||
* [friends] - similarly but friend modules (-friend-modules).
|
|
||||||
* [includedLibraries] - similarly but included modules (-Xinclude).
|
|
||||||
*/
|
|
||||||
internal class TestCompilationDependencies(
|
|
||||||
val libraries: Collection<TestCompilation> = emptyList(),
|
|
||||||
val friends: Collection<TestCompilation> = emptyList(),
|
|
||||||
val includedLibraries: Collection<TestCompilation> = emptyList()
|
|
||||||
) {
|
|
||||||
fun collectFailures(): Set<TestCompilationResult.Failure> = listOf(libraries, friends, includedLibraries)
|
|
||||||
.flatten()
|
|
||||||
.flatMapToSet { compilation ->
|
|
||||||
when (val result = compilation.result) {
|
|
||||||
is TestCompilationResult.Failure -> listOf(result)
|
|
||||||
is TestCompilationResult.DependencyFailures -> result.causes
|
|
||||||
is TestCompilationResult.Success -> emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestCompilationImpl(
|
|
||||||
private val targets: KotlinNativeTargets,
|
private val targets: KotlinNativeTargets,
|
||||||
private val home: KotlinNativeHome,
|
private val home: KotlinNativeHome,
|
||||||
private val classLoader: KotlinNativeClassLoader,
|
private val classLoader: KotlinNativeClassLoader,
|
||||||
@@ -144,12 +32,11 @@ private class TestCompilationImpl(
|
|||||||
private val gcType: GCType,
|
private val gcType: GCType,
|
||||||
private val freeCompilerArgs: TestCompilerArgs,
|
private val freeCompilerArgs: TestCompilerArgs,
|
||||||
private val sourceModules: Collection<TestModule>,
|
private val sourceModules: Collection<TestModule>,
|
||||||
private val dependencies: TestCompilationDependencies,
|
private val dependencies: Collection<TestCompilationDependency<*>>,
|
||||||
private val expectedArtifactFile: File,
|
private val expectedArtifact: A
|
||||||
private val specificCompilerArgs: ArgsBuilder.() -> Unit
|
) : TestCompilation<A>() {
|
||||||
) : TestCompilation {
|
|
||||||
// Runs the compiler and memorizes the result on property access.
|
// Runs the compiler and memorizes the result on property access.
|
||||||
override val result: TestCompilationResult by lazy {
|
final override val result: TestCompilationResult<out A> by lazy {
|
||||||
val failures = dependencies.collectFailures()
|
val failures = dependencies.collectFailures()
|
||||||
if (failures.isNotEmpty())
|
if (failures.isNotEmpty())
|
||||||
TestCompilationResult.DependencyFailures(causes = failures)
|
TestCompilationResult.DependencyFailures(causes = failures)
|
||||||
@@ -162,7 +49,7 @@ private class TestCompilationImpl(
|
|||||||
"-enable-assertions",
|
"-enable-assertions",
|
||||||
"-target", targets.testTarget.name,
|
"-target", targets.testTarget.name,
|
||||||
"-repo", home.dir.resolve("klib").path,
|
"-repo", home.dir.resolve("klib").path,
|
||||||
"-output", expectedArtifactFile.path,
|
"-output", expectedArtifact.path,
|
||||||
"-Xskip-prerelease-check",
|
"-Xskip-prerelease-check",
|
||||||
"-Xverify-ir",
|
"-Xverify-ir",
|
||||||
"-Xbinary=runtimeAssertionsMode=panic"
|
"-Xbinary=runtimeAssertionsMode=panic"
|
||||||
@@ -172,28 +59,30 @@ private class TestCompilationImpl(
|
|||||||
threadStateChecker.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
threadStateChecker.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
||||||
gcType.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
gcType.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
||||||
|
|
||||||
addFlattened(dependencies.libraries) { library -> listOf("-l", library.resultingArtifactPath) }
|
addFlattened(dependencies.libraries) { library -> listOf("-l", library.path) }
|
||||||
dependencies.friends.takeIf(Collection<*>::isNotEmpty)?.let { friends ->
|
dependencies.friends.takeIf(Collection<*>::isNotEmpty)?.let { friends ->
|
||||||
add("-friend-modules", friends.joinToString(File.pathSeparator) { friend -> friend.resultingArtifactPath })
|
add("-friend-modules", friends.joinToString(File.pathSeparator) { friend -> friend.path })
|
||||||
}
|
}
|
||||||
add(dependencies.includedLibraries) { include -> "-Xinclude=${include.resultingArtifactPath}" }
|
add(dependencies.includedLibraries) { include -> "-Xinclude=${include.path}" }
|
||||||
add(freeCompilerArgs.compilerArgs)
|
add(freeCompilerArgs.compilerArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract fun ArgsBuilder.applySpecificCompilerArgs()
|
||||||
|
|
||||||
private fun ArgsBuilder.applySources() {
|
private fun ArgsBuilder.applySources() {
|
||||||
addFlattenedTwice(sourceModules, { it.files }) { it.location.path }
|
addFlattenedTwice(sourceModules, { it.files }) { it.location.path }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doCompile(): TestCompilationResult.ImmediateResult {
|
private fun doCompile(): TestCompilationResult.ImmediateResult<out A> {
|
||||||
val compilerArgs = buildArgs {
|
val compilerArgs = buildArgs {
|
||||||
applyCommonArgs()
|
applyCommonArgs()
|
||||||
specificCompilerArgs()
|
applySpecificCompilerArgs()
|
||||||
applySources()
|
applySources()
|
||||||
}
|
}
|
||||||
|
|
||||||
val loggedCompilerParameters = LoggedData.CompilerParameters(compilerArgs, sourceModules)
|
val loggedCompilerParameters = LoggedData.CompilerParameters(compilerArgs, sourceModules)
|
||||||
|
|
||||||
val (loggedCompilerCall: LoggedData, result: TestCompilationResult.ImmediateResult) = try {
|
val (loggedCompilerCall: LoggedData, result: TestCompilationResult.ImmediateResult<out A>) = try {
|
||||||
val (exitCode, compilerOutput, compilerOutputHasErrors, duration) = callCompiler(
|
val (exitCode, compilerOutput, compilerOutputHasErrors, duration) = callCompiler(
|
||||||
compilerArgs = compilerArgs,
|
compilerArgs = compilerArgs,
|
||||||
kotlinNativeClassLoader = classLoader.classLoader
|
kotlinNativeClassLoader = classLoader.classLoader
|
||||||
@@ -205,7 +94,7 @@ private class TestCompilationImpl(
|
|||||||
val result = if (exitCode != ExitCode.OK || compilerOutputHasErrors)
|
val result = if (exitCode != ExitCode.OK || compilerOutputHasErrors)
|
||||||
TestCompilationResult.CompilerFailure(loggedCompilerCall)
|
TestCompilationResult.CompilerFailure(loggedCompilerCall)
|
||||||
else
|
else
|
||||||
TestCompilationResult.CompiledArtifact(expectedArtifactFile, loggedCompilerCall)
|
TestCompilationResult.Success(expectedArtifact, loggedCompilerCall)
|
||||||
|
|
||||||
loggedCompilerCall to result
|
loggedCompilerCall to result
|
||||||
} catch (unexpectedThrowable: Throwable) {
|
} catch (unexpectedThrowable: Throwable) {
|
||||||
@@ -215,83 +104,91 @@ private class TestCompilationImpl(
|
|||||||
loggedFailure to result
|
loggedFailure to result
|
||||||
}
|
}
|
||||||
|
|
||||||
getLogFile(expectedArtifactFile).writeText(loggedCompilerCall.toString())
|
getLogFile(expectedArtifact.file).writeText(loggedCompilerCall.toString())
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun compilerArgsForKlib(): ArgsBuilder.() -> Unit = { add("-produce", "library") }
|
private fun Collection<TestCompilationDependency<*>>.collectFailures() = flatMapToSet { dependency ->
|
||||||
|
when (val result = (dependency as? TestCompilation<*>)?.result) {
|
||||||
fun compilerArgsForExecutable(cacheKind: CacheKind, extras: Extras): ArgsBuilder.() -> Unit = {
|
is TestCompilationResult.Failure -> listOf(result)
|
||||||
add("-produce", "program")
|
is TestCompilationResult.DependencyFailures -> result.causes
|
||||||
when (extras) {
|
is TestCompilationResult.Success -> emptyList()
|
||||||
is NoTestRunnerExtras -> add("-entry", extras.entryPoint)
|
null -> emptyList()
|
||||||
is WithTestRunnerExtras -> {
|
|
||||||
val testRunnerArg = when (extras.runnerType) {
|
|
||||||
TestRunnerType.DEFAULT -> "-generate-test-runner"
|
|
||||||
TestRunnerType.WORKER -> "-generate-worker-test-runner"
|
|
||||||
TestRunnerType.NO_EXIT -> "-generate-no-exit-test-runner"
|
|
||||||
}
|
|
||||||
add(testRunnerArg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cacheKind.rootCacheDir?.let { rootCacheDir -> add("-Xcache-directory=$rootCacheDir") }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just a shortcut to reduce the number of arguments.
|
private inline fun <reified A : TestCompilationArtifact, reified T : TestCompilationDependencyType<A>> Collection<TestCompilationDependency<*>>.collectArtifacts() =
|
||||||
fun create(
|
mapNotNull { dependency -> if (dependency.type is T) dependency.artifact as A else null }
|
||||||
settings: Settings,
|
|
||||||
freeCompilerArgs: TestCompilerArgs,
|
private val Collection<TestCompilationDependency<*>>.libraries get() = collectArtifacts<KLIB, Library>()
|
||||||
sourceModules: Collection<TestModule>,
|
private val Collection<TestCompilationDependency<*>>.friends get() = collectArtifacts<KLIB, FriendLibrary>()
|
||||||
dependencies: TestCompilationDependencies,
|
private val Collection<TestCompilationDependency<*>>.includedLibraries get() = collectArtifacts<KLIB, IncludedLibrary>()
|
||||||
expectedArtifactFile: File,
|
|
||||||
specificCompilerArgs: ArgsBuilder.() -> Unit
|
private fun getLogFile(expectedArtifactFile: File): File = expectedArtifactFile.resolveSibling(expectedArtifactFile.name + ".log")
|
||||||
) = TestCompilationImpl(
|
|
||||||
targets = settings.get(),
|
|
||||||
home = settings.get(),
|
|
||||||
classLoader = settings.get(),
|
|
||||||
optimizationMode = settings.get(),
|
|
||||||
memoryModel = settings.get(),
|
|
||||||
threadStateChecker = settings.get(),
|
|
||||||
gcType = settings.get(),
|
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
|
||||||
sourceModules = sourceModules,
|
|
||||||
dependencies = dependencies,
|
|
||||||
expectedArtifactFile = expectedArtifactFile,
|
|
||||||
specificCompilerArgs = specificCompilerArgs
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ArgsBuilder {
|
internal class LibraryCompilation(
|
||||||
private val args = mutableListOf<String>()
|
settings: Settings,
|
||||||
|
freeCompilerArgs: TestCompilerArgs,
|
||||||
fun add(vararg args: String) {
|
sourceModules: Collection<TestModule>,
|
||||||
this.args += args
|
dependencies: Collection<TestCompilationDependency<*>>,
|
||||||
|
expectedArtifact: KLIB
|
||||||
|
) : BaseCompilation<KLIB>(
|
||||||
|
targets = settings.get(),
|
||||||
|
home = settings.get(),
|
||||||
|
classLoader = settings.get(),
|
||||||
|
optimizationMode = settings.get(),
|
||||||
|
memoryModel = settings.get(),
|
||||||
|
threadStateChecker = settings.get(),
|
||||||
|
gcType = settings.get(),
|
||||||
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
|
sourceModules = sourceModules,
|
||||||
|
dependencies = dependencies,
|
||||||
|
expectedArtifact = expectedArtifact
|
||||||
|
) {
|
||||||
|
override fun ArgsBuilder.applySpecificCompilerArgs() {
|
||||||
|
add("-produce", "library")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun add(args: Iterable<String>) {
|
|
||||||
this.args += args
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <T> add(rawArgs: Iterable<T>, transform: (T) -> String) {
|
|
||||||
rawArgs.mapTo(args) { transform(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <T> addFlattened(rawArgs: Iterable<T>, transform: (T) -> Iterable<String>) {
|
|
||||||
rawArgs.flatMapTo(args) { transform(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <T, R> addFlattenedTwice(rawArgs: Iterable<T>, transform1: (T) -> Iterable<R>, transform2: (R) -> String) {
|
|
||||||
rawArgs.forEach { add(transform1(it), transform2) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun build(): Array<String> = args.toTypedArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun buildArgs(builderAction: ArgsBuilder.() -> Unit): Array<String> {
|
internal class ExecutableCompilation(
|
||||||
return ArgsBuilder().apply(builderAction).build()
|
settings: Settings,
|
||||||
}
|
freeCompilerArgs: TestCompilerArgs,
|
||||||
|
sourceModules: Collection<TestModule>,
|
||||||
|
private val extras: Extras,
|
||||||
|
dependencies: Collection<TestCompilationDependency<*>>,
|
||||||
|
expectedArtifact: Executable
|
||||||
|
) : BaseCompilation<Executable>(
|
||||||
|
targets = settings.get(),
|
||||||
|
home = settings.get(),
|
||||||
|
classLoader = settings.get(),
|
||||||
|
optimizationMode = settings.get(),
|
||||||
|
memoryModel = settings.get(),
|
||||||
|
threadStateChecker = settings.get(),
|
||||||
|
gcType = settings.get(),
|
||||||
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
|
sourceModules = sourceModules,
|
||||||
|
dependencies = dependencies,
|
||||||
|
expectedArtifact = expectedArtifact
|
||||||
|
) {
|
||||||
|
private val cacheKind: CacheKind = settings.get()
|
||||||
|
|
||||||
private fun getLogFile(expectedArtifactFile: File): File = expectedArtifactFile.resolveSibling(expectedArtifactFile.name + ".log")
|
override fun ArgsBuilder.applySpecificCompilerArgs() {
|
||||||
|
add("-produce", "program")
|
||||||
|
when (extras) {
|
||||||
|
is NoTestRunnerExtras -> add("-entry", extras.entryPoint)
|
||||||
|
is WithTestRunnerExtras -> {
|
||||||
|
val testRunnerArg = when (extras.runnerType) {
|
||||||
|
TestRunnerType.DEFAULT -> "-generate-test-runner"
|
||||||
|
TestRunnerType.WORKER -> "-generate-worker-test-runner"
|
||||||
|
TestRunnerType.NO_EXIT -> "-generate-no-exit-test-runner"
|
||||||
|
}
|
||||||
|
add(testRunnerArg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cacheKind.rootCacheDir?.let { rootCacheDir -> add("-Xcache-directory=$rootCacheDir") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.konan.blackboxtest.support.compilation
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
internal sealed interface TestCompilationArtifact {
|
||||||
|
val file: File
|
||||||
|
val path: String get() = file.path
|
||||||
|
|
||||||
|
data class KLIB(override val file: File) : TestCompilationArtifact
|
||||||
|
data class Executable(override val file: File) : TestCompilationArtifact
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.konan.blackboxtest.support.compilation
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of dependency for a particular [TestCompilation].
|
||||||
|
*
|
||||||
|
* [Library] - the [TestCompilation]s (modules) that should yield KLIBs to be consumed as dependency libraries in the current compilation.
|
||||||
|
* [FriendLibrary] - similarly but friend modules (-friend-modules).
|
||||||
|
* [IncludedLibrary] - similarly but included modules (-Xinclude).
|
||||||
|
*/
|
||||||
|
internal sealed interface TestCompilationDependencyType<A : TestCompilationArtifact> {
|
||||||
|
object Library : TestCompilationDependencyType<TestCompilationArtifact.KLIB>
|
||||||
|
object FriendLibrary : TestCompilationDependencyType<TestCompilationArtifact.KLIB>
|
||||||
|
object IncludedLibrary : TestCompilationDependencyType<TestCompilationArtifact.KLIB>
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed interface TestCompilationDependency<A : TestCompilationArtifact> {
|
||||||
|
val artifact: A
|
||||||
|
val type: TestCompilationDependencyType<A>
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class CompiledDependency<A : TestCompilationArtifact>(
|
||||||
|
val compilation: TestCompilation<A>,
|
||||||
|
override val type: TestCompilationDependencyType<A>
|
||||||
|
) : TestCompilationDependency<A> {
|
||||||
|
override val artifact: A get() = compilation.result.assertSuccess().resultingArtifact
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExistingLibraryDependency(
|
||||||
|
override val artifact: TestCompilationArtifact.KLIB,
|
||||||
|
override val type: TestCompilationDependencyType<TestCompilationArtifact.KLIB>
|
||||||
|
) : TestCompilationDependency<TestCompilationArtifact.KLIB>
|
||||||
+38
-23
@@ -11,6 +11,10 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.TestCompilerArgs
|
|||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule.Companion.allDependencies
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule.Companion.allDependencies
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule.Companion.allFriends
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule.Companion.allFriends
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.Executable
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.KLIB
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationDependencyType.FriendLibrary
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationDependencyType.Library
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Binaries
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Binaries
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
||||||
@@ -18,60 +22,71 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal class TestCompilationFactory {
|
internal class TestCompilationFactory {
|
||||||
private val cachedCompilations = ThreadSafeCache<TestCompilationCacheKey, TestCompilation>()
|
private val cachedKlibCompilations = ThreadSafeCache<KlibCacheKey, TestCompilation<KLIB>>()
|
||||||
|
private val cachedExecutableCompilations = ThreadSafeCache<ExecutableCacheKey, TestCompilation<Executable>>()
|
||||||
|
|
||||||
private sealed interface TestCompilationCacheKey {
|
private data class KlibCacheKey(val sourceModules: Set<TestModule>, val freeCompilerArgs: TestCompilerArgs)
|
||||||
data class Klib(val sourceModules: Set<TestModule>, val freeCompilerArgs: TestCompilerArgs) : TestCompilationCacheKey
|
private data class ExecutableCacheKey(val sourceModules: Set<TestModule>)
|
||||||
data class Executable(val sourceModules: Set<TestModule>) : TestCompilationCacheKey
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testCasesToExecutable(testCases: Collection<TestCase>, settings: Settings): TestCompilation {
|
fun testCasesToExecutable(testCases: Collection<TestCase>, settings: Settings): TestCompilation<Executable> {
|
||||||
val rootModules = testCases.flatMapToSet { testCase -> testCase.rootModules }
|
val rootModules = testCases.flatMapToSet { testCase -> testCase.rootModules }
|
||||||
val cacheKey = TestCompilationCacheKey.Executable(rootModules)
|
val cacheKey = ExecutableCacheKey(rootModules)
|
||||||
|
|
||||||
// Fast pass.
|
// Fast pass.
|
||||||
cachedCompilations[cacheKey]?.let { return it }
|
cachedExecutableCompilations[cacheKey]?.let { return it }
|
||||||
|
|
||||||
// Long pass.
|
// Long pass.
|
||||||
val freeCompilerArgs = rootModules.first().testCase.freeCompilerArgs // Should be identical inside the same test case group.
|
val freeCompilerArgs = rootModules.first().testCase.freeCompilerArgs // Should be identical inside the same test case group.
|
||||||
val extras = testCases.first().extras // Should be identical inside the same test case group.
|
val extras = testCases.first().extras // Should be identical inside the same test case group.
|
||||||
val libraries = rootModules.flatMapToSet { it.allDependencies }.map { moduleToKlib(it, freeCompilerArgs, settings) }
|
val dependencies = buildList {
|
||||||
val friends = rootModules.flatMapToSet { it.allFriends }.map { moduleToKlib(it, freeCompilerArgs, settings) }
|
rootModules.flatMapToSet { it.allDependencies }.mapTo(this) { it.asKlibDependency(freeCompilerArgs, settings, Library) }
|
||||||
|
rootModules.flatMapToSet { it.allFriends }.mapTo(this) { it.asKlibDependency(freeCompilerArgs, settings, FriendLibrary) }
|
||||||
|
}
|
||||||
|
val expectedArtifact = Executable(settings.artifactFileForExecutable(rootModules))
|
||||||
|
|
||||||
return cachedCompilations.computeIfAbsent(cacheKey) {
|
return cachedExecutableCompilations.computeIfAbsent(cacheKey) {
|
||||||
TestCompilation.createForExecutable(
|
ExecutableCompilation(
|
||||||
settings = settings,
|
settings = settings,
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
sourceModules = rootModules,
|
sourceModules = rootModules,
|
||||||
extras = extras,
|
extras = extras,
|
||||||
dependencies = TestCompilationDependencies(libraries = libraries, friends = friends),
|
dependencies = dependencies,
|
||||||
expectedExecutableFile = settings.artifactFileForExecutable(rootModules),
|
expectedArtifact = expectedArtifact
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun moduleToKlib(sourceModule: TestModule, freeCompilerArgs: TestCompilerArgs, settings: Settings): TestCompilation {
|
private fun moduleToKlib(sourceModule: TestModule, freeCompilerArgs: TestCompilerArgs, settings: Settings): TestCompilation<KLIB> {
|
||||||
val sourceModules = setOf(sourceModule)
|
val sourceModules = setOf(sourceModule)
|
||||||
val cacheKey = TestCompilationCacheKey.Klib(sourceModules, freeCompilerArgs)
|
val cacheKey = KlibCacheKey(sourceModules, freeCompilerArgs)
|
||||||
|
|
||||||
// Fast pass.
|
// Fast pass.
|
||||||
cachedCompilations[cacheKey]?.let { return it }
|
cachedKlibCompilations[cacheKey]?.let { return it }
|
||||||
|
|
||||||
// Long pass.
|
// Long pass.
|
||||||
val libraries = sourceModule.allDependencies.map { moduleToKlib(it, freeCompilerArgs, settings) }
|
val dependencies = buildList {
|
||||||
val friends = sourceModule.allFriends.map { moduleToKlib(it, freeCompilerArgs, settings) }
|
sourceModule.allDependencies.mapTo(this) { it.asKlibDependency(freeCompilerArgs, settings, Library) }
|
||||||
|
sourceModule.allFriends.mapTo(this) { it.asKlibDependency(freeCompilerArgs, settings, FriendLibrary) }
|
||||||
|
}
|
||||||
|
val expectedArtifact = KLIB(settings.artifactFileForKlib(sourceModule, freeCompilerArgs))
|
||||||
|
|
||||||
return cachedCompilations.computeIfAbsent(cacheKey) {
|
return cachedKlibCompilations.computeIfAbsent(cacheKey) {
|
||||||
TestCompilation.createForKlib(
|
LibraryCompilation(
|
||||||
settings = settings,
|
settings = settings,
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
sourceModules = sourceModules,
|
sourceModules = sourceModules,
|
||||||
dependencies = TestCompilationDependencies(libraries = libraries, friends = friends),
|
dependencies = dependencies,
|
||||||
expectedKlibFile = settings.artifactFileForKlib(sourceModule, freeCompilerArgs)
|
expectedArtifact = expectedArtifact
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T : TestCompilationDependencyType<KLIB>> TestModule.asKlibDependency(
|
||||||
|
freeCompilerArgs: TestCompilerArgs,
|
||||||
|
settings: Settings,
|
||||||
|
type: T
|
||||||
|
) = CompiledDependency(moduleToKlib(this, freeCompilerArgs, settings), type)
|
||||||
|
|
||||||
private fun Settings.artifactFileForExecutable(modules: Set<TestModule.Exclusive>) = when (modules.size) {
|
private fun Settings.artifactFileForExecutable(modules: Set<TestModule.Exclusive>) = when (modules.size) {
|
||||||
1 -> artifactFileForExecutable(modules.first())
|
1 -> artifactFileForExecutable(modules.first())
|
||||||
else -> multiModuleArtifactFile(modules, get<KotlinNativeTargets>().testTarget.family.exeSuffix)
|
else -> multiModuleArtifactFile(modules, get<KotlinNativeTargets>().testTarget.family.exeSuffix)
|
||||||
|
|||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.konan.blackboxtest.support.compilation
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.LoggedData
|
||||||
|
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||||
|
|
||||||
|
internal sealed interface TestCompilationResult<A : TestCompilationArtifact> {
|
||||||
|
sealed interface ImmediateResult<A : TestCompilationArtifact> : TestCompilationResult<A> {
|
||||||
|
val loggedData: LoggedData
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed interface Failure : ImmediateResult<Nothing>
|
||||||
|
|
||||||
|
data class Success<A : TestCompilationArtifact>(val resultingArtifact: A, override val loggedData: LoggedData.CompilerCall) :
|
||||||
|
ImmediateResult<A>
|
||||||
|
|
||||||
|
data class CompilerFailure(override val loggedData: LoggedData.CompilerCall) : Failure
|
||||||
|
data class UnexpectedFailure(override val loggedData: LoggedData.CompilerCallUnexpectedFailure) : Failure
|
||||||
|
data class DependencyFailures(val causes: Set<Failure>) : TestCompilationResult<Nothing>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <A : TestCompilationArtifact> TestCompilationResult<A>.assertSuccess(): Success<A> = when (this) {
|
||||||
|
is Success -> this
|
||||||
|
is Failure -> fail { describeFailure() }
|
||||||
|
is DependencyFailures -> fail { describeDependencyFailures() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Failure.describeFailure() = loggedData.withErrorMessage(
|
||||||
|
when (this@describeFailure) {
|
||||||
|
is CompilerFailure -> "Compilation failed."
|
||||||
|
is UnexpectedFailure -> "Compilation failed with unexpected exception."
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun DependencyFailures.describeDependencyFailures() =
|
||||||
|
buildString {
|
||||||
|
appendLine("Compilation aborted due to errors in dependency compilations (${causes.size} items). See details below.")
|
||||||
|
appendLine()
|
||||||
|
causes.forEachIndexed { index, cause ->
|
||||||
|
append("#").append(index + 1).append(". ")
|
||||||
|
appendLine(cause.describeFailure())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-4
@@ -11,8 +11,9 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
|||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.NoTestRunnerExtras
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.NoTestRunnerExtras
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.WithTestRunnerExtras
|
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.WithTestRunnerExtras
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilation
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilation
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.Executable
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationFactory
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationFactory
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccessfullyCompiled
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.TestCaseGroupProvider
|
import org.jetbrains.kotlin.konan.blackboxtest.support.group.TestCaseGroupProvider
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunners.extractTestNames
|
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunners.extractTestNames
|
||||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
|
||||||
@@ -32,7 +33,7 @@ internal class TestRunProvider(
|
|||||||
private val testCaseGroupProvider: TestCaseGroupProvider
|
private val testCaseGroupProvider: TestCaseGroupProvider
|
||||||
) : BaseTestRunProvider(), ExtensionContext.Store.CloseableResource {
|
) : BaseTestRunProvider(), ExtensionContext.Store.CloseableResource {
|
||||||
private val compilationFactory = TestCompilationFactory()
|
private val compilationFactory = TestCompilationFactory()
|
||||||
private val cachedCompilations = ThreadSafeCache<TestCompilationCacheKey, TestCompilation>()
|
private val cachedCompilations = ThreadSafeCache<TestCompilationCacheKey, TestCompilation<Executable>>()
|
||||||
private val cachedTestNames = ThreadSafeCache<TestCompilationCacheKey, Collection<TestName>>()
|
private val cachedTestNames = ThreadSafeCache<TestCompilationCacheKey, Collection<TestName>>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,8 +156,8 @@ internal class TestRunProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val (executableFile, loggedCompilerCall) = testCompilation.result.assertSuccessfullyCompiled() // <-- Compilation happens here.
|
val (artifact, loggedCompilerCall) = testCompilation.result.assertSuccess() // <-- Compilation happens here.
|
||||||
val executable = TestExecutable(executableFile, loggedCompilerCall)
|
val executable = TestExecutable(artifact.file, loggedCompilerCall)
|
||||||
|
|
||||||
return action(testCase, executable, cacheKey)
|
return action(testCase, executable, cacheKey)
|
||||||
}
|
}
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.konan.blackboxtest.support.util
|
||||||
|
|
||||||
|
internal class ArgsBuilder {
|
||||||
|
private val args = mutableListOf<String>()
|
||||||
|
|
||||||
|
fun add(vararg args: String) {
|
||||||
|
this.args += args
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(args: Iterable<String>) {
|
||||||
|
this.args += args
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> add(rawArgs: Iterable<T>, transform: (T) -> String) {
|
||||||
|
rawArgs.mapTo(args) { transform(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> addFlattened(rawArgs: Iterable<T>, transform: (T) -> Iterable<String>) {
|
||||||
|
rawArgs.flatMapTo(args) { transform(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T, R> addFlattenedTwice(rawArgs: Iterable<T>, transform1: (T) -> Iterable<R>, transform2: (R) -> String) {
|
||||||
|
rawArgs.forEach { add(transform1(it), transform2) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(): Array<String> = args.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun buildArgs(builderAction: ArgsBuilder.() -> Unit): Array<String> {
|
||||||
|
return ArgsBuilder().apply(builderAction).build()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user