[Native][tests] Add a directive to specify test runner type
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
// TEST_RUNNER: DEFAULT
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun addition() {
|
||||
assertEquals(42, 40 + 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multiplication () {
|
||||
assertEquals(42, 21 * 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtraction () {
|
||||
assertEquals(42, 50 - 8)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun division () {
|
||||
assertEquals(42, 126 / 3)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// TEST_RUNNER: NO_EXIT
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun addition() {
|
||||
assertEquals(42, 40 + 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multiplication () {
|
||||
assertEquals(42, 21 * 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtraction () {
|
||||
assertEquals(42, 50 - 8)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun division () {
|
||||
assertEquals(42, 126 / 3)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// TEST_RUNNER: WORKER
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun addition() {
|
||||
assertEquals(42, 40 + 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multiplication () {
|
||||
assertEquals(42, 21 * 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtraction () {
|
||||
assertEquals(42, 50 - 8)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun division () {
|
||||
assertEquals(42, 126 / 3)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// KIND: STANDALONE
|
||||
// TEST_RUNNER: DEFAULT
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun addition() {
|
||||
assertEquals(42, 40 + 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multiplication () {
|
||||
assertEquals(42, 21 * 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtraction () {
|
||||
assertEquals(42, 50 - 8)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun division () {
|
||||
assertEquals(42, 126 / 3)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// KIND: STANDALONE
|
||||
// TEST_RUNNER: NO_EXIT
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun addition() {
|
||||
assertEquals(42, 40 + 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multiplication () {
|
||||
assertEquals(42, 21 * 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtraction () {
|
||||
assertEquals(42, 50 - 8)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun division () {
|
||||
assertEquals(42, 126 / 3)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// KIND: STANDALONE
|
||||
// TEST_RUNNER: WORKER
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun addition() {
|
||||
assertEquals(42, 40 + 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun multiplication () {
|
||||
assertEquals(42, 21 * 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subtraction () {
|
||||
assertEquals(42, 50 - 8)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun division () {
|
||||
assertEquals(42, 126 / 3)
|
||||
}
|
||||
+12
-6
@@ -7,6 +7,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.konan.blackboxtest.support
|
||||
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.WithTestRunnerExtras
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule.Companion.allDependencies
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.TestMode
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.*
|
||||
@@ -177,7 +178,7 @@ internal class TestCase(
|
||||
) {
|
||||
sealed interface Extras
|
||||
class NoTestRunnerExtras(val entryPoint: String, val inputDataFile: File?) : Extras
|
||||
object WithTestRunnerExtras : Extras
|
||||
class WithTestRunnerExtras(val runnerType: TestRunnerType) : Extras
|
||||
|
||||
init {
|
||||
when (kind) {
|
||||
@@ -256,7 +257,7 @@ internal interface TestCaseGroupId {
|
||||
internal interface TestCaseGroup {
|
||||
fun isEnabled(testCaseId: TestCaseId): Boolean
|
||||
fun getByName(testCaseId: TestCaseId): TestCase?
|
||||
fun getRegularOnlyByCompilerArgs(freeCompilerArgs: TestCompilerArgs): Collection<TestCase>
|
||||
fun getRegularOnly(freeCompilerArgs: TestCompilerArgs, runnerType: TestRunnerType): Collection<TestCase>
|
||||
|
||||
class Default(
|
||||
private val disabledTestCaseIds: Set<TestCaseId>,
|
||||
@@ -267,15 +268,20 @@ internal interface TestCaseGroup {
|
||||
override fun isEnabled(testCaseId: TestCaseId) = testCaseId !in disabledTestCaseIds
|
||||
override fun getByName(testCaseId: TestCaseId) = testCasesById[testCaseId]
|
||||
|
||||
override fun getRegularOnlyByCompilerArgs(freeCompilerArgs: TestCompilerArgs) =
|
||||
testCasesById.values.filter { it.kind == TestKind.REGULAR && it.freeCompilerArgs == freeCompilerArgs }
|
||||
override fun getRegularOnly(freeCompilerArgs: TestCompilerArgs, runnerType: TestRunnerType) =
|
||||
testCasesById.values.filter { testCase ->
|
||||
testCase.kind == TestKind.REGULAR
|
||||
&& testCase.extras<WithTestRunnerExtras>().runnerType == runnerType
|
||||
&& testCase.freeCompilerArgs == freeCompilerArgs
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ALL_DISABLED = object : TestCaseGroup {
|
||||
override fun isEnabled(testCaseId: TestCaseId) = false
|
||||
override fun getByName(testCaseId: TestCaseId) = fail { "This function should not be called" }
|
||||
override fun getRegularOnlyByCompilerArgs(freeCompilerArgs: TestCompilerArgs) = fail { "This function should not be called" }
|
||||
override fun getByName(testCaseId: TestCaseId) = unsupported()
|
||||
override fun getRegularOnly(freeCompilerArgs: TestCompilerArgs, runnerType: TestRunnerType) = unsupported()
|
||||
private fun unsupported(): Nothing = fail { "This function should not be called" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-4
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.compilerRunner.processCompilerOutput
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
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.TestCompilation.Companion.resultingArtifactPath
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCompilationResult.Companion.assertSuccess
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestModule.Companion.allDependencies
|
||||
@@ -41,13 +42,12 @@ internal class TestCompilationFactory(private val settings: Settings) {
|
||||
cachedCompilations[cacheKey]?.let { return it }
|
||||
|
||||
// Long pass.
|
||||
val freeCompilerArgs = rootModules.first().testCase.freeCompilerArgs
|
||||
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 libraries = rootModules.flatMapToSet { it.allDependencies }.map { moduleToKlib(it, freeCompilerArgs) }
|
||||
val friends = rootModules.flatMapToSet { it.allFriends }.map { moduleToKlib(it, freeCompilerArgs) }
|
||||
|
||||
return cachedCompilations.computeIfAbsent(cacheKey) {
|
||||
val entryPoint = testCases.singleOrNull()?.safeExtras<NoTestRunnerExtras>()?.entryPoint
|
||||
|
||||
TestCompilationImpl(
|
||||
settings = settings,
|
||||
freeCompilerArgs = freeCompilerArgs,
|
||||
@@ -56,7 +56,17 @@ internal class TestCompilationFactory(private val settings: Settings) {
|
||||
expectedArtifactFile = artifactFileForExecutable(rootModules),
|
||||
specificCompilerArgs = {
|
||||
add("-produce", "program")
|
||||
if (entryPoint != null) add("-entry", entryPoint) else add("-generate-test-runner")
|
||||
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)
|
||||
}
|
||||
}
|
||||
settings.get<GlobalSettings>().getRootCacheDirectory(debuggable = true)?.let { rootCacheDir ->
|
||||
add("-Xcache-directory=$rootCacheDir")
|
||||
}
|
||||
|
||||
+23
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.FREE_COMPI
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.INPUT_DATA_FILE
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.KIND
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.OUTPUT_DATA_FILE
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.TEST_RUNNER
|
||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||
import org.jetbrains.kotlin.test.directives.model.StringDirective
|
||||
@@ -35,6 +36,14 @@ internal object TestDirectives : SimpleDirectivesContainer() {
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val TEST_RUNNER by enumDirective<TestRunnerType>(
|
||||
description = """
|
||||
Usage: // TEST_RUNNER: [DEFAULT, WORKER, NO_EXIT]
|
||||
Specify test runner type.
|
||||
Note that this directive makes sense only in combination with // KIND: REGULAR or // KIND: STANDALONE
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val ENTRY_POINT by stringDirective(
|
||||
description = """
|
||||
Specify custom program entry point. The default entry point is `main` function in the root package.
|
||||
@@ -81,6 +90,12 @@ internal enum class TestKind {
|
||||
STANDALONE_NO_TR;
|
||||
}
|
||||
|
||||
internal enum class TestRunnerType {
|
||||
DEFAULT,
|
||||
WORKER,
|
||||
NO_EXIT
|
||||
}
|
||||
|
||||
internal class TestCompilerArgs(val compilerArgs: List<String>) {
|
||||
private val uniqueCompilerArgs = compilerArgs.toSet()
|
||||
override fun hashCode() = uniqueCompilerArgs.hashCode()
|
||||
@@ -115,6 +130,14 @@ internal fun parseTestKind(registeredDirectives: RegisteredDirectives, location:
|
||||
return values.singleOrNull() ?: fail { "$location: Exactly one test kind expected in $KIND directive: $values" }
|
||||
}
|
||||
|
||||
internal fun parseTestRunner(registeredDirectives: RegisteredDirectives, location: Location): TestRunnerType {
|
||||
if (TEST_RUNNER !in registeredDirectives)
|
||||
return TestRunnerType.DEFAULT // The default one.
|
||||
|
||||
val values = registeredDirectives[TEST_RUNNER]
|
||||
return values.singleOrNull() ?: fail { "$location: Exactly one test runner type expected in $TEST_RUNNER directive: $values" }
|
||||
}
|
||||
|
||||
internal fun parseEntryPoint(registeredDirectives: RegisteredDirectives, location: Location): String {
|
||||
if (ENTRY_POINT !in registeredDirectives)
|
||||
return "main" // The default one.
|
||||
|
||||
+9
-3
@@ -9,6 +9,7 @@ package org.jetbrains.kotlin.konan.blackboxtest.support
|
||||
|
||||
import com.intellij.openapi.util.Disposer
|
||||
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.TestCompilationResult.Companion.assertSuccess
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.TestCaseGroupProvider
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.AbstractRunner
|
||||
@@ -143,9 +144,10 @@ internal class TestRunProvider(
|
||||
}
|
||||
TestKind.REGULAR -> {
|
||||
// Group regular test cases by compiler arguments.
|
||||
val cacheKey = TestCompilationCacheKey.Grouped(testCaseId.testCaseGroupId, testCase.freeCompilerArgs)
|
||||
val testRunnerType = testCase.extras<WithTestRunnerExtras>().runnerType
|
||||
val cacheKey = TestCompilationCacheKey.Grouped(testCaseId.testCaseGroupId, testCase.freeCompilerArgs, testRunnerType)
|
||||
val testCompilation = cachedCompilations.computeIfAbsent(cacheKey) {
|
||||
val testCases = testCaseGroup.getRegularOnlyByCompilerArgs(testCase.freeCompilerArgs)
|
||||
val testCases = testCaseGroup.getRegularOnly(testCase.freeCompilerArgs, testRunnerType)
|
||||
assertTrue(testCases.isNotEmpty())
|
||||
compilationFactory.testCasesToExecutable(testCases)
|
||||
}
|
||||
@@ -217,6 +219,10 @@ internal class TestRunProvider(
|
||||
|
||||
private sealed class TestCompilationCacheKey {
|
||||
data class Standalone(val testCaseId: TestCaseId) : TestCompilationCacheKey()
|
||||
data class Grouped(val testCaseGroupId: TestCaseGroupId, val freeCompilerArgs: TestCompilerArgs) : TestCompilationCacheKey()
|
||||
data class Grouped(
|
||||
val testCaseGroupId: TestCaseGroupId,
|
||||
val freeCompilerArgs: TestCompilerArgs,
|
||||
val runnerType: TestRunnerType
|
||||
) : TestCompilationCacheKey()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -594,7 +594,7 @@ private class ExtTestDataFile(
|
||||
freeCompilerArgs = assembleFreeCompilerArgs(),
|
||||
nominalPackageName = testDataFileSettings.nominalPackageName,
|
||||
expectedOutputDataFile = null,
|
||||
extras = WithTestRunnerExtras
|
||||
extras = WithTestRunnerExtras(runnerType = TestRunnerType.DEFAULT)
|
||||
)
|
||||
testCase.initialize(sharedModules::get)
|
||||
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ internal class PredefinedTestCaseGroupProvider(private val settings: Settings, a
|
||||
.parseCompilerArgs { "Failed to parse free compiler arguments for test case $testCaseId" },
|
||||
nominalPackageName = PackageName(testCaseId.uniqueName),
|
||||
expectedOutputDataFile = null,
|
||||
extras = WithTestRunnerExtras
|
||||
extras = WithTestRunnerExtras(runnerType = TestRunnerType.DEFAULT) // TODO: pass TR from the predefined configuration here
|
||||
)
|
||||
testCase.initialize(null)
|
||||
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ internal class StandardTestCaseGroupProvider(private val settings: Settings) : T
|
||||
inputDataFile = parseInputDataFile(baseDir = testDataFile.parentFile, registeredDirectives, location)
|
||||
)
|
||||
else
|
||||
WithTestRunnerExtras
|
||||
WithTestRunnerExtras(runnerType = parseTestRunner(registeredDirectives, location))
|
||||
)
|
||||
testCase.initialize(findSharedModule = null)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user