diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/jvm8against6/jdk8Against6.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/jvm8against6/jdk8Against6.kt index ea875801559..7b27a77f915 100644 --- a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/jvm8against6/jdk8Against6.kt +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/jvm8against6/jdk8Against6.kt @@ -1,4 +1,5 @@ // SKIP_JDK6 +// FULL_JDK // MODULE: lib // FILE: A.kt import java.util.* @@ -13,7 +14,6 @@ class Jdk6List : AbstractList() { } // MODULE: main(lib) -// FULL_JDK // FILE: B.kt fun box(): String { diff --git a/compiler/tests-common-new/build.gradle.kts b/compiler/tests-common-new/build.gradle.kts index d7a5f84cec3..ca46149571c 100644 --- a/compiler/tests-common-new/build.gradle.kts +++ b/compiler/tests-common-new/build.gradle.kts @@ -24,6 +24,7 @@ dependencies { testApi(projectTests(":compiler:test-infrastructure")) testApi(projectTests(":compiler:test-infrastructure-utils")) testApi(projectTests(":compiler:tests-compiler-utils")) + testApi(projectTests(":compiler:tests-common-jvm6")) testImplementation(intellijDep()) { // This dependency is needed only for FileComparisonFailure diff --git a/compiler/tests-different-jdk/build.gradle.kts b/compiler/tests-different-jdk/build.gradle.kts index 789490d6546..46e1f235e75 100644 --- a/compiler/tests-different-jdk/build.gradle.kts +++ b/compiler/tests-different-jdk/build.gradle.kts @@ -9,7 +9,20 @@ val testJvm6ServerRuntime by configurations.creating dependencies { testCompile(projectTests(":compiler")) + testApi(projectTests(":compiler:test-infrastructure")) + testApi(projectTests(":compiler:test-infrastructure-utils")) + testApi(projectTests(":compiler:tests-compiler-utils")) testCompile(projectTests(":compiler:tests-common")) + testCompile(projectTests(":compiler:tests-common-new")) + + testApi(platform("org.junit:junit-bom:5.7.0")) + testApi("org.junit.jupiter:junit-jupiter") + testApi("org.junit.vintage:junit-vintage-engine:5.7.0") + testApi("org.junit.platform:junit-platform-commons:1.7.0") + testApi("org.junit.platform:junit-platform-launcher:1.7.0") + testApi("org.junit.platform:junit-platform-runner:1.7.0") + testApi("org.junit.platform:junit-platform-suite-api:1.7.0") + testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") } testRuntime(project(":kotlin-reflect")) testRuntime(intellijDep()) @@ -34,11 +47,12 @@ fun Project.codegenTest( target: Int, jvm: String, jdk: String, targetInTestClass: String = "$target", body: Test.() -> Unit -): TaskProvider = projectTest("codegenTarget${targetInTestClass}Jvm${jvm}Test") { +): TaskProvider = projectTest("codegenTarget${targetInTestClass}Jvm${jvm}Test", jUnit5Enabled = true) { dependsOn(":dist") workingDir = rootDir - filter.includeTestsMatching("org.jetbrains.kotlin.codegen.jdk.JvmTarget${targetInTestClass}OnJvm${jvm}") + val testName = "JvmTarget${targetInTestClass}OnJvm${jvm}" + filter.includeTestsMatching("org.jetbrains.kotlin.codegen.jdk.$testName") systemProperty("kotlin.test.default.jvm.target", "${if (target <= 8) "1." else ""}$target") body() diff --git a/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt index 9877ff60276..1392c59982b 100644 --- a/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt +++ b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt @@ -5,105 +5,65 @@ package org.jetbrains.kotlin.codegen.jdk -import org.jetbrains.kotlin.codegen.* -import org.jetbrains.kotlin.codegen.CodegenTestCase.BOX_IN_SEPARATE_PROCESS_PORT -import org.jetbrains.kotlin.test.RunOnlyJdk6Test -import org.jetbrains.kotlin.test.SuiteRunnerForCustomJdk -import org.junit.AfterClass -import org.junit.BeforeClass +import org.jetbrains.kotlin.codegen.jdk.RunOnlyJdk6Test +import org.jetbrains.kotlin.test.runners.codegen.BlackBoxCodegenTestGenerated +import org.jetbrains.kotlin.test.runners.codegen.BlackBoxInlineCodegenTestGenerated +import org.jetbrains.kotlin.test.runners.codegen.CompileKotlinAgainstInlineKotlinTestGenerated +import org.junit.jupiter.api.parallel.Execution +import org.junit.jupiter.api.parallel.ExecutionMode +import org.junit.platform.runner.JUnitPlatform +import org.junit.platform.suite.api.IncludeClassNamePatterns +import org.junit.platform.suite.api.SelectClasses +import org.junit.platform.suite.api.UseTechnicalNames import org.junit.runner.RunWith -import org.junit.runners.Suite -import java.io.File -import kotlin.test.assertTrue /* * NB: ALL NECESSARY FLAGS ARE PASSED THROUGH Gradle */ -@Suite.SuiteClasses( +@SelectClasses( + BlackBoxCodegenTestGenerated::class, BlackBoxInlineCodegenTestGenerated::class, - CompileKotlinAgainstInlineKotlinTestGenerated::class, - CompileKotlinAgainstKotlinTestGenerated::class, - BlackBoxAgainstJavaCodegenTestGenerated::class + CompileKotlinAgainstInlineKotlinTestGenerated::class ) +@IncludeClassNamePatterns(".*Test.*Generated") +@Execution(ExecutionMode.SAME_THREAD) +@UseTechnicalNames abstract class CustomJvmTargetOnJvmBaseTest @RunOnlyJdk6Test -@RunWith(SuiteRunnerForCustomJdk::class) -class JvmTarget6OnJvm6 : CustomJvmTargetOnJvmBaseTest() { +@Execution(ExecutionMode.SAME_THREAD) +@RunWith(JUnitPlatformRunnerForJdk6::class) +class JvmTarget6OnJvm6 : CustomJvmTargetOnJvmBaseTest() - companion object { - - private lateinit var jdkProcess: Process - - @JvmStatic - @BeforeClass - fun setUp() { - println("Configuring JDK6 Test server...") - val jdkPath = System.getenv("JDK_16") ?: error("JDK_16 is not optional to run this test") - - val executable = File(jdkPath, "bin/java").canonicalPath - val main = "org.jetbrains.kotlin.test.clientserver.TestProcessServer" - val classpath = - System.getProperty("kotlin.test.box.in.separate.process.server.classpath") ?: System.getProperty("java.class.path") - - println("Server classpath: $classpath") - val port = BOX_IN_SEPARATE_PROCESS_PORT ?: error("kotlin.test.box.in.separate.process.port is not specified") - val builder = ProcessBuilder(executable, "-cp", classpath, main, port) - - builder.inheritIO() - - println("Starting JDK 6 server $executable...") - jdkProcess = builder.start() - Thread.sleep(2000) - assertTrue(jdkProcess.isAlive, "Test server process hasn't started") - println("Test server started!") - Runtime.getRuntime().addShutdownHook(object : Thread() { - override fun run() { - tearDown() - } - }) - } - - @JvmStatic - @AfterClass - fun tearDown() { - println("Stopping JDK 6 server...") - if (::jdkProcess.isInitialized) { - jdkProcess.destroy() - } - } - } -} - -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget8OnJvm8 : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget6OnJvm11 : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget8OnJvm11 : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget11OnJvm11 : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget6OnJvmLast : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget8OnJvmLast : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTargetLastOnJvmLast : CustomJvmTargetOnJvmBaseTest() //TODO: delete old tasks -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget6OnJvm9 : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget8OnJvm9 : CustomJvmTargetOnJvmBaseTest() -@RunWith(SuiteRunnerForCustomJdk::class) +@RunWith(JUnitPlatform::class) class JvmTarget9OnJvm9 : CustomJvmTargetOnJvmBaseTest() diff --git a/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/JUnitPlatformRunnerForJdk6.kt b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/JUnitPlatformRunnerForJdk6.kt new file mode 100644 index 00000000000..2ca1961b934 --- /dev/null +++ b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/JUnitPlatformRunnerForJdk6.kt @@ -0,0 +1,54 @@ +/* + * 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.codegen.jdk + +import org.jetbrains.kotlin.test.InTextDirectivesUtils +import org.jetbrains.kotlin.test.TestMetadata +import org.junit.platform.runner.JUnitPlatform +import org.junit.runner.Description +import org.junit.runner.manipulation.Filter +import org.junit.runner.notification.RunNotifier +import java.io.File + +annotation class RunOnlyJdk6Test + +class JUnitPlatformRunnerForJdk6(testClass: Class<*>) : JUnitPlatform(testClass) { + init { + if (testClass.getAnnotation(RunOnlyJdk6Test::class.java) != null) { + this.filter(object : Filter() { + override fun shouldRun(description: Description): Boolean { + if (description.isTest) { + @Suppress("NAME_SHADOWING") + val testClass = description.testClass ?: return true + val methodName = description.methodName ?: return true + + val testClassAnnotation = testClass.getAnnotation(TestMetadata::class.java) ?: return true + val method = testClass.getMethod(methodName) + val methodAnnotation = method.getAnnotation(TestMetadata::class.java) ?: return true + val path = "${testClassAnnotation.value}/${methodAnnotation.value}" + val fileText = File(path).readText() + return !InTextDirectivesUtils.isDirectiveDefined(fileText, "// JVM_TARGET:") && + !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_JDK6") + } + return true + } + + override fun describe(): String { + return "skipped on JDK 6" + } + }) + } + } + + override fun run(notifier: RunNotifier?) { + SeparateJavaProcessHelper.setUp() + try { + super.run(notifier) + } finally { + SeparateJavaProcessHelper.tearDown() + } + } +} diff --git a/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/SeparateJavaProcessHelper.kt b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/SeparateJavaProcessHelper.kt new file mode 100644 index 00000000000..45b90628c7a --- /dev/null +++ b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/SeparateJavaProcessHelper.kt @@ -0,0 +1,71 @@ +/* + * 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.codegen.jdk + +import org.jetbrains.kotlin.codegen.CodegenTestCase +import java.io.File +import java.util.concurrent.locks.ReentrantLock +import kotlin.concurrent.withLock +import kotlin.test.assertTrue + +object SeparateJavaProcessHelper { + private lateinit var jdkProcess: Process + + private val lock = ReentrantLock() + private var counter = 0 + + fun setUp() { + lock.withLock { + if (counter == 0) { + initJdkProcess() + } + counter += 1 + } + } + + fun tearDown() { + lock.withLock { + counter -= 1 + if (counter == 0) { + destroyJdkProcess() + } + } + } + + private fun initJdkProcess() { + println("Configuring JDK6 Test server...") + val jdkPath = System.getenv("JDK_16") ?: error("JDK_16 is not optional to run this test") + + val executable = File(jdkPath, "bin/java").canonicalPath + val main = "org.jetbrains.kotlin.test.clientserver.TestProcessServer" + val classpath = + System.getProperty("kotlin.test.box.in.separate.process.server.classpath") ?: System.getProperty("java.class.path") + + println("Server classpath: $classpath") + val port = CodegenTestCase.BOX_IN_SEPARATE_PROCESS_PORT ?: error("kotlin.test.box.in.separate.process.port is not specified") + val builder = ProcessBuilder(executable, "-cp", classpath, main, port) + + builder.inheritIO() + + println("Starting JDK 6 server $executable...") + jdkProcess = builder.start() + Thread.sleep(2000) + assertTrue(jdkProcess.isAlive, "Test server process hasn't started") + println("Test server started!") + Runtime.getRuntime().addShutdownHook(object : Thread() { + override fun run() { + destroyJdkProcess() + } + }) + } + + private fun destroyJdkProcess() { + println("Stopping JDK 6 server...") + if (::jdkProcess.isInitialized) { + jdkProcess.destroy() + } + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/test/SuiteRunnerForCustomJdk.kt b/compiler/tests/org/jetbrains/kotlin/test/SuiteRunnerForCustomJdk.kt deleted file mode 100644 index 717847e845c..00000000000 --- a/compiler/tests/org/jetbrains/kotlin/test/SuiteRunnerForCustomJdk.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2010-2018 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.test - -import org.junit.runner.Description -import org.junit.runner.manipulation.Filter -import org.junit.runners.Suite -import org.junit.runners.model.RunnerBuilder -import java.io.File -import java.lang.reflect.Modifier -import java.util.* - -annotation class RunOnlyJdk6Test - -class SuiteRunnerForCustomJdk constructor(klass: Class<*>, builder: RunnerBuilder?) : - Suite(builder, klass, getAnnotatedClasses(klass).flatMap { - collectDeclaredClasses( - it, - true - ) - }.distinct().toTypedArray()) { - - init { - if (klass.getAnnotation(RunOnlyJdk6Test::class.java) != null) { - filter(object : Filter() { - override fun shouldRun(description: Description): Boolean { - if (description.isTest) { - val methodAnnotation = description.getAnnotation(TestMetadata::class.java) ?: return true - val testClassAnnotation = description.testClass.getAnnotation(TestMetadata::class.java) ?: return true - - val path = testClassAnnotation.value + "/" + methodAnnotation.value - val fileText = File(path).readText() - return !InTextDirectivesUtils.isDirectiveDefined(fileText, "// JVM_TARGET:") && - !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_JDK6") - } - return true - } - - override fun describe(): String { - return "skipped on JDK 6" - } - }) - } - } - - companion object { - - private fun getAnnotatedClasses(klass: Class<*>, addSuperAnnotations: Boolean = true): List> { - val annotation = klass.getAnnotation(SuiteClasses::class.java) - return (annotation?.value?.map { it.java } ?: emptyList()) + - if (addSuperAnnotations) getAnnotatedClasses( - klass.superclass, - false - ) else emptyList() - } - - private fun collectDeclaredClasses(klass: Class<*>, withItself: Boolean): List> { - val result = ArrayList>() - if (klass.enclosingClass != null && !Modifier.isStatic(klass.modifiers)) return emptyList() - - if (withItself) { - result.add(klass) - } - - for (aClass in klass.declaredClasses) { - result.addAll(collectDeclaredClasses(aClass, true)) - } - - return result - } - } -}