From fda37eaaaed9bac0351d75bb5cde7c222308743e Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Tue, 27 Aug 2019 11:29:43 +0200 Subject: [PATCH] [minor] Rearrange test utils for easier reuse --- .../kotlin/mainKts/test/mainKtsIT.kt | 89 ++--------- .../scripting-compiler/build.gradle.kts | 1 + .../plugin/ScriptingWithCliCompilerTest.kt | 68 ++------ .../scripting/compiler/plugin/testUtil.kt | 147 ++++++++++++++++++ 4 files changed, 174 insertions(+), 131 deletions(-) create mode 100644 plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt diff --git a/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt b/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt index b155762e58a..3544f196fb2 100644 --- a/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt +++ b/libraries/tools/kotlin-main-kts-test/test/org/jetbrains/kotlin/mainKts/test/mainKtsIT.kt @@ -5,93 +5,24 @@ package org.jetbrains.kotlin.mainKts.test -import junit.framework.Assert.* +import junit.framework.Assert import org.jetbrains.kotlin.scripting.compiler.plugin.runWithK2JVMCompiler +import org.jetbrains.kotlin.scripting.compiler.plugin.runWithKotlinc import org.junit.Test import java.io.File -import java.io.InputStream -import java.util.concurrent.TimeUnit -import kotlin.concurrent.thread class MainKtsIT { - // TODO: partially copypasted from LauncherReplTest, consider extracting common parts to some (new) test util module - private fun runWithKotlinc( - scriptPath: String, - expectedOutPatterns: List = emptyList(), - expectedExitCode: Int = 0, - workDirectory: File? = null - ) { - val executableName = "kotlinc" - // TODO: - val executableFileName = - if (System.getProperty("os.name").contains("windows", ignoreCase = true)) "$executableName.bat" else executableName - val launcherFile = File("dist/kotlinc/bin/$executableFileName") - assertTrue("Launcher script not found, run dist task: ${launcherFile.absolutePath}", launcherFile.exists()) - - val mainKtsJar = File("dist/kotlinc/lib/kotlin-main-kts.jar") - assertTrue("kotlin-main-kts.jar not found, run dist task: ${mainKtsJar.absolutePath}", mainKtsJar.exists()) - - val processBuilder = ProcessBuilder(launcherFile.absolutePath, "-cp", mainKtsJar.absolutePath, "-script", scriptPath) - if (workDirectory != null) { - processBuilder.directory(workDirectory) - } - val process = processBuilder.start() - - data class ExceptionContainer( - var value: Throwable? = null - ) - - fun InputStream.captureStream(): Triple> { - val out = ArrayList() - val exceptionContainer = ExceptionContainer() - val thread = thread { - try { - reader().forEachLine { - out.add(it.trim()) - } - } catch (e: Throwable) { - exceptionContainer.value = e - } - } - return Triple(thread, exceptionContainer, out) - } - - val (stdoutThread, stdoutException, processOut) = process.inputStream.captureStream() - val (stderrThread, stderrException, processErr) = process.errorStream.captureStream() - - process.waitFor(30000, TimeUnit.MILLISECONDS) - - try { - if (process.isAlive) { - process.destroyForcibly() - fail("Process terminated forcibly") - } - stdoutThread.join(300) - assertFalse("stdout thread not finished", stdoutThread.isAlive) - assertNull(stdoutException.value) - stderrThread.join(300) - assertFalse("stderr thread not finished", stderrThread.isAlive) - assertNull(stderrException.value) - assertEquals(expectedOutPatterns.size, processOut.size) - for ((expectedPattern, actualLine) in expectedOutPatterns.zip(processOut)) { - assertTrue( - "line \"$actualLine\" do not match with expected pattern \"$expectedPattern\"", - Regex(expectedPattern).matches(actualLine) - ) - } - assertEquals(expectedExitCode, process.exitValue()) - - } catch (e: Throwable) { - println("OUT:\n${processOut.joinToString("\n")}") - println("ERR:\n${processErr.joinToString("\n")}") - throw e - } - } - @Test fun testResolveJunit() { - runWithKotlinc("$TEST_DATA_ROOT/hello-resolve-junit.main.kts", listOf("Hello, World!")) + runWithKotlinc( + "$TEST_DATA_ROOT/hello-resolve-junit.main.kts", listOf("Hello, World!"), + classpath = listOf( + File("dist/kotlinc/lib/kotlin-main-kts.jar").also { + Assert.assertTrue("kotlin-main-kts.jar not found, run dist task: ${it.absolutePath}", it.exists()) + } + ) + ) } @Test diff --git a/plugins/scripting/scripting-compiler/build.gradle.kts b/plugins/scripting/scripting-compiler/build.gradle.kts index 0a52f37f51f..e66eb6bc5d0 100644 --- a/plugins/scripting/scripting-compiler/build.gradle.kts +++ b/plugins/scripting/scripting-compiler/build.gradle.kts @@ -54,5 +54,6 @@ javadocJar() testsJar() projectTest { + dependsOn(":dist") workingDir = rootDir } diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt index 26a0be74e77..1ac3453a84f 100644 --- a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt @@ -5,13 +5,9 @@ package org.jetbrains.kotlin.scripting.compiler.plugin -import java.io.File -import junit.framework.Assert.* -import org.jetbrains.kotlin.cli.common.CLITool -import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler +import junit.framework.Assert import org.junit.Test -import java.io.ByteArrayOutputStream -import java.io.PrintStream +import java.io.File class ScriptingWithCliCompilerTest { @@ -24,58 +20,26 @@ class ScriptingWithCliCompilerTest { runWithK2JVMCompiler("$TEST_DATA_DIR/integration/intResult.kts", listOf("10")) } + @Test + fun testResultValueViaKotlinc() { + runWithKotlinc("$TEST_DATA_DIR/integration/intResult.kts", listOf("10")) + } + @Test fun testStandardScriptWithDeps() { runWithK2JVMCompiler("$TEST_DATA_DIR/integration/withDependencyOnCompileClassPath.kts", listOf("Hello from standard kts!")) } -} -fun runWithK2JVMCompiler( - scriptPath: String, - expectedOutPatterns: List = emptyList(), - expectedExitCode: Int = 0 -) { - val mainKtsJar = File("dist/kotlinc/lib/kotlin-main-kts.jar") - assertTrue("kotlin-main-kts.jar not found, run dist task: ${mainKtsJar.absolutePath}", mainKtsJar.exists()) - - val (out, err, ret) = captureOutErrRet { - CLITool.doMainNoExit( - K2JVMCompiler(), - arrayOf("-kotlin-home", "dist/kotlinc", "-cp", mainKtsJar.absolutePath, "-script", scriptPath) + @Test + fun testStandardScriptWithDepsViaKotlinc() { + runWithKotlinc( + "$TEST_DATA_DIR/integration/withDependencyOnCompileClassPath.kts", listOf("Hello from standard kts!"), + classpath = listOf( + File("dist/kotlinc/lib/kotlin-main-kts.jar").also { + Assert.assertTrue("kotlin-main-kts.jar not found, run dist task: ${it.absolutePath}", it.exists()) + } + ) ) } - try { - val outLines = out.lines() - assertEquals(expectedOutPatterns.size, outLines.size) - for ((expectedPattern, actualLine) in expectedOutPatterns.zip(outLines)) { - assertTrue( - "line \"$actualLine\" do not match with expected pattern \"$expectedPattern\"", - Regex(expectedPattern).matches(actualLine) - ) - } - assertEquals(expectedExitCode, ret.code) - } catch (e: Throwable) { - println("OUT:\n$out") - println("ERR:\n$err") - throw e - } } - -internal fun captureOutErrRet(body: () -> T): Triple { - val outStream = ByteArrayOutputStream() - val errStream = ByteArrayOutputStream() - val prevOut = System.out - val prevErr = System.err - System.setOut(PrintStream(outStream)) - System.setErr(PrintStream(errStream)) - val ret = try { - body() - } finally { - System.out.flush() - System.err.flush() - System.setOut(prevOut) - System.setErr(prevErr) - } - return Triple(outStream.toString().trim(), errStream.toString().trim(), ret) -} diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt new file mode 100644 index 00000000000..065fa153648 --- /dev/null +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt @@ -0,0 +1,147 @@ +/* + * Copyright 2010-2019 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.scripting.compiler.plugin + +import junit.framework.Assert +import org.jetbrains.kotlin.cli.common.CLITool +import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.InputStream +import java.io.PrintStream +import java.util.concurrent.TimeUnit +import kotlin.concurrent.thread + +// TODO: partially copypasted from LauncherReplTest, consider extracting common parts to some (new) test util module +fun runWithKotlinc( + scriptPath: String, + expectedOutPatterns: List = emptyList(), + expectedExitCode: Int = 0, + workDirectory: File? = null, + classpath: List = emptyList() +) { + val executableName = "kotlinc" + // TODO: + val executableFileName = + if (System.getProperty("os.name").contains("windows", ignoreCase = true)) "$executableName.bat" else executableName + val launcherFile = File("dist/kotlinc/bin/$executableFileName") + Assert.assertTrue("Launcher script not found, run dist task: ${launcherFile.absolutePath}", launcherFile.exists()) + + val args = arrayListOf(launcherFile.absolutePath).apply { + if (classpath.isNotEmpty()) { + add("-cp") + add(classpath.joinToString(File.pathSeparator)) + } + add("-script") + add(scriptPath) + } + val processBuilder = ProcessBuilder(args) + if (workDirectory != null) { + processBuilder.directory(workDirectory) + } + val process = processBuilder.start() + + data class ExceptionContainer( + var value: Throwable? = null + ) + + fun InputStream.captureStream(): Triple> { + val out = ArrayList() + val exceptionContainer = ExceptionContainer() + val thread = thread { + try { + reader().forEachLine { + out.add(it.trim()) + } + } catch (e: Throwable) { + exceptionContainer.value = e + } + } + return Triple(thread, exceptionContainer, out) + } + + val (stdoutThread, stdoutException, processOut) = process.inputStream.captureStream() + val (stderrThread, stderrException, processErr) = process.errorStream.captureStream() + + process.waitFor(30000, TimeUnit.MILLISECONDS) + + try { + if (process.isAlive) { + process.destroyForcibly() + Assert.fail("Process terminated forcibly") + } + stdoutThread.join(300) + Assert.assertFalse("stdout thread not finished", stdoutThread.isAlive) + Assert.assertNull(stdoutException.value) + stderrThread.join(300) + Assert.assertFalse("stderr thread not finished", stderrThread.isAlive) + Assert.assertNull(stderrException.value) + Assert.assertEquals(expectedOutPatterns.size, processOut.size) + for ((expectedPattern, actualLine) in expectedOutPatterns.zip(processOut)) { + Assert.assertTrue( + "line \"$actualLine\" do not match with expected pattern \"$expectedPattern\"", + Regex(expectedPattern).matches(actualLine) + ) + } + Assert.assertEquals(expectedExitCode, process.exitValue()) + + } catch (e: Throwable) { + println("OUT:\n${processOut.joinToString("\n")}") + println("ERR:\n${processErr.joinToString("\n")}") + throw e + } +} + +fun runWithK2JVMCompiler( + scriptPath: String, + expectedOutPatterns: List = emptyList(), + expectedExitCode: Int = 0 +) { + val mainKtsJar = File("dist/kotlinc/lib/kotlin-main-kts.jar") + Assert.assertTrue("kotlin-main-kts.jar not found, run dist task: ${mainKtsJar.absolutePath}", mainKtsJar.exists()) + + val (out, err, ret) = captureOutErrRet { + CLITool.doMainNoExit( + K2JVMCompiler(), + arrayOf("-kotlin-home", "dist/kotlinc", "-cp", mainKtsJar.absolutePath, "-script", scriptPath) + ) + } + try { + val outLines = out.lines() + Assert.assertEquals(expectedOutPatterns.size, outLines.size) + for ((expectedPattern, actualLine) in expectedOutPatterns.zip(outLines)) { + Assert.assertTrue( + "line \"$actualLine\" do not match with expected pattern \"$expectedPattern\"", + Regex(expectedPattern).matches(actualLine) + ) + } + Assert.assertEquals(expectedExitCode, ret.code) + } catch (e: Throwable) { + println("OUT:\n$out") + println("ERR:\n$err") + throw e + } +} + + +internal fun captureOutErrRet(body: () -> T): Triple { + val outStream = ByteArrayOutputStream() + val errStream = ByteArrayOutputStream() + val prevOut = System.out + val prevErr = System.err + System.setOut(PrintStream(outStream)) + System.setErr(PrintStream(errStream)) + val ret = try { + body() + } finally { + System.out.flush() + System.err.flush() + System.setOut(prevOut) + System.setErr(prevErr) + } + return Triple(outStream.toString().trim(), errStream.toString().trim(), ret) +} +