[K/N][tests] Support running the compiler without altering its output

This commit is contained in:
Svyatoslav Scherbina
2023-02-09 18:16:18 +01:00
committed by Space Team
parent e0c7d72cee
commit ac95ca12cf
5 changed files with 69 additions and 5 deletions
@@ -53,7 +53,10 @@ internal enum class ClassLevelProperty(shortName: String) {
GC_SCHEDULER("gcScheduler"),
CACHE_MODE("cacheMode"),
EXECUTION_TIMEOUT("executionTimeout"),
SANITIZER("sanitizer");
SANITIZER("sanitizer"),
COMPILER_OUTPUT_INTERCEPTOR("compilerOutputInterceptor"),
;
internal val propertyName = fullPropertyName(shortName)
@@ -200,6 +200,8 @@ private object NativeTestSupport {
// Parse annotations of current class, since there's no way to put annotations to upper-level enclosing class
output += computePipelineType(testClass.get())
output += computeCompilerOutputInterceptor(enforcedProperties)
return nativeTargets
}
@@ -222,6 +224,13 @@ private object NativeTestSupport {
private fun computeSanitizer(enforcedProperties: EnforcedProperties): Sanitizer =
ClassLevelProperty.SANITIZER.readValue(enforcedProperties, Sanitizer.values(), default = Sanitizer.NONE)
private fun computeCompilerOutputInterceptor(enforcedProperties: EnforcedProperties): CompilerOutputInterceptor =
ClassLevelProperty.COMPILER_OUTPUT_INTERCEPTOR.readValue(
enforcedProperties,
CompilerOutputInterceptor.values(),
default = CompilerOutputInterceptor.DEFAULT
)
private fun computeGCType(enforcedProperties: EnforcedProperties): GCType =
ClassLevelProperty.GC_TYPE.readValue(enforcedProperties, GCType.values(), default = GCType.UNSPECIFIED)
@@ -74,6 +74,39 @@ internal fun callCompiler(compilerArgs: Array<String>, kotlinNativeClassLoader:
return CompilationToolCallResult(exitCode, compilerOutput, messageCollector.hasErrors(), duration)
}
internal fun callCompilerWithoutOutputInterceptor(
compilerArgs: Array<String>,
kotlinNativeClassLoader: ClassLoader
): CompilationToolCallResult {
val exitCode: ExitCode
val compilerOutput: String
@OptIn(ExperimentalTime::class)
val duration = measureTime {
val compilerClass = Class.forName("org.jetbrains.kotlin.cli.bc.K2Native", true, kotlinNativeClassLoader)
val entryPoint = compilerClass.getMethod(
"exec",
PrintStream::class.java,
Array<String>::class.java
)
// TODO: we better use the same entry point as the actual compiler.
val outputStream = ByteArrayOutputStream()
exitCode = PrintStream(outputStream).use { printStream ->
val result = entryPoint.invoke(compilerClass.getDeclaredConstructor().newInstance(), printStream, compilerArgs)
ExitCode.valueOf(result.toString())
}
compilerOutput = outputStream.toString(Charsets.UTF_8.name())
}
val toolOutputHasErrors = exitCode != ExitCode.OK // An approximation, good enough.
// Alternatively, we can look for 'error:' and 'exception:' in the output.
return CompilationToolCallResult(exitCode, compilerOutput, toolOutputHasErrors = toolOutputHasErrors, duration)
}
@OptIn(ExperimentalTime::class)
internal fun invokeCInterop(
kotlinNativeClassLoader: ClassLoader,
@@ -31,6 +31,7 @@ internal abstract class BasicCompilation<A : TestCompilationArtifact>(
protected val home: KotlinNativeHome,
private val classLoader: KotlinNativeClassLoader,
private val optimizationMode: OptimizationMode,
private val compilerOutputInterceptor: CompilerOutputInterceptor,
protected val freeCompilerArgs: TestCompilerArgs,
protected val dependencies: CategorizedDependencies,
protected val expectedArtifact: A
@@ -82,10 +83,18 @@ internal abstract class BasicCompilation<A : TestCompilationArtifact>(
val loggedCompilerParameters = LoggedData.CompilerParameters(home, compilerArgs, sourceModules)
val (loggedCompilerCall: LoggedData, result: TestCompilationResult.ImmediateResult<out A>) = try {
val (exitCode, compilerOutput, compilerOutputHasErrors, duration) = callCompiler(
compilerArgs = compilerArgs,
kotlinNativeClassLoader = classLoader.classLoader
)
val compilerToolCallResult = when (compilerOutputInterceptor) {
CompilerOutputInterceptor.DEFAULT -> callCompiler(
compilerArgs = compilerArgs,
kotlinNativeClassLoader = classLoader.classLoader
)
CompilerOutputInterceptor.NONE -> callCompilerWithoutOutputInterceptor(
compilerArgs = compilerArgs,
kotlinNativeClassLoader = classLoader.classLoader
)
}
val (exitCode, compilerOutput, compilerOutputHasErrors, duration) = compilerToolCallResult
val loggedCompilationToolCall =
LoggedData.CompilationToolCall("COMPILER", loggedCompilerParameters, exitCode, compilerOutput, compilerOutputHasErrors, duration)
@@ -116,6 +125,7 @@ internal abstract class SourceBasedCompilation<A : TestCompilationArtifact>(
home: KotlinNativeHome,
classLoader: KotlinNativeClassLoader,
optimizationMode: OptimizationMode,
compilerOutputInterceptor: CompilerOutputInterceptor,
private val memoryModel: MemoryModel,
private val threadStateChecker: ThreadStateChecker,
private val sanitizer: Sanitizer,
@@ -131,6 +141,7 @@ internal abstract class SourceBasedCompilation<A : TestCompilationArtifact>(
home = home,
classLoader = classLoader,
optimizationMode = optimizationMode,
compilerOutputInterceptor = compilerOutputInterceptor,
freeCompilerArgs = freeCompilerArgs,
dependencies = dependencies,
expectedArtifact = expectedArtifact
@@ -165,6 +176,7 @@ internal class LibraryCompilation(
home = settings.get(),
classLoader = settings.get(),
optimizationMode = settings.get(),
compilerOutputInterceptor = settings.get(),
memoryModel = settings.get(),
threadStateChecker = settings.get(),
sanitizer = settings.get(),
@@ -249,6 +261,7 @@ internal class ExecutableCompilation(
home = settings.get(),
classLoader = settings.get(),
optimizationMode = settings.get(),
compilerOutputInterceptor = settings.get(),
memoryModel = settings.get(),
threadStateChecker = settings.get(),
sanitizer = settings.get(),
@@ -332,6 +345,7 @@ internal class StaticCacheCompilation(
home = settings.get(),
classLoader = settings.get(),
optimizationMode = settings.get(),
compilerOutputInterceptor = settings.get(),
freeCompilerArgs = freeCompilerArgs,
dependencies = CategorizedDependencies(dependencies),
expectedArtifact = expectedArtifact
@@ -246,3 +246,8 @@ internal enum class PipelineType(val mutedOption: MutedOption, val compilerFlags
override fun toString() = if (compilerFlags.isEmpty()) "" else compilerFlags.joinToString(prefix = "(", postfix = ")", separator = " ")
}
internal enum class CompilerOutputInterceptor {
DEFAULT,
NONE
}