Gradle, tests: Improve tests for running simulator unit-tests
This commit is contained in:
+88
-7
@@ -4,6 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
|
import org.jdom.input.SAXBuilder
|
||||||
import org.jetbrains.kotlin.gradle.internals.*
|
import org.jetbrains.kotlin.gradle.internals.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ProjectLocalConfigurations
|
import org.jetbrains.kotlin.gradle.plugin.ProjectLocalConfigurations
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmWithJavaTargetPreset
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmWithJavaTargetPreset
|
||||||
@@ -20,6 +22,7 @@ import org.jetbrains.kotlin.konan.target.HostManager
|
|||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import java.io.File
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@@ -1277,9 +1280,20 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getBootedSimulators(workingDirectory: File): Set<String>? =
|
||||||
|
if (HostManager.hostIsMac) {
|
||||||
|
val simulators = runProcess(listOf("xcrun", "simctl", "list"), workingDirectory, System.getenv()).also {
|
||||||
|
assertTrue(it.isSuccessful, "xcrun exection failed")
|
||||||
|
}.output
|
||||||
|
|
||||||
|
simulators.split('\n').filter { it.contains("(Booted)") }.map { it.trim() }.toSet()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNativeTests() = with(Project("new-mpp-native-tests", gradleVersion)) {
|
fun testNativeTests() = with(Project("new-mpp-native-tests", gradleVersion, minLogLevel = LogLevel.INFO)) {
|
||||||
val testTasks = listOf("macos64Test", "linux64Test", "mingw64Test", "iosTest")
|
val testTasks = listOf("macos64Test", "linux64Test", "mingw64Test", "iosTest")
|
||||||
val hostTestTask = "${nativeHostTargetName}Test"
|
val hostTestTask = "${nativeHostTargetName}Test"
|
||||||
|
|
||||||
@@ -1288,6 +1302,8 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
val defaultOutputFile = "build/bin/$nativeHostTargetName/debugTest/test.$suffix"
|
val defaultOutputFile = "build/bin/$nativeHostTargetName/debugTest/test.$suffix"
|
||||||
val anotherOutputFile = "build/bin/$nativeHostTargetName/anotherDebugTest/another.$suffix"
|
val anotherOutputFile = "build/bin/$nativeHostTargetName/anotherDebugTest/another.$suffix"
|
||||||
|
|
||||||
|
val hostIsMac = HostManager.hostIsMac
|
||||||
|
|
||||||
build("tasks") {
|
build("tasks") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
testTasks.forEach {
|
testTasks.forEach {
|
||||||
@@ -1296,6 +1312,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform all following checks in a single test to avoid running the K/N compiler several times.
|
||||||
// Check that tests are not built during the ":assemble" execution
|
// Check that tests are not built during the ":assemble" execution
|
||||||
build("assemble") {
|
build("assemble") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
@@ -1303,27 +1320,91 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
assertNoSuchFile(anotherOutputFile)
|
assertNoSuchFile(anotherOutputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val testsToExecute = mutableListOf(":$hostTestTask")
|
||||||
|
if (hostIsMac) {
|
||||||
|
testsToExecute.add(":iosTest")
|
||||||
|
}
|
||||||
|
val testsToSkip = testTasks.map { ":$it" } - testsToExecute
|
||||||
|
|
||||||
|
// Store currently booted simulators to check that they don't leak (MacOS only).
|
||||||
|
val bootedSimulatorsBefore = getBootedSimulators(projectDir)
|
||||||
|
|
||||||
|
// Check the case when all tests pass.
|
||||||
build("check") {
|
build("check") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
|
|
||||||
val testsToExecute = mutableListOf(":$hostTestTask")
|
|
||||||
if (HostManager.hostIsMac) {
|
|
||||||
testsToExecute.add(":iosTest")
|
|
||||||
}
|
|
||||||
val testsToSkip = testTasks.map { ":$it" } - testsToExecute
|
|
||||||
|
|
||||||
assertTasksExecuted(*testsToExecute.toTypedArray())
|
assertTasksExecuted(*testsToExecute.toTypedArray())
|
||||||
assertTasksSkipped(*testsToSkip.toTypedArray())
|
assertTasksSkipped(*testsToSkip.toTypedArray())
|
||||||
|
|
||||||
|
assertContainsRegex("org\\.foo\\.test\\.TestKt\\.fooTest\\s+PASSED".toRegex())
|
||||||
|
assertContainsRegex("org\\.foo\\.test\\.TestKt\\.barTest\\s+PASSED".toRegex())
|
||||||
|
|
||||||
assertFileExists(defaultOutputFile)
|
assertFileExists(defaultOutputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check simulator process leaking.
|
||||||
|
val bootedSimulatorsAfter = getBootedSimulators(projectDir)
|
||||||
|
assertEquals(bootedSimulatorsBefore, bootedSimulatorsAfter)
|
||||||
|
|
||||||
|
// Check the case with failed tests.
|
||||||
|
projectDir.resolve("src/commonTest/kotlin/test.kt").appendText(
|
||||||
|
"""
|
||||||
|
@Test
|
||||||
|
fun fail() {
|
||||||
|
error("FAILURE!")
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
build("check") {
|
||||||
|
assertFailed()
|
||||||
|
|
||||||
|
assertTasksFailed(":allTests")
|
||||||
|
// In the aggregation report mode platform-specific tasks
|
||||||
|
// are executed successfully even if there are failing tests.
|
||||||
|
assertTasksExecuted(*testsToExecute.toTypedArray())
|
||||||
|
assertTasksSkipped(*testsToSkip.toTypedArray())
|
||||||
|
|
||||||
|
assertContainsRegex("org\\.foo\\.test\\.TestKt\\.fail\\s+FAILED".toRegex())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that individual test reports are created correctly.
|
||||||
|
build("check", "-Pkotlin.tests.individualTaskReports=true", "--continue") {
|
||||||
|
assertFailed()
|
||||||
|
|
||||||
|
// In the individual report mode platform-specific tasks
|
||||||
|
// fail if there are failing tests.
|
||||||
|
assertTasksFailed(*testsToExecute.toTypedArray())
|
||||||
|
assertTasksSkipped(*testsToSkip.toTypedArray())
|
||||||
|
|
||||||
|
|
||||||
|
fun assertStacktrace(taskName: String) {
|
||||||
|
val testReport = projectDir.resolve("build/test-results/$taskName/TEST-org.foo.test.TestKt.xml")
|
||||||
|
val stacktrace = SAXBuilder().build(testReport).rootElement
|
||||||
|
.getChildren("testcase")
|
||||||
|
.single { it.getAttribute("name").value == "fail" }
|
||||||
|
.getChild("failure")
|
||||||
|
.text
|
||||||
|
assertTrue(stacktrace.contains("""at org\.foo\.test\.fail\(.*test\.kt:24\)""".toRegex()))
|
||||||
|
}
|
||||||
|
|
||||||
assertTestResults("testProject/new-mpp-native-tests/TEST-TestKt.xml", hostTestTask)
|
assertTestResults("testProject/new-mpp-native-tests/TEST-TestKt.xml", hostTestTask)
|
||||||
|
// K/N doesn't report line numbers correctly on Linux (see KT-35408).
|
||||||
|
// TODO: Uncomment when this is fixed.
|
||||||
|
//assertStacktrace(hostTestTask)
|
||||||
|
if (hostIsMac) {
|
||||||
|
assertTestResults("testProject/new-mpp-native-tests/TEST-TestKt.xml", "iosTest")
|
||||||
|
assertStacktrace("iosTest")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build("linkAnotherDebugTest${nativeHostTargetName}") {
|
build("linkAnotherDebugTest${nativeHostTargetName}") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
assertFileExists(anotherOutputFile)
|
assertFileExists(anotherOutputFile)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testNativeTestGetters() = with(Project("new-mpp-native-tests", gradleVersion)) {
|
||||||
// Check that test binaries can be accessed in a buildscript.
|
// Check that test binaries can be accessed in a buildscript.
|
||||||
build("checkNewGetters") {
|
build("checkNewGetters") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
|
|||||||
+4
-1
@@ -1,9 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<results>
|
<results>
|
||||||
<testsuite name="org.foo.test.TestKt" tests="2" skipped="0" failures="0" errors="0" timestamp="..." hostname="..." time="...">
|
<testsuite name="org.foo.test.TestKt" tests="3" skipped="0" failures="1" errors="0" timestamp="..." hostname="..." time="...">
|
||||||
<properties/>
|
<properties/>
|
||||||
<testcase name="fooTest" classname="org.foo.test.TestKt" time="..."/>
|
<testcase name="fooTest" classname="org.foo.test.TestKt" time="..."/>
|
||||||
<testcase name="barTest" classname="org.foo.test.TestKt" time="..."/>
|
<testcase name="barTest" classname="org.foo.test.TestKt" time="..."/>
|
||||||
|
<testcase name="fail" classname="org.foo.test.TestKt" time="...">
|
||||||
|
<failure message="..." type="kotlin.IllegalStateException">...</failure>
|
||||||
|
</testcase>
|
||||||
<system-out><![CDATA[Foo call
|
<system-out><![CDATA[Foo call
|
||||||
Bar call]]></system-out>
|
Bar call]]></system-out>
|
||||||
<system-err/>
|
<system-err/>
|
||||||
|
|||||||
+7
@@ -48,6 +48,13 @@ kotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that test events are correctly reported in CLI.
|
||||||
|
configure([macos64Test, linux64Test, mingw64Test, iosTest]){
|
||||||
|
testLogging {
|
||||||
|
events "passed", "skipped", "failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check that getting a test binary in an old way fails showing the corresponding warning
|
// Check that getting a test binary in an old way fails showing the corresponding warning
|
||||||
task checkOldGet {
|
task checkOldGet {
|
||||||
doLast {
|
doLast {
|
||||||
|
|||||||
-1
@@ -1,2 +1 @@
|
|||||||
kotlin.tests.individualTaskReports=true
|
|
||||||
kotlin.native.disableCompilerDaemon=true
|
kotlin.native.disableCompilerDaemon=true
|
||||||
Reference in New Issue
Block a user