[K/N][tests] Remove now unused LocalTestNameExtractor
This commit is contained in:
committed by
Space Team
parent
234eb29bab
commit
8d696dae03
+2
-112
@@ -7,92 +7,17 @@ package org.jetbrains.kotlin.konan.test.blackbox.support.runner
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.text.StringUtilRt.convertLineSeparators
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.kotlin.konan.target.Architecture
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.needSmallBinary
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.TestCaseId
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.runner.AbstractRunner.AbstractRun
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.runner.TestRunCheck.ExecutionTimeout
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.runner.TestRunCheck.ExitCode
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.runner.UnfilteredProcessOutput.Companion.launchReader
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.KotlinNativeTargets
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.OptimizationMode
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.configurables
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.util.TestOutputFilter
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly
|
||||
import java.io.*
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.time.*
|
||||
|
||||
internal abstract class AbstractLocalProcessRunner<R>(protected val checks: TestRunChecks) : AbstractRunner<R>() {
|
||||
protected abstract val visibleProcessName: String
|
||||
protected abstract val executable: TestExecutable
|
||||
protected abstract val programArgs: List<String>
|
||||
protected abstract val outputFilter: TestOutputFilter
|
||||
|
||||
protected open fun customizeProcess(process: Process) = Unit
|
||||
|
||||
@OptIn(ExperimentalTime::class)
|
||||
final override fun buildRun() = AbstractRun {
|
||||
runBlocking(Dispatchers.IO) {
|
||||
val unfilteredOutput = UnfilteredProcessOutput()
|
||||
val unfilteredOutputReader: Job
|
||||
|
||||
val executionTimeout: Duration = checks.executionTimeoutCheck.timeout
|
||||
|
||||
val process: Process
|
||||
val hasFinishedOnTime: Boolean
|
||||
|
||||
// Don't ignore IO errors that happen just after the process is started.
|
||||
val ignoreIOErrorsInProcessOutput = AtomicBoolean(false)
|
||||
|
||||
val duration = measureTime {
|
||||
process = ProcessBuilder(programArgs).directory(executable.executable.executableFile.parentFile).start()
|
||||
customizeProcess(process)
|
||||
|
||||
unfilteredOutputReader = launchReader(
|
||||
unfilteredOutput,
|
||||
processStdout = process.inputStream,
|
||||
processStderr = process.errorStream,
|
||||
ignoreIOErrorsInProcessOutput
|
||||
)
|
||||
|
||||
hasFinishedOnTime = process.waitFor(
|
||||
executionTimeout.toLong(DurationUnit.MILLISECONDS),
|
||||
DurationUnit.MILLISECONDS.toTimeUnit()
|
||||
)
|
||||
}
|
||||
|
||||
val exitCode: Int? = if (hasFinishedOnTime) {
|
||||
unfilteredOutputReader.join() // Wait until all output streams are drained.
|
||||
process.exitValue()
|
||||
} else {
|
||||
try { // It could happen just by an accident that the process has exited by itself.
|
||||
val exitCode = process.exitValue() // Fetch exit code.
|
||||
unfilteredOutputReader.join() // Wait until all streams are drained.
|
||||
exitCode
|
||||
} catch (_: IllegalThreadStateException) { // Still not destroyed.
|
||||
ignoreIOErrorsInProcessOutput.set(true) // Ignore IO errors caused by the closed streams of the killed process.
|
||||
unfilteredOutputReader.cancel() // Cancel it. No need to read streams, actually.
|
||||
process.destroyForcibly() // kill -9
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
RunResult(
|
||||
testExecutable = executable,
|
||||
exitCode = exitCode,
|
||||
timeout = executionTimeout,
|
||||
duration = duration,
|
||||
hasFinishedOnTime = hasFinishedOnTime,
|
||||
processOutput = unfilteredOutput.toProcessOutput(outputFilter)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
abstract override fun buildResultHandler(runResult: RunResult): LocalResultHandler<R> // ?? Narrow returned type.
|
||||
}
|
||||
import java.io.File
|
||||
|
||||
private fun RunResult.processOutputAsString(output: TestRunCheck.Output) = when (output) {
|
||||
TestRunCheck.Output.STDOUT -> processOutput.stdOut.filteredOutput
|
||||
@@ -234,43 +159,8 @@ internal abstract class LocalResultHandler<R>(
|
||||
protected abstract fun doHandle(): R
|
||||
}
|
||||
|
||||
private class UnfilteredProcessOutput {
|
||||
private val stdOut = ByteArrayOutputStream()
|
||||
private val stdErr = ByteArrayOutputStream()
|
||||
|
||||
fun toProcessOutput(outputFilter: TestOutputFilter): ProcessOutput = ProcessOutput(
|
||||
stdOut = outputFilter.filter(stdOut.toString(Charsets.UTF_8.name())),
|
||||
stdErr = stdErr.toString(Charsets.UTF_8.name())
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun CoroutineScope.launchReader(
|
||||
unfilteredOutput: UnfilteredProcessOutput,
|
||||
processStdout: InputStream,
|
||||
processStderr: InputStream,
|
||||
ignoreIOErrors: AtomicBoolean
|
||||
): Job = launch {
|
||||
fun InputStream.safeCopyTo(output: OutputStream) {
|
||||
try {
|
||||
copyTo(output)
|
||||
} catch (e: IOException) {
|
||||
if (ignoreIOErrors.get()) { // Note: Just checking `!process.isAlive` seems to be not reliable in concurrent environment.
|
||||
// The IO exception might be caused by the closed stream due to process death. Just ignore.
|
||||
} else {
|
||||
// The process is still alive. Some I/O error happened, which is better to rethrow.
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
launch { processStdout.safeCopyTo(unfilteredOutput.stdOut) }
|
||||
launch { processStderr.safeCopyTo(unfilteredOutput.stdErr) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shameless borrowing `val KonanTarget.abiInfo` from module `:kotlin-native:backend.native`, which cannot be imported here for now.
|
||||
val KonanTarget.abiInfoString: String
|
||||
private val KonanTarget.abiInfoString: String
|
||||
get() = when {
|
||||
this == KonanTarget.MINGW_X64 -> "WINDOWSX64"
|
||||
!family.isAppleFamily && architecture == Architecture.ARM64 -> "AAPCS"
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.test.blackbox.support.runner
|
||||
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.LoggedData
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.TestName
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.util.GTestListing
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.util.TestOutputFilter
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||
|
||||
internal class LocalTestNameExtractor(
|
||||
override val executable: TestExecutable,
|
||||
checks: TestRunChecks
|
||||
) : AbstractLocalProcessRunner<Collection<TestName>>(checks) {
|
||||
override val visibleProcessName get() = "Test name extractor"
|
||||
override val programArgs = listOf(executable.executable.executableFile.path, "--ktest_list_tests")
|
||||
override val outputFilter get() = TestOutputFilter.NO_FILTERING
|
||||
|
||||
override fun getLoggedParameters() = LoggedData.TestRunParameters(
|
||||
compilationToolCall = executable.loggedCompilationToolCall,
|
||||
testCaseId = null,
|
||||
runArgs = programArgs,
|
||||
runParameters = null
|
||||
)
|
||||
|
||||
override fun buildResultHandler(runResult: RunResult) =
|
||||
TestNameResultHandler(runResult, visibleProcessName, checks, getLoggedParameters())
|
||||
|
||||
override fun handleUnexpectedFailure(t: Throwable) = fail {
|
||||
LoggedData.TestRunUnexpectedFailure(getLoggedParameters(), t)
|
||||
.withErrorMessage("Test name extraction failed with unexpected exception.")
|
||||
}
|
||||
}
|
||||
|
||||
internal class TestNameResultHandler(
|
||||
runResult: RunResult,
|
||||
visibleProcessName: String,
|
||||
checks: TestRunChecks,
|
||||
private val loggedParameters: LoggedData.TestRunParameters
|
||||
) : LocalResultHandler<Collection<TestName>>(runResult, visibleProcessName, checks, null, false) {
|
||||
override fun getLoggedRun() = LoggedData.TestRun(loggedParameters, runResult)
|
||||
override fun doHandle() = GTestListing.parse(runResult.processOutput.stdOut.filteredOutput)
|
||||
}
|
||||
-10
@@ -35,16 +35,6 @@ internal object TestRunners {
|
||||
|
||||
private val executorCache: ConcurrentHashMap<KonanTarget, Executor> = ConcurrentHashMap()
|
||||
|
||||
// Currently, only local test name extractor is supported.
|
||||
fun extractTestNames(executable: TestExecutable, settings: Settings): Collection<TestName> = with(settings) {
|
||||
with(get<KotlinNativeTargets>()) {
|
||||
if (testTarget == hostTarget)
|
||||
LocalTestNameExtractor(executable, TestRunChecks.Default(get<Timeouts>().executionTimeout)).run()
|
||||
else
|
||||
runningOnUnsupportedTarget()
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinNativeTargets.runningOnUnsupportedTarget(): Nothing = fail {
|
||||
"Running tests for $testTarget on $hostTarget is not supported yet."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user