Rewrite parallel daemon start test to make it tougher but more robust

This commit is contained in:
Ilya Chernikov
2017-02-28 16:44:56 +01:00
parent 4c6b9b695c
commit e3391175d9
@@ -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() {