[Native][tests] Extract GTest report verification logic
This commit is contained in:
+9
-41
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.runner
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtilRt.convertLineSeparators
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.util.parseGTestReport
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||
import kotlin.time.Duration
|
||||
|
||||
@@ -55,46 +56,22 @@ internal class LocalTestRunner(
|
||||
}
|
||||
|
||||
private fun verifyTestWithGTestRunner() {
|
||||
val testStatuses = hashMapOf<TestStatus, MutableSet<TestName>>()
|
||||
val cleanStdOut = StringBuilder()
|
||||
val testReport = parseGTestReport(runResult.output.stdOut)
|
||||
|
||||
var expectStatusLine = false
|
||||
runResult.output.stdOut.lines().forEach { line ->
|
||||
when {
|
||||
expectStatusLine -> {
|
||||
val matcher = GTEST_STATUS_LINE_REGEX.matchEntire(line)
|
||||
if (matcher != null) {
|
||||
// Read the line with test status.
|
||||
val testStatus = matcher.groupValues[1]
|
||||
val testName = matcher.groupValues[2]
|
||||
testStatuses.getOrPut(testStatus) { hashSetOf() } += testName
|
||||
expectStatusLine = false
|
||||
} else {
|
||||
// If current line is not a status line then it could be only the line with the process' output.
|
||||
cleanStdOut.appendLine(line)
|
||||
}
|
||||
}
|
||||
line.startsWith(GTEST_RUN_LINE_PREFIX) -> {
|
||||
expectStatusLine = true // Next line contains either test status.
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
verifyExpectation(!testReport.isEmpty()) { "No tests have been executed." }
|
||||
|
||||
verifyExpectation(testStatuses.isNotEmpty()) { "No tests have been executed." }
|
||||
|
||||
val passedTests = testStatuses[GTEST_STATUS_OK]?.size ?: 0
|
||||
verifyExpectation(passedTests > 0) { "No passed tests." }
|
||||
val passedTests = testReport.getPassedTests()
|
||||
verifyExpectation(passedTests.isNotEmpty()) { "No passed tests." }
|
||||
|
||||
testRun.runParameters.get<TestRunParameter.WithFilter> {
|
||||
val excessiveTests = testStatuses.getValue(GTEST_STATUS_OK).filter { testName -> !testMatches(testName) }
|
||||
val excessiveTests = passedTests.filter { testName -> !testMatches(testName) }
|
||||
verifyExpectation(excessiveTests.isEmpty()) { "Excessive tests have been executed: $excessiveTests." }
|
||||
}
|
||||
|
||||
val failedTests = (testStatuses - GTEST_STATUS_OK).values.sumOf { it.size }
|
||||
verifyExpectation(0, failedTests) { "There are failed tests." }
|
||||
val failedTests = testReport.getFailedTests().size
|
||||
verifyExpectation(0, failedTests) { "There are $failedTests failed tests." }
|
||||
|
||||
verifyOutputData(mergedOutput = cleanStdOut.toString() + runResult.output.stdErr)
|
||||
verifyOutputData(mergedOutput = testReport.cleanStdOut + runResult.output.stdErr)
|
||||
}
|
||||
|
||||
private fun verifyPlainTest() = verifyOutputData(mergedOutput = runResult.output.stdOut + runResult.output.stdErr)
|
||||
@@ -107,13 +84,4 @@ internal class LocalTestRunner(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val GTEST_RUN_LINE_PREFIX = "[ RUN ]"
|
||||
private val GTEST_STATUS_LINE_REGEX = Regex("^\\[\\s+([A-Z]+)\\s+]\\s+(\\S+)\\s+.*")
|
||||
private const val GTEST_STATUS_OK = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
private typealias TestStatus = String
|
||||
private typealias TestName = String
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.konan.blackboxtest.support.util
|
||||
|
||||
internal typealias TestName = String
|
||||
internal typealias TestStatus = String
|
||||
|
||||
internal class GTestReport(
|
||||
private val testStatuses: Map<TestStatus, Collection<TestName>>,
|
||||
val cleanStdOut: String
|
||||
) {
|
||||
fun getPassedTests(): Collection<TestName> = testStatuses[STATUS_OK].orEmpty()
|
||||
fun getFailedTests(): Collection<TestName> = (testStatuses - STATUS_OK).flatMap { it.value }
|
||||
|
||||
fun isEmpty(): Boolean = testStatuses.isEmpty()
|
||||
|
||||
companion object {
|
||||
private const val STATUS_OK = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses GTest reports like this:
|
||||
*
|
||||
* [==========] Running 2 tests from 1 test cases.
|
||||
* [----------] Global test environment set-up.
|
||||
* [----------] 2 tests from sample.test.SampleTestKt
|
||||
* [ RUN ] sample.test.SampleTestKt.one
|
||||
* [ OK ] sample.test.SampleTestKt.one (0 ms)
|
||||
* [ RUN ] sample.test.SampleTestKt.two
|
||||
* [ OK ] sample.test.SampleTestKt.two (0 ms)
|
||||
* [----------] 2 tests from sample.test.SampleTestKt (0 ms total)
|
||||
*
|
||||
* [----------] Global test environment tear-down
|
||||
* [==========] 2 tests from 1 test cases ran. (0 ms total)
|
||||
* [ PASSED ] 2 tests.
|
||||
*/
|
||||
internal fun parseGTestReport(stdOut: String): GTestReport {
|
||||
val testStatuses = hashMapOf<TestStatus, MutableSet<TestName>>()
|
||||
val cleanStdOut = StringBuilder()
|
||||
|
||||
var expectStatusLine = false
|
||||
stdOut.lineSequence().forEach { line ->
|
||||
when {
|
||||
expectStatusLine -> {
|
||||
val matcher = STATUS_LINE_REGEX.matchEntire(line)
|
||||
if (matcher != null) {
|
||||
// Read the line with test status.
|
||||
val testStatus = matcher.groupValues[1]
|
||||
val testName = matcher.groupValues[2]
|
||||
testStatuses.getOrPut(testStatus) { hashSetOf() } += testName
|
||||
expectStatusLine = false
|
||||
} else {
|
||||
// If current line is not a status line then it could be only the line with the process' output.
|
||||
cleanStdOut.appendLine(line)
|
||||
}
|
||||
}
|
||||
line.matches(RUN_LINE_REGEX) -> {
|
||||
expectStatusLine = true // Next line contains either test status.
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
return GTestReport(testStatuses, cleanStdOut.toString())
|
||||
}
|
||||
|
||||
private val RUN_LINE_REGEX = Regex("""^\[\s+RUN\s+]\s+.*""")
|
||||
private val STATUS_LINE_REGEX = Regex("""^\[\s+([A-Z]+)\s+]\s+(\S+)\s+.*""")
|
||||
Reference in New Issue
Block a user