[K/N][tests] Support running the compiler without altering its output
This commit is contained in:
committed by
Space Team
parent
e0c7d72cee
commit
ac95ca12cf
+4
-1
@@ -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)
|
||||
|
||||
|
||||
+9
@@ -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)
|
||||
|
||||
|
||||
+33
@@ -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,
|
||||
|
||||
+18
-4
@@ -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
|
||||
|
||||
+5
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user