diff --git a/compiler/rmi/kotlinr/src/KotlinCompilerClient.kt b/compiler/rmi/kotlinr/src/KotlinCompilerClient.kt index ab5324dda2b..7808fbdf82d 100644 --- a/compiler/rmi/kotlinr/src/KotlinCompilerClient.kt +++ b/compiler/rmi/kotlinr/src/KotlinCompilerClient.kt @@ -157,19 +157,33 @@ public class KotlinCompilerClient { return connectToService(compilerId, daemonOptions, errStream) } - public fun shutdownCompileService(): Unit { - KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonLaunchingOptions(), DaemonOptions(), System.out, autostart = false, checkId = false) + public fun shutdownCompileService(daemonOptions: DaemonOptions): Unit { + KotlinCompilerClient.connectToCompileService(CompilerId(), DaemonLaunchingOptions(), daemonOptions, System.out, autostart = false, checkId = false) ?.shutdown() } - public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { + public fun shutdownCompileService(): Unit { + shutdownCompileService(DaemonOptions()) + } + + public fun compile(compiler: CompileService, args: Array, out: OutputStream): Int { + + val outStrm = RemoteOutputStreamServer(out) + try { + return compiler.remoteCompile(args, outStrm, CompileService.OutputFormat.PLAIN) + } + finally { + outStrm.disconnect() + } + } + + public fun incrementalCompile(compiler: CompileService, args: Array, caches: Map, out: OutputStream): Int { val outStrm = RemoteOutputStreamServer(out) val cacheServers = hashMapOf() try { caches.forEach { cacheServers.put( it.getKey(), RemoteIncrementalCacheServer( it.getValue())) } - val res = compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) - return res + return compiler.remoteIncrementalCompile(args, cacheServers, outStrm, CompileService.OutputFormat.XML) } finally { cacheServers.forEach { it.getValue().disconnect() } diff --git a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt index 890c4eae466..5d5cd9c7530 100644 --- a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt +++ b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/CompileService.kt @@ -51,7 +51,7 @@ public interface CompileService : Remote { throws(RemoteException::class) public fun remoteIncrementalCompile( - args: Array, + args: Array, caches: Map, outputStream: RemoteOutputStream, outputFormat: OutputFormat): Int diff --git a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt index f5bb4fede4c..2719bc17e7b 100644 --- a/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt +++ b/compiler/rmi/rmi-server/src/org/jetbrains/kotlin/rmi/service/CompileServiceImpl.kt @@ -126,7 +126,7 @@ class CompileServiceImpl>( val res = body() val endTime = System.nanoTime() val endMem = usedMemory() / 1024 - log.info("Done") + log.info("Done with result " + res.toString()) log.info("Elapsed time: " + TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + " ms") log.info("Used memory: $endMem kb (${"%+d".format(endMem - startMem)} kb)") return res @@ -178,7 +178,7 @@ class CompileServiceImpl>( } } - override fun remoteIncrementalCompile(args: Array, caches: Map, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int = + override fun remoteIncrementalCompile(args: Array, caches: Map, errStream: RemoteOutputStream, outputFormat: CompileService.OutputFormat): Int = ifAlive { checkedCompile(args) { val strm = RemoteOutputStreamClient(errStream) diff --git a/compiler/tests/compiler-tests.iml b/compiler/tests/compiler-tests.iml index fb072c4387d..5448f557960 100644 --- a/compiler/tests/compiler-tests.iml +++ b/compiler/tests/compiler-tests.iml @@ -26,5 +26,7 @@ + + \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt new file mode 100644 index 00000000000..dd5842f9e5e --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/daemon/CompilerDaemonTest.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.daemon + +import junit.framework.TestCase +import org.jetbrains.kotlin.cli.CliBaseTest +import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase +import org.jetbrains.kotlin.rmi.CompilerId +import org.jetbrains.kotlin.rmi.DaemonLaunchingOptions +import org.jetbrains.kotlin.rmi.DaemonOptions +import org.jetbrains.kotlin.rmi.kotlinr.KotlinCompilerClient +import org.jetbrains.kotlin.test.JetTestUtils +import java.io.ByteArrayOutputStream +import java.io.File + +val KOTLIN_DAEMON_TEST_PORT = 19753 + +public class CompilerDaemonTest : KotlinIntegrationTestBase() { + + data class CompilerResults(val resultCode: Int, val out: String) + + val daemonOptions = DaemonOptions(port = KOTLIN_DAEMON_TEST_PORT) + val daemonLaunchingOptions = DaemonLaunchingOptions() + val compilerId by lazy { CompilerId.makeCompilerId( File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler.jar"), + File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-runtime.jar"), + File("dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-reflect.jar")) } + + private fun compileOnDaemon(args: Array): CompilerResults { + val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonLaunchingOptions, daemonOptions, System.err, autostart = true, checkId = true) + TestCase.assertNotNull("failed to connect daemon", daemon) + val strm = ByteArrayOutputStream() + val code = KotlinCompilerClient.compile(daemon!!, args, strm) + return CompilerResults(code, strm.toString()) + } + + private fun runDaemonCompilerTwice(logName: String, vararg arguments: String): Unit { + KotlinCompilerClient.shutdownCompileService(daemonOptions) + + try { + val res1 = compileOnDaemon(arguments) + TestCase.assertEquals("first compilation failed:\n${res1.out}", 0, res1.resultCode) + val res2 = compileOnDaemon(arguments) + TestCase.assertEquals("second compilation failed:\n${res2.out}", 0, res2.resultCode) + TestCase.assertEquals("build results differ", CliBaseTest.removePerfOutput(res1.out), CliBaseTest.removePerfOutput(res2.out)) + // TODO: add performance comparison assert + } + finally { + KotlinCompilerClient.shutdownCompileService(daemonOptions) + } + } + + private fun getTestBaseDir(): String = JetTestUtils.getTestDataPathBase() + "/integration/smoke/" + getTestName(true) + + private fun run(logName: String, vararg args: String): Int = runJava(getTestBaseDir(), logName, *args) + + public fun testHelloApp() { + val jar = tmpdir.absolutePath + File.separator + "hello.jar" + + runDaemonCompilerTwice("hello.compile", "-include-runtime", File(getTestBaseDir(), "hello.kt").absolutePath, "-d", jar) + run("hello.run", "-cp", jar, "Hello.HelloPackage") + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/integration/KotlinIntegrationTestBase.java b/compiler/tests/org/jetbrains/kotlin/integration/KotlinIntegrationTestBase.java index 4766c779fa4..2b81e49fc34 100644 --- a/compiler/tests/org/jetbrains/kotlin/integration/KotlinIntegrationTestBase.java +++ b/compiler/tests/org/jetbrains/kotlin/integration/KotlinIntegrationTestBase.java @@ -133,7 +133,7 @@ public abstract class KotlinIntegrationTestBase extends TestCaseWithTmpdir { return runtime; } - protected static File getCompilerLib() { + public static File getCompilerLib() { File file = PathUtil.getKotlinPathsForDistDirectory().getLibPath().getAbsoluteFile(); assertTrue("Lib directory doesn't exist. Run 'ant dist'", file.isDirectory()); return file;