[Native][tests] Reorganize OUTPUT_DATA_FILE directive

Use it as one of [TestRunCheck]s.
This commit is contained in:
Dmitriy Dolovov
2022-04-07 16:33:03 +03:00
committed by Space
parent 996ff5085d
commit 24552a625c
12 changed files with 36 additions and 32 deletions
@@ -116,7 +116,6 @@ abstract class AbstractNativeKlibABITest : AbstractNativeSimpleTest() {
modules = setOf(module), modules = setOf(module),
freeCompilerArgs = compilerArgs, freeCompilerArgs = compilerArgs,
nominalPackageName = PackageName.EMPTY, nominalPackageName = PackageName.EMPTY,
expectedOutputDataFile = null,
checks = TestRunChecks.Default(testRunSettings.get<Timeouts>().executionTimeout), checks = TestRunChecks.Default(testRunSettings.get<Timeouts>().executionTimeout),
extras = DEFAULT_EXTRAS extras = DEFAULT_EXTRAS
).apply { ).apply {
@@ -112,7 +112,6 @@ class InfrastructureDumpedTestListingTest : AbstractNativeSimpleTest() {
modules = setOf(module), modules = setOf(module),
freeCompilerArgs = TestCompilerArgs.EMPTY, freeCompilerArgs = TestCompilerArgs.EMPTY,
nominalPackageName = PackageName.EMPTY, nominalPackageName = PackageName.EMPTY,
expectedOutputDataFile = null,
checks = TestRunChecks.Default(testRunSettings.get<Timeouts>().executionTimeout), checks = TestRunChecks.Default(testRunSettings.get<Timeouts>().executionTimeout),
extras = DEFAULT_EXTRAS extras = DEFAULT_EXTRAS
).apply { ).apply {
@@ -170,7 +170,6 @@ internal class TestCase(
val modules: Set<TestModule.Exclusive>, val modules: Set<TestModule.Exclusive>,
val freeCompilerArgs: TestCompilerArgs, val freeCompilerArgs: TestCompilerArgs,
val nominalPackageName: PackageName, val nominalPackageName: PackageName,
val expectedOutputDataFile: File?, // TODO: refactor to TestRunCheck
val checks: TestRunChecks, val checks: TestRunChecks,
val extras: Extras val extras: Extras
) { ) {
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.OUTPUT_DAT
import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.EXPECTED_TIMEOUT_FAILURE import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.EXPECTED_TIMEOUT_FAILURE
import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.TEST_RUNNER import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.TEST_RUNNER
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.OutputDataFile
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
import org.jetbrains.kotlin.test.directives.model.StringDirective import org.jetbrains.kotlin.test.directives.model.StringDirective
@@ -276,8 +277,8 @@ internal fun parseFreeCompilerArgs(registeredDirectives: RegisteredDirectives, l
return TestCompilerArgs(freeCompilerArgs) return TestCompilerArgs(freeCompilerArgs)
} }
internal fun parseOutputDataFile(baseDir: File, registeredDirectives: RegisteredDirectives, location: Location): File? = internal fun parseOutputDataFile(baseDir: File, registeredDirectives: RegisteredDirectives, location: Location): OutputDataFile? =
parseFileBasedDirective(baseDir, OUTPUT_DATA_FILE, registeredDirectives, location) parseFileBasedDirective(baseDir, OUTPUT_DATA_FILE, registeredDirectives, location)?.let(TestRunCheck::OutputDataFile)
internal fun parseInputDataFile(baseDir: File, registeredDirectives: RegisteredDirectives, location: Location): File? = internal fun parseInputDataFile(baseDir: File, registeredDirectives: RegisteredDirectives, location: Location): File? =
parseFileBasedDirective(baseDir, INPUT_DATA_FILE, registeredDirectives, location) parseFileBasedDirective(baseDir, INPUT_DATA_FILE, registeredDirectives, location)
@@ -553,7 +553,6 @@ private class ExtTestDataFile(
modules = modules, modules = modules,
freeCompilerArgs = assembleFreeCompilerArgs(), freeCompilerArgs = assembleFreeCompilerArgs(),
nominalPackageName = testDataFileSettings.nominalPackageName, nominalPackageName = testDataFileSettings.nominalPackageName,
expectedOutputDataFile = null,
checks = TestRunChecks.Default(timeouts.executionTimeout), checks = TestRunChecks.Default(timeouts.executionTimeout),
extras = WithTestRunnerExtras(runnerType = TestRunnerType.DEFAULT) extras = WithTestRunnerExtras(runnerType = TestRunnerType.DEFAULT)
) )
@@ -63,7 +63,6 @@ internal class PredefinedTestCaseGroupProvider(annotation: PredefinedTestCases)
freeCompilerArgs = predefinedTestCase.freeCompilerArgs freeCompilerArgs = predefinedTestCase.freeCompilerArgs
.parseCompilerArgs(settings) { "Failed to parse free compiler arguments for test case $testCaseId" }, .parseCompilerArgs(settings) { "Failed to parse free compiler arguments for test case $testCaseId" },
nominalPackageName = PackageName(testCaseId.uniqueName), nominalPackageName = PackageName(testCaseId.uniqueName),
expectedOutputDataFile = null,
checks = TestRunChecks.Default(settings.get<Timeouts>().executionTimeout), checks = TestRunChecks.Default(settings.get<Timeouts>().executionTimeout),
extras = WithTestRunnerExtras( extras = WithTestRunnerExtras(
runnerType = predefinedTestCase.runnerType, runnerType = predefinedTestCase.runnerType,
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.group
import org.jetbrains.kotlin.konan.blackboxtest.support.* import org.jetbrains.kotlin.konan.blackboxtest.support.*
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.NoTestRunnerExtras import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.NoTestRunnerExtras
import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.WithTestRunnerExtras import org.jetbrains.kotlin.konan.blackboxtest.support.TestCase.WithTestRunnerExtras
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.ExecutionTimeout import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.*
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.ExitCode
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.GeneratedSources import org.jetbrains.kotlin.konan.blackboxtest.support.settings.GeneratedSources
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings
@@ -183,7 +182,6 @@ internal class StandardTestCaseGroupProvider : TestCaseGroupProvider {
val registeredDirectives = directivesParser.build() val registeredDirectives = directivesParser.build()
val freeCompilerArgs = parseFreeCompilerArgs(registeredDirectives, location) val freeCompilerArgs = parseFreeCompilerArgs(registeredDirectives, location)
val expectedOutputDataFile = parseOutputDataFile(baseDir = testDataFile.parentFile, registeredDirectives, location)
val testKind = parseTestKind(registeredDirectives, location) val testKind = parseTestKind(registeredDirectives, location)
val expectedTimeoutFailure = parseExpectedTimeoutFailure(registeredDirectives) val expectedTimeoutFailure = parseExpectedTimeoutFailure(registeredDirectives)
@@ -198,10 +196,10 @@ internal class StandardTestCaseGroupProvider : TestCaseGroupProvider {
modules = testModules.values.toSet(), modules = testModules.values.toSet(),
freeCompilerArgs = freeCompilerArgs, freeCompilerArgs = freeCompilerArgs,
nominalPackageName = nominalPackageName, nominalPackageName = nominalPackageName,
expectedOutputDataFile = expectedOutputDataFile,
checks = TestRunChecks( checks = TestRunChecks(
computeExecutionTimeoutCheck(settings, expectedTimeoutFailure), computeExecutionTimeoutCheck(settings, expectedTimeoutFailure),
computeExitCodeCheck(testKind, registeredDirectives, location) computeExitCodeCheck(testKind, registeredDirectives, location),
computeOutputDataFileCheck(testDataFile, registeredDirectives, location)
), ),
extras = if (testKind == TestKind.STANDALONE_NO_TR) extras = if (testKind == TestKind.STANDALONE_NO_TR)
NoTestRunnerExtras( NoTestRunnerExtras(
@@ -254,5 +252,11 @@ internal class StandardTestCaseGroupProvider : TestCaseGroupProvider {
parseExpectedExitCode(registeredDirectives, location) parseExpectedExitCode(registeredDirectives, location)
else else
ExitCode.Expected(0) ExitCode.Expected(0)
private fun computeOutputDataFileCheck(
testDataFile: File,
registeredDirectives: RegisteredDirectives,
location: Location
): OutputDataFile? = parseOutputDataFile(baseDir = testDataFile.parentFile, registeredDirectives, location)
} }
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.konan.blackboxtest.support.runner package org.jetbrains.kotlin.konan.blackboxtest.support.runner
import com.intellij.openapi.util.text.StringUtilRt.convertLineSeparators
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.AbstractRunner.AbstractRun import org.jetbrains.kotlin.konan.blackboxtest.support.runner.AbstractRunner.AbstractRun
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.ExecutionTimeout import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.ExecutionTimeout
@@ -94,6 +95,16 @@ internal abstract class AbstractLocalProcessRunner<R>(private val checks: TestRu
} }
} }
} }
is TestRunCheck.OutputDataFile -> {
val expectedOutput = check.file.readText()
val actualFilteredOutput = runResult.processOutput.stdOut.filteredOutput + runResult.processOutput.stdErr
// Don't use verifyExpectation(expected, actual) to avoid exposing potentially large test output in exception message
// and blowing up test logs.
verifyExpectation(convertLineSeparators(expectedOutput) == convertLineSeparators(actualFilteredOutput)) {
"Tested process output mismatch. See \"TEST STDOUT\" and \"EXPECTED OUTPUT DATA FILE\" below."
}
}
} }
} }
@@ -26,7 +26,7 @@ internal open class BaseTestRunProvider {
) )
private fun getTestRunParameters(testCase: TestCase, testName: TestName?): List<TestRunParameter> = buildList { private fun getTestRunParameters(testCase: TestCase, testName: TestName?): List<TestRunParameter> = buildList {
addIfNotNull(testCase.expectedOutputDataFile?.let(TestRunParameter::WithExpectedOutputData)) addIfNotNull(testCase.checks.outputDataFile?.file?.let(TestRunParameter::WithExpectedOutputData))
when (testCase.kind) { when (testCase.kind) {
TestKind.STANDALONE_NO_TR -> { TestKind.STANDALONE_NO_TR -> {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.konan.blackboxtest.support.runner 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.*
import org.jetbrains.kotlin.konan.blackboxtest.support.util.TCTestOutputFilter import org.jetbrains.kotlin.konan.blackboxtest.support.util.TCTestOutputFilter
import org.jetbrains.kotlin.konan.blackboxtest.support.util.TestOutputFilter import org.jetbrains.kotlin.konan.blackboxtest.support.util.TestOutputFilter
@@ -51,9 +50,6 @@ internal class LocalTestRunner(private val testRun: TestRun) : AbstractLocalProc
override fun doHandle() { override fun doHandle() {
verifyTestReport(runResult.processOutput.stdOut.testReport) verifyTestReport(runResult.processOutput.stdOut.testReport)
val mergedOutput = runResult.processOutput.stdOut.filteredOutput + runResult.processOutput.stdErr
verifyNonTestOutput(mergedOutput)
} }
private fun verifyTestReport(testReport: TestReport?) { private fun verifyTestReport(testReport: TestReport?) {
@@ -84,15 +80,5 @@ internal class LocalTestRunner(private val testRun: TestRun) : AbstractLocalProc
tests.forEach { appendLine().append(" - ").append(it) } tests.forEach { appendLine().append(" - ").append(it) }
} }
} }
private fun verifyNonTestOutput(nonTestOutput: String) {
testRun.runParameters.get<TestRunParameter.WithExpectedOutputData> {
// Don't use verifyExpectation(expected, actual) to avoid exposing potentially large test output in exception message
// and blowing up test logs.
verifyExpectation(convertLineSeparators(expectedOutputDataFile.readText()) == convertLineSeparators(nonTestOutput)) {
"Tested process output mismatch. See \"TEST STDOUT\" and \"EXPECTED OUTPUT DATA FILE\" below."
}
}
}
} }
} }
@@ -96,6 +96,7 @@ internal sealed interface TestRunParameter {
override fun applyTo(programArgs: MutableList<String>) = Unit override fun applyTo(programArgs: MutableList<String>) = Unit
} }
// Currently, used only for logging the data.
class WithExpectedOutputData(val expectedOutputDataFile: File) : TestRunParameter { class WithExpectedOutputData(val expectedOutputDataFile: File) : TestRunParameter {
override fun applyTo(programArgs: MutableList<String>) = Unit override fun applyTo(programArgs: MutableList<String>) = Unit
} }
@@ -5,8 +5,9 @@
package org.jetbrains.kotlin.konan.blackboxtest.support.runner package org.jetbrains.kotlin.konan.blackboxtest.support.runner
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.ExecutionTimeout import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.*
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunCheck.ExitCode import org.jetbrains.kotlin.utils.yieldIfNotNull
import java.io.File
import kotlin.time.Duration import kotlin.time.Duration
internal sealed interface TestRunCheck { internal sealed interface TestRunCheck {
@@ -19,24 +20,29 @@ internal sealed interface TestRunCheck {
object AnyNonZero : ExitCode() object AnyNonZero : ExitCode()
class Expected(val expectedExitCode: Int) : ExitCode() class Expected(val expectedExitCode: Int) : ExitCode()
} }
class OutputDataFile(val file: File) : TestRunCheck
} }
internal class TestRunChecks( internal class TestRunChecks(
val executionTimeoutCheck: ExecutionTimeout, val executionTimeoutCheck: ExecutionTimeout,
private val exitCodeCheck: ExitCode private val exitCodeCheck: ExitCode,
val outputDataFile: OutputDataFile?
) : Iterable<TestRunCheck> { ) : Iterable<TestRunCheck> {
override fun iterator() = iterator { override fun iterator() = iterator {
yield(executionTimeoutCheck) yield(executionTimeoutCheck)
yield(exitCodeCheck) yield(exitCodeCheck)
yieldIfNotNull(outputDataFile)
} }
companion object { companion object {
// The most frequently used case: // The most frequently used case:
@Suppress("TestFunctionName") @Suppress("TestFunctionName")
fun Default(timeout: Duration) = TestRunChecks( fun Default(timeout: Duration) = TestRunChecks(
ExecutionTimeout.ShouldNotExceed(timeout), executionTimeoutCheck = ExecutionTimeout.ShouldNotExceed(timeout),
ExitCode.Expected(0) exitCodeCheck = ExitCode.Expected(0),
outputDataFile = null
) )
} }
} }