Drop TestCaseWithTempDir usage from scripting compiler plugin tests
fighting with flaky tests
This commit is contained in:
+136
-120
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.scripting.compiler.plugin
|
package org.jetbrains.kotlin.scripting.compiler.plugin
|
||||||
|
|
||||||
|
import com.intellij.openapi.Disposable
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
@@ -29,7 +30,6 @@ import org.jetbrains.kotlin.scripting.definitions.discoverScriptTemplatesInClass
|
|||||||
import org.jetbrains.kotlin.scripting.definitions.loadScriptTemplatesFromClasspath
|
import org.jetbrains.kotlin.scripting.definitions.loadScriptTemplatesFromClasspath
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
|
|
||||||
import org.jetbrains.kotlin.test.TestJdkKind
|
import org.jetbrains.kotlin.test.TestJdkKind
|
||||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||||
import org.jetbrains.kotlin.utils.PathUtil
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
@@ -37,7 +37,7 @@ import org.junit.Assert
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||||
|
|
||||||
class ScriptingCompilerPluginTest : TestCaseWithTmpdir() {
|
class ScriptingCompilerPluginTest : TestCase() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TEST_DATA_DIR = "plugins/scripting/scripting-compiler/testData"
|
const val TEST_DATA_DIR = "plugins/scripting/scripting-compiler/testData"
|
||||||
@@ -54,7 +54,11 @@ class ScriptingCompilerPluginTest : TestCaseWithTmpdir() {
|
|||||||
val scriptingClasspath = listOf("kotlin-scripting-common.jar").map { File(kotlinPaths.libPath, it) }
|
val scriptingClasspath = listOf("kotlin-scripting-common.jar").map { File(kotlinPaths.libPath, it) }
|
||||||
|
|
||||||
private fun createEnvironment(
|
private fun createEnvironment(
|
||||||
sources: List<String>, destDir: File, messageCollector: MessageCollector, confBody: CompilerConfiguration.() -> Unit
|
sources: List<String>,
|
||||||
|
destDir: File,
|
||||||
|
messageCollector: MessageCollector,
|
||||||
|
disposable: Disposable,
|
||||||
|
confBody: CompilerConfiguration.() -> Unit
|
||||||
): KotlinCoreEnvironment {
|
): KotlinCoreEnvironment {
|
||||||
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.NO_KOTLIN_REFLECT, TestJdkKind.FULL_JDK).apply {
|
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.NO_KOTLIN_REFLECT, TestJdkKind.FULL_JDK).apply {
|
||||||
put<MessageCollector>(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
put<MessageCollector>(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
||||||
@@ -64,7 +68,7 @@ class ScriptingCompilerPluginTest : TestCaseWithTmpdir() {
|
|||||||
}
|
}
|
||||||
configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar())
|
configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar())
|
||||||
|
|
||||||
return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
return KotlinCoreEnvironment.createForTests(disposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testScriptResolverEnvironmentArgsParsing() {
|
fun testScriptResolverEnvironmentArgsParsing() {
|
||||||
@@ -90,138 +94,150 @@ class ScriptingCompilerPluginTest : TestCaseWithTmpdir() {
|
|||||||
|
|
||||||
fun testLazyScriptDefinitionDiscovery() {
|
fun testLazyScriptDefinitionDiscovery() {
|
||||||
|
|
||||||
// Three tests in one function: the direct loading, the discovery code separately, and as a part of regular compilation
|
withTempDir { tmpdir ->
|
||||||
// tests are combined to avoid multiple compilation of script definition modules
|
withDisposable { disposable ->
|
||||||
|
// Three tests in one function: the direct loading, the discovery code separately, and as a part of regular compilation
|
||||||
|
// tests are combined to avoid multiple compilation of script definition modules
|
||||||
|
|
||||||
val defsOut = File(tmpdir, "testLazyScriptDefinition/out/defs")
|
val defsOut = File(tmpdir, "testLazyScriptDefinition/out/defs")
|
||||||
val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions")
|
val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions")
|
||||||
val scriptsOut = File(tmpdir, "testLazyScriptDefinition/out/scripts")
|
val scriptsOut = File(tmpdir, "testLazyScriptDefinition/out/scripts")
|
||||||
val scriptsSrc = File(TEST_DATA_DIR, "lazyDefinitions/scripts")
|
val scriptsSrc = File(TEST_DATA_DIR, "lazyDefinitions/scripts")
|
||||||
val scriptsOut2 = File(tmpdir, "testLazyScriptDefinition/out/scripts2")
|
val scriptsOut2 = File(tmpdir, "testLazyScriptDefinition/out/scripts2")
|
||||||
val defClasses = listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars")
|
val defClasses = listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars")
|
||||||
|
|
||||||
val messageCollector = TestMessageCollector()
|
val messageCollector = TestMessageCollector()
|
||||||
|
|
||||||
val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources(
|
val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources(
|
||||||
createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector) {
|
createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector, disposable) {
|
||||||
addJvmClasspathRoots(runtimeClasspath)
|
addJvmClasspathRoots(runtimeClasspath)
|
||||||
addJvmClasspathRoots(scriptingClasspath)
|
addJvmClasspathRoots(scriptingClasspath)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
assertTrue(definitionsCompileResult) {
|
assertTrue(definitionsCompileResult) {
|
||||||
"Compilation of script definitions failed: $messageCollector"
|
"Compilation of script definitions failed: $messageCollector"
|
||||||
}
|
}
|
||||||
|
|
||||||
messageCollector.clear()
|
messageCollector.clear()
|
||||||
|
|
||||||
loadScriptTemplatesFromClasspath(
|
loadScriptTemplatesFromClasspath(
|
||||||
listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars"),
|
listOf("TestScriptWithReceivers", "TestScriptWithSimpleEnvVars"),
|
||||||
listOf(defsOut), emptyList(), this::class.java.classLoader, defaultJvmScriptingHostConfiguration, messageCollector.reporter
|
listOf(defsOut),
|
||||||
).toList()
|
emptyList(),
|
||||||
|
this::class.java.classLoader,
|
||||||
|
defaultJvmScriptingHostConfiguration,
|
||||||
|
messageCollector.reporter
|
||||||
|
).toList()
|
||||||
|
|
||||||
for (def in defClasses) {
|
for (def in defClasses) {
|
||||||
assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) {
|
assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) {
|
||||||
"Missing messages from loading sequence (should contain \"Added template $def\"):\n$messageCollector"
|
"Missing messages from loading sequence (should contain \"Added template $def\"):\n$messageCollector"
|
||||||
}
|
}
|
||||||
assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) {
|
assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) {
|
||||||
"Unexpected messages from loading sequence (should not contain \"loading script definition class $def\"):\n$messageCollector"
|
"Unexpected messages from loading sequence (should not contain \"loading script definition class $def\"):\n$messageCollector"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messageCollector.clear()
|
||||||
|
|
||||||
|
// chacking lazy discovery
|
||||||
|
|
||||||
|
val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() }
|
||||||
|
for (def in defClasses) {
|
||||||
|
File(templatesDir, def).createNewFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
val lazyDefsSeq =
|
||||||
|
discoverScriptTemplatesInClasspath(
|
||||||
|
listOf(defsOut),
|
||||||
|
this::class.java.classLoader,
|
||||||
|
defaultJvmScriptingHostConfiguration,
|
||||||
|
messageCollector.reporter
|
||||||
|
)
|
||||||
|
|
||||||
|
assertTrue(messageCollector.messages.isEmpty()) {
|
||||||
|
"Unexpected messages from discovery sequence (should be empty):\n$messageCollector"
|
||||||
|
}
|
||||||
|
|
||||||
|
val lazyDefs = lazyDefsSeq.toList()
|
||||||
|
|
||||||
|
for (def in defClasses) {
|
||||||
|
assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) {
|
||||||
|
"Missing messages from discovery sequence (should contain \"Added template $def\"):\n$messageCollector"
|
||||||
|
}
|
||||||
|
assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) {
|
||||||
|
"Unexpected messages from discovery sequence (should not contain \"loading script definition class $def\"):\n$messageCollector"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messageCollector.clear()
|
||||||
|
|
||||||
|
val scriptFiles = scriptsSrc.listFiles { file: File -> file.extension == "kts" }.map { it.canonicalPath }
|
||||||
|
|
||||||
|
val scriptsCompileEnv = createEnvironment(scriptFiles, scriptsOut, messageCollector, disposable) {
|
||||||
|
addJvmClasspathRoots(runtimeClasspath)
|
||||||
|
addJvmClasspathRoots(scriptingClasspath)
|
||||||
|
addJvmClasspathRoot(defsOut)
|
||||||
|
addAll(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS, lazyDefs)
|
||||||
|
}
|
||||||
|
|
||||||
|
val res = KotlinToJVMBytecodeCompiler.compileBunchOfSources(scriptsCompileEnv)
|
||||||
|
|
||||||
|
assertTrue(res) {
|
||||||
|
"Failed to compile scripts:\n$messageCollector"
|
||||||
|
}
|
||||||
|
|
||||||
|
val cp = (runtimeClasspath + scriptingClasspath + defsOut).joinToString(File.pathSeparator)
|
||||||
|
val exitCode = K2JVMCompiler().exec(System.err, "-cp", cp, *(scriptFiles.toTypedArray()), "-d", scriptsOut2.canonicalPath)
|
||||||
|
|
||||||
|
Assert.assertEquals(ExitCode.OK, exitCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
messageCollector.clear()
|
|
||||||
|
|
||||||
// chacking lazy discovery
|
|
||||||
|
|
||||||
val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() }
|
|
||||||
for (def in defClasses) {
|
|
||||||
File(templatesDir, def).createNewFile()
|
|
||||||
}
|
|
||||||
|
|
||||||
val lazyDefsSeq =
|
|
||||||
discoverScriptTemplatesInClasspath(
|
|
||||||
listOf(defsOut),
|
|
||||||
this::class.java.classLoader,
|
|
||||||
defaultJvmScriptingHostConfiguration,
|
|
||||||
messageCollector.reporter
|
|
||||||
)
|
|
||||||
|
|
||||||
assertTrue(messageCollector.messages.isEmpty()) {
|
|
||||||
"Unexpected messages from discovery sequence (should be empty):\n$messageCollector"
|
|
||||||
}
|
|
||||||
|
|
||||||
val lazyDefs = lazyDefsSeq.toList()
|
|
||||||
|
|
||||||
for (def in defClasses) {
|
|
||||||
assertTrue(messageCollector.messages.any { it.message.contains("Configure scripting: Added template $def") }) {
|
|
||||||
"Missing messages from discovery sequence (should contain \"Added template $def\"):\n$messageCollector"
|
|
||||||
}
|
|
||||||
assertTrue(messageCollector.messages.none { it.message.contains("Configure scripting: loading script definition class $def") }) {
|
|
||||||
"Unexpected messages from discovery sequence (should not contain \"loading script definition class $def\"):\n$messageCollector"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
messageCollector.clear()
|
|
||||||
|
|
||||||
val scriptFiles = scriptsSrc.listFiles { file: File -> file.extension == "kts" }.map { it.canonicalPath}
|
|
||||||
|
|
||||||
val scriptsCompileEnv = createEnvironment(scriptFiles, scriptsOut, messageCollector) {
|
|
||||||
addJvmClasspathRoots(runtimeClasspath)
|
|
||||||
addJvmClasspathRoots(scriptingClasspath)
|
|
||||||
addJvmClasspathRoot(defsOut)
|
|
||||||
addAll(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS, lazyDefs)
|
|
||||||
}
|
|
||||||
|
|
||||||
val res = KotlinToJVMBytecodeCompiler.compileBunchOfSources(scriptsCompileEnv)
|
|
||||||
|
|
||||||
assertTrue(res) {
|
|
||||||
"Failed to compile scripts:\n$messageCollector"
|
|
||||||
}
|
|
||||||
|
|
||||||
val cp = (runtimeClasspath + scriptingClasspath + defsOut).joinToString(File.pathSeparator)
|
|
||||||
val exitCode = K2JVMCompiler().exec(System.err, "-cp", cp, *(scriptFiles.toTypedArray()), "-d", scriptsOut2.canonicalPath)
|
|
||||||
|
|
||||||
Assert.assertEquals(ExitCode.OK, exitCode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testLazyScriptDefinitionOtherAnnotation() {
|
fun testLazyScriptDefinitionOtherAnnotation() {
|
||||||
|
|
||||||
val defsOut = File(tmpdir, "testLazyScriptDefinition/out/otherAnn")
|
withTempDir { tmpdir ->
|
||||||
val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions")
|
withDisposable { disposable ->
|
||||||
val defClasses = listOf("TestScriptWithOtherAnnotation")
|
val defsOut = File(tmpdir, "testLazyScriptDefinition/out/otherAnn")
|
||||||
|
val defsSrc = File(TEST_DATA_DIR, "lazyDefinitions/definitions")
|
||||||
|
val defClasses = listOf("TestScriptWithOtherAnnotation")
|
||||||
|
|
||||||
val messageCollector = TestMessageCollector()
|
val messageCollector = TestMessageCollector()
|
||||||
|
|
||||||
val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources(
|
val definitionsCompileResult = KotlinToJVMBytecodeCompiler.compileBunchOfSources(
|
||||||
createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector) {
|
createEnvironment(defClasses.map { File(defsSrc, "$it.kt").canonicalPath }, defsOut, messageCollector, disposable) {
|
||||||
addJvmClasspathRoots(runtimeClasspath)
|
addJvmClasspathRoots(runtimeClasspath)
|
||||||
addJvmClasspathRoots(scriptingClasspath)
|
addJvmClasspathRoots(scriptingClasspath)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertTrue(definitionsCompileResult) {
|
||||||
|
"Compilation of script definitions failed: $messageCollector"
|
||||||
|
}
|
||||||
|
|
||||||
|
val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() }
|
||||||
|
for (def in defClasses) {
|
||||||
|
File(templatesDir, def).createNewFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
messageCollector.clear()
|
||||||
|
|
||||||
|
discoverScriptTemplatesInClasspath(
|
||||||
|
listOf(defsOut),
|
||||||
|
this::class.java.classLoader,
|
||||||
|
defaultJvmScriptingHostConfiguration,
|
||||||
|
messageCollector.reporter
|
||||||
|
).toList()
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
messageCollector.messages.isNotEmpty()
|
||||||
|
&& messageCollector.messages.all { it.message.contains("s not marked with any known kotlin script annotation") }
|
||||||
|
) {
|
||||||
|
"Unexpected messages from discovery sequence:\n$messageCollector"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
assertTrue(definitionsCompileResult) {
|
|
||||||
"Compilation of script definitions failed: $messageCollector"
|
|
||||||
}
|
|
||||||
|
|
||||||
val templatesDir = File(defsOut, SCRIPT_DEFINITION_MARKERS_PATH).also { it.mkdirs() }
|
|
||||||
for (def in defClasses) {
|
|
||||||
File(templatesDir, def).createNewFile()
|
|
||||||
}
|
|
||||||
|
|
||||||
messageCollector.clear()
|
|
||||||
|
|
||||||
discoverScriptTemplatesInClasspath(
|
|
||||||
listOf(defsOut),
|
|
||||||
this::class.java.classLoader,
|
|
||||||
defaultJvmScriptingHostConfiguration,
|
|
||||||
messageCollector.reporter
|
|
||||||
).toList()
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
messageCollector.messages.isNotEmpty()
|
|
||||||
&& messageCollector.messages.all { it.message.contains("s not marked with any known kotlin script annotation") }
|
|
||||||
) {
|
|
||||||
"Unexpected messages from discovery sequence:\n$messageCollector"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.scripting.compiler.plugin
|
package org.jetbrains.kotlin.scripting.compiler.plugin
|
||||||
|
|
||||||
|
import com.intellij.openapi.Disposable
|
||||||
|
import com.intellij.openapi.util.Disposer
|
||||||
import junit.framework.Assert
|
import junit.framework.Assert
|
||||||
import org.jetbrains.kotlin.cli.common.CLITool
|
import org.jetbrains.kotlin.cli.common.CLITool
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||||
@@ -12,6 +14,7 @@ import java.io.ByteArrayOutputStream
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
|
import java.nio.file.Files
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
@@ -151,3 +154,22 @@ internal fun <T> captureOutErrRet(body: () -> T): Triple<String, String, T> {
|
|||||||
return Triple(outStream.toString().trim(), errStream.toString().trim(), ret)
|
return Triple(outStream.toString().trim(), errStream.toString().trim(), ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <R> withTempDir(keyName: String = "tmp", body: (File) -> R) {
|
||||||
|
val tempDir = Files.createTempDirectory(keyName).toFile()
|
||||||
|
try {
|
||||||
|
body(tempDir)
|
||||||
|
} finally {
|
||||||
|
tempDir.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun <R> withDisposable(body: (Disposable) -> R) {
|
||||||
|
val disposable = Disposer.newDisposable()
|
||||||
|
try {
|
||||||
|
body(disposable)
|
||||||
|
} finally {
|
||||||
|
Disposer.dispose(disposable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user