Rewrite parallel daemon start test to make it tougher but more robust
This commit is contained in:
@@ -401,7 +401,7 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
|
|
||||||
fun testParallelDaemonStart() {
|
fun testParallelDaemonStart() {
|
||||||
|
|
||||||
val PARALLEL_THREADS_TO_START = 10
|
val PARALLEL_THREADS_TO_START = 16
|
||||||
|
|
||||||
val doneLatch = CountDownLatch(PARALLEL_THREADS_TO_START)
|
val doneLatch = CountDownLatch(PARALLEL_THREADS_TO_START)
|
||||||
|
|
||||||
@@ -417,6 +417,7 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
runFilesPath = File(tmpdir, getTestName(true)).absolutePath,
|
runFilesPath = File(tmpdir, getTestName(true)).absolutePath,
|
||||||
verbose = true)
|
verbose = true)
|
||||||
val logFile = createTempFile("kotlin-daemon-test", ".log")
|
val logFile = createTempFile("kotlin-daemon-test", ".log")
|
||||||
|
logFiles[threadNo] = logFile
|
||||||
val daemonJVMOptions =
|
val daemonJVMOptions =
|
||||||
configureDaemonJVMOptions(DaemonJVMOptions(maxMemory = "2048m"),
|
configureDaemonJVMOptions(DaemonJVMOptions(maxMemory = "2048m"),
|
||||||
"D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile.loggerCompatiblePath}\"",
|
"D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"${logFile.loggerCompatiblePath}\"",
|
||||||
@@ -424,7 +425,9 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
val daemonWithSession = KotlinCompilerClient.connectAndLease(compilerId, flagFile, daemonJVMOptions, daemonOptions,
|
val daemonWithSession = KotlinCompilerClient.connectAndLease(compilerId, flagFile, daemonJVMOptions, daemonOptions,
|
||||||
DaemonReportingTargets(out = System.err), autostart = true,
|
DaemonReportingTargets(out = System.err), autostart = true,
|
||||||
leaseSession = true, sessionAliveFlagFile = sessionFlagFile)
|
leaseSession = true, sessionAliveFlagFile = sessionFlagFile)
|
||||||
assertNotNull("failed to connect daemon", daemonWithSession?.first)
|
if (daemonWithSession?.first == null) {
|
||||||
|
fail("failed to connect daemon:\n${logFile.readLines().joinToString("\n")}\n------")
|
||||||
|
}
|
||||||
val jar = tmpdir.absolutePath + File.separator + "hello.$threadNo.jar"
|
val jar = tmpdir.absolutePath + File.separator + "hello.$threadNo.jar"
|
||||||
val res = KotlinCompilerClient.compile(
|
val res = KotlinCompilerClient.compile(
|
||||||
daemonWithSession!!.first,
|
daemonWithSession!!.first,
|
||||||
@@ -433,7 +436,6 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
arrayOf(File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar),
|
arrayOf(File(getHelloAppBaseDir(), "hello.kt").absolutePath, "-d", jar),
|
||||||
outStreams[threadNo])
|
outStreams[threadNo])
|
||||||
resultCodes[threadNo] = res
|
resultCodes[threadNo] = res
|
||||||
logFiles[threadNo] = logFile
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,23 +444,32 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(1..PARALLEL_THREADS_TO_START).forEach { connectThread(it - 1) }
|
System.setProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY, "true")
|
||||||
|
System.setProperty(COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY, "100000")
|
||||||
|
|
||||||
|
val succeeded = try {
|
||||||
|
(1..PARALLEL_THREADS_TO_START).forEach { connectThread(it - 1) }
|
||||||
|
doneLatch.await(PARALLEL_WAIT_TIMEOUT_S, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
System.clearProperty(COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY)
|
||||||
|
System.clearProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY)
|
||||||
|
}
|
||||||
|
|
||||||
val succeeded = doneLatch.await(PARALLEL_WAIT_TIMEOUT_S, TimeUnit.SECONDS)
|
|
||||||
assertTrue("parallel daemons start failed to complete in $PARALLEL_WAIT_TIMEOUT_S s, ${doneLatch.count} unfinished threads", succeeded)
|
assertTrue("parallel daemons start failed to complete in $PARALLEL_WAIT_TIMEOUT_S s, ${doneLatch.count} unfinished threads", succeeded)
|
||||||
|
|
||||||
Thread.sleep(100) // Wait for processes to finish and close log files
|
Thread.sleep(100) // Wait for processes to finish and close log files
|
||||||
|
|
||||||
val electionLogs = logFiles.map { it to it?.readLines()?.find { it.contains(LOG_PREFIX_ASSUMING_OTHER_DAEMONS_HAVE) } }
|
val electionLogs = (0..(PARALLEL_THREADS_TO_START - 1)).map {
|
||||||
|
val logContents = logFiles[it]?.readLines()
|
||||||
|
assertEquals("Compilation on thread $it failed:\n${outStreams[it]}\n\n------- daemon log: -------\n${logContents?.joinToString("\n")}\n-------", 0, resultCodes[it])
|
||||||
|
logContents?.find { it.contains(LOG_PREFIX_ASSUMING_OTHER_DAEMONS_HAVE) }
|
||||||
|
}
|
||||||
|
|
||||||
assertTrue("No daemon elected: \n${electionLogs.joinToString("\n")}",
|
assertTrue("No daemon elected: \n${electionLogs.joinToString("\n")}",
|
||||||
electionLogs.any { (_, electionLine) -> electionLine != null && (electionLine.contains("lower prio") || electionLine.contains("equal prio")) })
|
electionLogs.any { it != null && (it.contains("lower prio") || it.contains("equal prio")) })
|
||||||
|
|
||||||
electionLogs.forEach { (logFile, _) -> logFile?.delete() }
|
logFiles.forEach { it?.delete() }
|
||||||
|
|
||||||
(1..PARALLEL_THREADS_TO_START).forEach {
|
|
||||||
assertEquals("Compilation on thread $it failed:\n${outStreams[it - 1]}", 0, resultCodes[it - 1])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testDaemonConnectionProblems() {
|
fun testDaemonConnectionProblems() {
|
||||||
|
|||||||
Reference in New Issue
Block a user