[K/N][tests] Remove now unused LocalTestNameExtractor

This commit is contained in:
Alexander Shabalin
2024-01-26 15:05:01 +01:00
committed by Space Team
parent 234eb29bab
commit 8d696dae03
3 changed files with 2 additions and 168 deletions
@@ -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"
@@ -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)
}
@@ -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."
}