Enable assertions in Kotlin Compile Daemon process
#KT-32992 Fixed
This commit is contained in:
@@ -314,9 +314,14 @@ fun configureDaemonJVMOptions(opts: DaemonJVMOptions,
|
|||||||
System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"$it\"") }
|
System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"$it\"") }
|
||||||
System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY)?.let { opts.jvmParams.add("D$KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY") }
|
System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY)?.let { opts.jvmParams.add("D$KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.jvmParams.none { it.matches(jvmAssertArgsRegex) }) {
|
||||||
|
opts.jvmParams.add("ea")
|
||||||
|
}
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val jvmAssertArgsRegex = "(es?a|ds?a|(enable|disable)(system)?assertions)(${'$'}|:)".toRegex()
|
||||||
|
|
||||||
fun configureDaemonJVMOptions(vararg additionalParams: String,
|
fun configureDaemonJVMOptions(vararg additionalParams: String,
|
||||||
inheritMemoryLimits: Boolean,
|
inheritMemoryLimits: Boolean,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.daemon
|
|||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.openapi.util.io.FileUtilRt
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
|
import junit.framework.Assert
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.cli.AbstractCliTest
|
import org.jetbrains.kotlin.cli.AbstractCliTest
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||||
@@ -187,6 +188,53 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testDaemonAssertsOptions() {
|
||||||
|
val allAssetionsArgs = setOf(
|
||||||
|
"-ea", "-enableassertions",
|
||||||
|
"-da", "-disableassertions",
|
||||||
|
"-esa", "-enablesystemassertions",
|
||||||
|
"-dsa", "-disablesystemassertions"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun assertionsJvmArgs() = configureDaemonJVMOptions(
|
||||||
|
inheritMemoryLimits = true,
|
||||||
|
inheritOtherJvmOptions = false,
|
||||||
|
inheritAdditionalProperties = true
|
||||||
|
).mappers.flatMap { it.toArgs("-") }.filter { it in allAssetionsArgs }.joinToString(", ")
|
||||||
|
|
||||||
|
for (assertArgValue in allAssetionsArgs) {
|
||||||
|
withDaemonJvmOptionsSetTo(assertArgValue) {
|
||||||
|
Assert.assertEquals(assertArgValue, assertionsJvmArgs())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
withDaemonJvmOptionsSetTo(null) {
|
||||||
|
Assert.assertEquals("-ea", assertionsJvmArgs())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun withDaemonJvmOptionsSetTo(newValue: String?, fn: () -> Unit) {
|
||||||
|
val backup = getAndSetSystemProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY, newValue)
|
||||||
|
|
||||||
|
try {
|
||||||
|
fn()
|
||||||
|
} finally {
|
||||||
|
getAndSetSystemProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY, backup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAndSetSystemProperty(property: String, newValue: String?): String? {
|
||||||
|
val oldValue = System.getProperty(property)
|
||||||
|
|
||||||
|
if (newValue != null) {
|
||||||
|
System.setProperty(property, newValue)
|
||||||
|
} else {
|
||||||
|
System.clearProperty(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldValue
|
||||||
|
}
|
||||||
|
|
||||||
fun testDaemonOptionsParsing() {
|
fun testDaemonOptionsParsing() {
|
||||||
val backupOptions = System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY)
|
val backupOptions = System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY)
|
||||||
try {
|
try {
|
||||||
|
|||||||
+48
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.daemon.experimental.integration
|
package org.jetbrains.kotlin.daemon.experimental.integration
|
||||||
|
|
||||||
|
import junit.framework.Assert
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.jetbrains.kotlin.cli.AbstractCliTest
|
import org.jetbrains.kotlin.cli.AbstractCliTest
|
||||||
@@ -264,6 +265,53 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ignore_testDaemonAssertsOptions() {
|
||||||
|
val allAssetionsArgs = setOf(
|
||||||
|
"-ea", "-enableassertions",
|
||||||
|
"-da", "-disableassertions",
|
||||||
|
"-esa", "-enablesystemassertions",
|
||||||
|
"-dsa", "-disablesystemassertions"
|
||||||
|
)
|
||||||
|
|
||||||
|
fun assertionsJvmArgs() = configureDaemonJVMOptions(
|
||||||
|
inheritMemoryLimits = true,
|
||||||
|
inheritOtherJvmOptions = false,
|
||||||
|
inheritAdditionalProperties = true
|
||||||
|
).mappers.flatMap { it.toArgs("-") }.filter { it in allAssetionsArgs }.joinToString(", ")
|
||||||
|
|
||||||
|
for (assertArgValue in allAssetionsArgs) {
|
||||||
|
withDaemonJvmOptionsSetTo(assertArgValue) {
|
||||||
|
Assert.assertEquals(assertArgValue, assertionsJvmArgs())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
withDaemonJvmOptionsSetTo(null) {
|
||||||
|
Assert.assertEquals("-ea", assertionsJvmArgs())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun withDaemonJvmOptionsSetTo(newValue: String?, fn: () -> Unit) {
|
||||||
|
val backup = getAndSetSystemProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY, newValue)
|
||||||
|
|
||||||
|
try {
|
||||||
|
fn()
|
||||||
|
} finally {
|
||||||
|
getAndSetSystemProperty(COMPILE_DAEMON_JVM_OPTIONS_PROPERTY, backup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAndSetSystemProperty(property: String, newValue: String?): String? {
|
||||||
|
val oldValue = System.getProperty(property)
|
||||||
|
|
||||||
|
if (newValue != null) {
|
||||||
|
System.setProperty(property, newValue)
|
||||||
|
} else {
|
||||||
|
System.clearProperty(property)
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldValue
|
||||||
|
}
|
||||||
|
|
||||||
fun ignore_testDaemonOptionsParsing() {
|
fun ignore_testDaemonOptionsParsing() {
|
||||||
val backupOptions = System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY)
|
val backupOptions = System.getProperty(COMPILE_DAEMON_OPTIONS_PROPERTY)
|
||||||
try {
|
try {
|
||||||
|
|||||||
-1
@@ -734,7 +734,6 @@ abstract class BaseGradleIT {
|
|||||||
|
|
||||||
// Workaround: override a console type set in the user machine gradle.properties (since Gradle 4.3):
|
// Workaround: override a console type set in the user machine gradle.properties (since Gradle 4.3):
|
||||||
add("--console=plain")
|
add("--console=plain")
|
||||||
add("-Dkotlin.daemon.ea=true")
|
|
||||||
addAll(options.freeCommandLineArgs)
|
addAll(options.freeCommandLineArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-12
@@ -1,6 +1,5 @@
|
|||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
import org.gradle.util.GradleVersion
|
|
||||||
import org.jetbrains.kotlin.gradle.util.checkedReplace
|
import org.jetbrains.kotlin.gradle.util.checkedReplace
|
||||||
import org.jetbrains.kotlin.gradle.util.getFileByName
|
import org.jetbrains.kotlin.gradle.util.getFileByName
|
||||||
import org.jetbrains.kotlin.gradle.util.modify
|
import org.jetbrains.kotlin.gradle.util.modify
|
||||||
@@ -66,23 +65,14 @@ abstract class ExecutionStrategyIT : BaseGradleIT() {
|
|||||||
val strategyCLIArg = "-Dkotlin.compiler.execution.strategy=$executionStrategy"
|
val strategyCLIArg = "-Dkotlin.compiler.execution.strategy=$executionStrategy"
|
||||||
val finishMessage = "Finished executing kotlin compiler using $executionStrategy strategy"
|
val finishMessage = "Finished executing kotlin compiler using $executionStrategy strategy"
|
||||||
|
|
||||||
val isGradleAtLeast50 = project.testGradleVersionAtLeast("5.0")
|
|
||||||
|
|
||||||
project.build("build", strategyCLIArg) {
|
project.build("build", strategyCLIArg) {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
assertContains(finishMessage)
|
assertContains(finishMessage)
|
||||||
checkOutput()
|
checkOutput()
|
||||||
assertNoWarnings()
|
assertNoWarnings()
|
||||||
|
|
||||||
if (executionStrategy == "daemon" && isGradleAtLeast50) {
|
if (executionStrategy == "daemon") {
|
||||||
val m = "Kotlin compile daemon JVM options: \\[(.*?)\\]".toRegex().find(output)
|
checkCompileDaemon()
|
||||||
?: error("Could not find Kotlin compile daemon JVM options in Gradle's output")
|
|
||||||
val kotlinDaemonJvmArgs = m.groupValues[1].split(",").map { it.trim() }
|
|
||||||
val maxMetaspaceArg = "-XX:MaxMetaspaceSize=256m"
|
|
||||||
Assert.assertTrue(
|
|
||||||
"Kotlin daemon JVM args do not contain '$maxMetaspaceArg': $kotlinDaemonJvmArgs",
|
|
||||||
maxMetaspaceArg in kotlinDaemonJvmArgs
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +88,28 @@ abstract class ExecutionStrategyIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun CompiledProject.checkCompileDaemon() {
|
||||||
|
val isGradleAtLeast50 = project.testGradleVersionAtLeast("5.0")
|
||||||
|
|
||||||
|
val m = "Kotlin compile daemon JVM options: \\[(.*?)\\]".toRegex().find(output)
|
||||||
|
?: error("Could not find Kotlin compile daemon JVM options in Gradle's output")
|
||||||
|
val kotlinDaemonJvmArgs = m.groupValues[1].split(",").mapTo(LinkedHashSet()) { it.trim() }
|
||||||
|
|
||||||
|
fun assertDaemonArgsContain(arg: String) {
|
||||||
|
Assert.assertTrue(
|
||||||
|
"Expected '$arg' in kotlin daemon JVM args, got: $kotlinDaemonJvmArgs",
|
||||||
|
arg in kotlinDaemonJvmArgs
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGradleAtLeast50) {
|
||||||
|
// 256m is the default value for Gradle 5.0+
|
||||||
|
assertDaemonArgsContain("-XX:MaxMetaspaceSize=256m")
|
||||||
|
}
|
||||||
|
|
||||||
|
assertDaemonArgsContain("-ea")
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun setupProject(project: Project) {
|
protected open fun setupProject(project: Project) {
|
||||||
project.setupWorkingDir()
|
project.setupWorkingDir()
|
||||||
File(project.projectDir, "app/build.gradle").appendText(
|
File(project.projectDir, "app/build.gradle").appendText(
|
||||||
|
|||||||
+1
-5
@@ -153,14 +153,10 @@ internal open class GradleCompilerRunner(protected val task: Task) {
|
|||||||
sessionIsAliveFlagFile: File,
|
sessionIsAliveFlagFile: File,
|
||||||
compilerFullClasspath: List<File>,
|
compilerFullClasspath: List<File>,
|
||||||
messageCollector: MessageCollector,
|
messageCollector: MessageCollector,
|
||||||
isDebugEnabled: Boolean,
|
isDebugEnabled: Boolean
|
||||||
enableAssertions: Boolean
|
|
||||||
): CompileServiceSession? {
|
): CompileServiceSession? {
|
||||||
val compilerId = CompilerId.makeCompilerId(compilerFullClasspath)
|
val compilerId = CompilerId.makeCompilerId(compilerFullClasspath)
|
||||||
val additionalJvmParams = arrayListOf<String>()
|
val additionalJvmParams = arrayListOf<String>()
|
||||||
if (enableAssertions) {
|
|
||||||
additionalJvmParams.add("ea")
|
|
||||||
}
|
|
||||||
return KotlinCompilerRunnerUtils.newDaemonConnection(
|
return KotlinCompilerRunnerUtils.newDaemonConnection(
|
||||||
compilerId, clientIsAliveFlagFile, sessionIsAliveFlagFile,
|
compilerId, clientIsAliveFlagFile, sessionIsAliveFlagFile,
|
||||||
messageCollector = messageCollector,
|
messageCollector = messageCollector,
|
||||||
|
|||||||
+1
-3
@@ -150,7 +150,6 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
|||||||
|
|
||||||
private fun compileWithDaemon(messageCollector: MessageCollector): ExitCode? {
|
private fun compileWithDaemon(messageCollector: MessageCollector): ExitCode? {
|
||||||
val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: true
|
val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: true
|
||||||
val enableAssertions = System.getProperty("kotlin.daemon.ea")?.toBoolean() ?: false
|
|
||||||
val daemonMessageCollector =
|
val daemonMessageCollector =
|
||||||
if (isDebugEnabled) messageCollector else MessageCollector.NONE
|
if (isDebugEnabled) messageCollector else MessageCollector.NONE
|
||||||
|
|
||||||
@@ -161,8 +160,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
|||||||
sessionFlagFile,
|
sessionFlagFile,
|
||||||
compilerFullClasspath,
|
compilerFullClasspath,
|
||||||
daemonMessageCollector,
|
daemonMessageCollector,
|
||||||
isDebugEnabled = isDebugEnabled,
|
isDebugEnabled = isDebugEnabled
|
||||||
enableAssertions = enableAssertions
|
|
||||||
)
|
)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log.error("Caught an exception trying to connect to Kotlin Daemon:")
|
log.error("Caught an exception trying to connect to Kotlin Daemon:")
|
||||||
|
|||||||
Reference in New Issue
Block a user