Immplement default cache in main-kts

This commit is contained in:
Ilya Chernikov
2020-01-15 18:02:33 +01:00
parent a4752087db
commit 1b65ec75ad
4 changed files with 146 additions and 33 deletions
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.mainKts.test
import junit.framework.Assert
import org.jetbrains.kotlin.mainKts.COMPILED_SCRIPTS_CACHE_DIR_ENV_VAR
import org.jetbrains.kotlin.mainKts.COMPILED_SCRIPTS_CACHE_DIR_PROPERTY
import org.jetbrains.kotlin.scripting.compiler.plugin.runWithK2JVMCompiler
import org.jetbrains.kotlin.scripting.compiler.plugin.runWithKotlinc
import org.junit.Ignore
@@ -49,26 +51,35 @@ class MainKtsIT {
fun runWithKotlincAndMainKts(
scriptPath: String,
expectedOutPatterns: List<String> = emptyList(),
expectedExitCode: Int = 0
) = runWithKotlinc(
scriptPath, expectedOutPatterns, expectedExitCode,
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())
}
expectedExitCode: Int = 0,
cacheDir: File? = null
) {
runWithKotlinc(
scriptPath, expectedOutPatterns, expectedExitCode,
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())
}
),
additionalEnvVars = listOf(COMPILED_SCRIPTS_CACHE_DIR_ENV_VAR to (cacheDir?.absolutePath ?: ""))
)
)
}
fun runWithK2JVMCompilerAndMainKts(
scriptPath: String,
expectedOutPatterns: List<String> = emptyList(),
expectedExitCode: Int = 0
) = runWithK2JVMCompiler(
scriptPath, expectedOutPatterns, expectedExitCode,
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())
}
)
)
expectedExitCode: Int = 0,
cacheDir: File? = null
) {
withProperty(COMPILED_SCRIPTS_CACHE_DIR_PROPERTY, cacheDir?.absolutePath ?: "") {
runWithK2JVMCompiler(
scriptPath, expectedOutPatterns, expectedExitCode,
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())
}
)
)
}
}
@@ -4,10 +4,12 @@
*/
package org.jetbrains.kotlin.mainKts.test
import org.jetbrains.kotlin.mainKts.COMPILED_SCRIPTS_CACHE_DIR_PROPERTY
import org.jetbrains.kotlin.mainKts.MainKtsScript
import org.junit.Assert
import org.junit.Test
import java.io.*
import java.net.URLClassLoader
import kotlin.script.experimental.api.*
import kotlin.script.experimental.host.toScriptSource
import kotlin.script.experimental.jvm.baseClassLoader
@@ -15,20 +17,21 @@ import kotlin.script.experimental.jvm.jvm
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate
fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
fun evalFile(scriptFile: File, cacheDir: File? = null): ResultWithDiagnostics<EvaluationResult> =
withProperty(COMPILED_SCRIPTS_CACHE_DIR_PROPERTY, cacheDir?.absolutePath ?: "") {
val scriptDefinition = createJvmCompilationConfigurationFromTemplate<MainKtsScript>()
val scriptDefinition = createJvmCompilationConfigurationFromTemplate<MainKtsScript>()
val evaluationEnv = ScriptEvaluationConfiguration {
jvm {
baseClassLoader(null)
val evaluationEnv = ScriptEvaluationConfiguration {
jvm {
baseClassLoader(null)
}
constructorArgs(emptyArray<String>())
enableScriptsInstancesSharing()
}
constructorArgs(emptyArray<String>())
enableScriptsInstancesSharing()
BasicJvmScriptingHost().eval(scriptFile.toScriptSource(), scriptDefinition, evaluationEnv)
}
return BasicJvmScriptingHost().eval(scriptFile.toScriptSource(), scriptDefinition, evaluationEnv)
}
const val TEST_DATA_ROOT = "libraries/tools/kotlin-main-kts-test/testData"
@@ -77,6 +80,8 @@ class MainKtsTest {
assertSucceeded(res)
}
private val outFromImportTest = listOf("Hi from common", "Hi from middle", "sharedVar == 5")
@Test
fun testImport() {
@@ -85,7 +90,7 @@ class MainKtsTest {
assertSucceeded(res)
}.lines()
Assert.assertEquals(listOf("Hi from common", "Hi from middle", "sharedVar == 5"), out)
Assert.assertEquals(outFromImportTest, out)
}
@Test
@@ -100,6 +105,34 @@ class MainKtsTest {
Assert.assertEquals(listOf("Hi from sub", "Hi from super", "Hi from random"), out)
}
@Test
fun testCache() {
val script = File("$TEST_DATA_ROOT/import-test.main.kts")
val cache = createTempDir("main.kts.test")
try {
Assert.assertTrue(cache.exists() && cache.listFiles { f: File -> f.extension == "jar" }?.isEmpty() == true)
val out1 = evalSuccessWithOut(script)
Assert.assertEquals(outFromImportTest, out1)
Assert.assertTrue(cache.listFiles { f: File -> f.extension.equals("jar", ignoreCase = true) }?.isEmpty() == true)
val out2 = evalSuccessWithOut(script, cache)
Assert.assertEquals(outFromImportTest, out2)
val casheFile = cache.listFiles { f: File -> f.extension.equals("jar", ignoreCase = true) }?.firstOrNull()
Assert.assertTrue(casheFile != null && casheFile.exists())
val out3 = captureOut {
val classLoader = URLClassLoader(arrayOf(casheFile!!.toURI().toURL()), null)
val clazz = classLoader.loadClass("Import_test_main")
val mainFn = clazz.getDeclaredMethod("main", Array<String>::class.java)
mainFn.invoke(null, arrayOf<String>())
}.lines()
Assert.assertEquals(outFromImportTest, out3)
} finally {
cache.deleteRecursively()
}
}
private fun assertIsJava6Bytecode(res: ResultWithDiagnostics<EvaluationResult>) {
val scriptClassResource = res.valueOrThrow().returnValue.scriptClass!!.java.run {
getResource("$simpleName.class")
@@ -129,6 +162,12 @@ class MainKtsTest {
res is ResultWithDiagnostics.Failure && res.reports.any { it.message.contains("$expectedError") }
)
}
private fun evalSuccessWithOut(scriptFile: File, cacheDir: File? = null): List<String> =
captureOut {
val res = evalFile(scriptFile, cacheDir)
assertSucceeded(res)
}.lines()
}
internal fun captureOut(body: () -> Unit): String {
@@ -143,3 +182,15 @@ internal fun captureOut(body: () -> Unit): String {
}
return outStream.toString().trim()
}
internal fun <T> withProperty(name: String, value: String?, body: () -> T): T {
val prevCacheDir = System.getProperty(name)
if (value == null) System.clearProperty(name)
else System.setProperty(name, value)
try {
return body()
} finally {
if (prevCacheDir == null) System.clearProperty(name)
else System.setProperty(name, prevCacheDir)
}
}