[KLIB tool] Add tests for dumping IR signatures
^KT-62341
This commit is contained in:
committed by
Space Team
parent
a49723e35c
commit
93506bcb95
+19
@@ -240,6 +240,25 @@ fun main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Dump KLIB IR signatures tests
|
||||
testGroup("native/native.tests/tests-gen", "native/native.tests/testData") {
|
||||
testClass<AbstractNativeKlibDumpIrSignaturesTest>(
|
||||
suiteTestClassName = "NativeKlibDumpIrSignaturesTestGenerated",
|
||||
) {
|
||||
model("klib/dump-signatures", pattern = "^([^_](.+)).kt$", recursive = true)
|
||||
}
|
||||
}
|
||||
testGroup("native/native.tests/tests-gen", "native/native.tests/testData") {
|
||||
testClass<AbstractNativeKlibDumpIrSignaturesTest>(
|
||||
suiteTestClassName = "FirNativeKlibDumpIrSignaturesTestGenerated",
|
||||
annotations = listOf(
|
||||
*frontendFir()
|
||||
)
|
||||
) {
|
||||
model("klib/dump-signatures", pattern = "^([^_](.+)).kt$", recursive = true)
|
||||
}
|
||||
}
|
||||
|
||||
// LLDB integration tests.
|
||||
testGroup("native/native.tests/tests-gen", "native/native.tests/testData") {
|
||||
testClass<AbstractNativeBlackBoxTest>(
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.testFramework.TestDataFile
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.*
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.TestCompilationArtifact
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.TestCompilationDependency
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.runner.TestRunChecks
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.KotlinNativeClassLoader
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.PipelineType
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.settings.Timeouts
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.util.getAbsoluteFile
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.util.dumpIrSignatures
|
||||
import org.jetbrains.kotlin.library.KotlinIrSignatureVersion
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEqualsToFile
|
||||
import org.jetbrains.kotlin.test.utils.withExtension
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Tag
|
||||
import java.io.File
|
||||
|
||||
@Tag("klib")
|
||||
abstract class AbstractNativeKlibDumpIrSignaturesTest : AbstractNativeSimpleTest() {
|
||||
protected fun runTest(@TestDataFile testDataPath: String) {
|
||||
val testDataFile = getAbsoluteFile(testDataPath)
|
||||
muteTestIfNecessary(testDataFile)
|
||||
|
||||
val dependencies: List<TestCompilationDependency<TestCompilationArtifact.KLIB>> = buildList {
|
||||
this += compileRegularDependencies(testDataFile)
|
||||
this += compileInteropDependencies(testDataFile)
|
||||
}
|
||||
|
||||
val library = compileSingleFileToLibrary(testDataFile, dependencies)
|
||||
|
||||
val testPathNoExtension = testDataFile.canonicalPath.substringBeforeLast(".")
|
||||
|
||||
val firSpecificExt =
|
||||
if (testRunSettings.get<PipelineType>() == PipelineType.K2 && !firIdentical(testDataFile))
|
||||
".fir"
|
||||
else ""
|
||||
|
||||
KotlinIrSignatureVersion.CURRENTLY_SUPPORTED_VERSIONS.forEach { signatureVersion ->
|
||||
val expectedContents = File("$testPathNoExtension$firSpecificExt.ir-signatures.v${signatureVersion.number}.txt")
|
||||
assertSignaturesMatchExpected(library, expectedContents, signatureVersion)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun assertSignaturesMatchExpected(
|
||||
library: TestCompilationArtifact.KLIB,
|
||||
expectedContents: File,
|
||||
signatureVersion: KotlinIrSignatureVersion
|
||||
) {
|
||||
val kotlinNativeClassLoader = testRunSettings.get<KotlinNativeClassLoader>()
|
||||
val dumpedSignatures = library.dumpIrSignatures(kotlinNativeClassLoader.classLoader, signatureVersion)
|
||||
assertEqualsToFile(expectedContents, dumpedSignatures)
|
||||
}
|
||||
|
||||
private fun compileInteropDependencies(testDataFile: File): List<TestCompilationDependency<TestCompilationArtifact.KLIB>> {
|
||||
val defFile = testDataFile.withExtension(".lib.def")
|
||||
if (!defFile.exists()) return emptyList()
|
||||
|
||||
assertTrue(defFile.isFile) { "Def file does not exist: $defFile" }
|
||||
|
||||
return listOf(
|
||||
cinteropToLibrary(
|
||||
targets = targets,
|
||||
defFile = defFile,
|
||||
outputDir = buildDir,
|
||||
freeCompilerArgs = TestCompilerArgs.EMPTY
|
||||
).assertSuccess().resultingArtifact.asLibraryDependency()
|
||||
)
|
||||
}
|
||||
|
||||
private fun compileRegularDependencies(testDataFile: File): List<TestCompilationDependency<TestCompilationArtifact.KLIB>> {
|
||||
val mainSourceFileName = testDataFile.name
|
||||
|
||||
return testDataFile.parentFile.listFiles().orEmpty().mapNotNull { dependencyTestDataFile ->
|
||||
if (dependencyTestDataFile == testDataFile || !dependencyTestDataFile.isFile) return@mapNotNull null
|
||||
val dependencyTestDataFileName = dependencyTestDataFile.name
|
||||
|
||||
val dependencyName = dependencyTestDataFileName.substringAfter(mainSourceFileName + "_", missingDelimiterValue = "")
|
||||
if (dependencyName.isBlank()) return@mapNotNull null
|
||||
|
||||
val dependencySourceFile = dependencyTestDataFile.copyTo(buildDir.resolve("$dependencyName.kt"))
|
||||
compileSingleFileToLibrary(dependencySourceFile, emptyList()).asLibraryDependency()
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileSingleFileToLibrary(
|
||||
sourceFile: File,
|
||||
dependencies: List<TestCompilationDependency<TestCompilationArtifact.KLIB>>,
|
||||
): TestCompilationArtifact.KLIB {
|
||||
val moduleName: String = sourceFile.nameWithoutExtension
|
||||
val module = TestModule.Exclusive(moduleName, emptySet(), emptySet(), emptySet())
|
||||
module.files += TestFile.createCommitted(sourceFile, module)
|
||||
|
||||
val testCase = TestCase(
|
||||
id = TestCaseId.Named(moduleName),
|
||||
kind = TestKind.STANDALONE,
|
||||
modules = setOf(module),
|
||||
freeCompilerArgs = TestCompilerArgs("-Xklib-relative-path-base=${sourceFile.parent}"),
|
||||
nominalPackageName = PackageName.EMPTY,
|
||||
checks = TestRunChecks.Default(testRunSettings.get<Timeouts>().executionTimeout),
|
||||
extras = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT)
|
||||
).apply {
|
||||
initialize(null, null)
|
||||
}
|
||||
|
||||
return compileToLibrary(testCase, *dependencies.toTypedArray()).assertSuccess().resultingArtifact
|
||||
}
|
||||
}
|
||||
+19
-3
@@ -6,13 +6,13 @@
|
||||
package org.jetbrains.kotlin.konan.test.blackbox.support.util
|
||||
|
||||
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.TestCompilationArtifact
|
||||
import org.jetbrains.kotlin.library.KotlinIrSignatureVersion
|
||||
import java.io.File
|
||||
|
||||
private fun invokeKlibTool(kotlinNativeClassLoader: ClassLoader, klibFile: File, functionName: String, vararg args: Any): String {
|
||||
private fun invokeKlibTool(kotlinNativeClassLoader: ClassLoader, klibFile: File, functionName: String, vararg args: Any?): String {
|
||||
val libraryClass = Class.forName("org.jetbrains.kotlin.cli.klib.Library", true, kotlinNativeClassLoader)
|
||||
val entryPoint = libraryClass.declaredMethods.single { it.name == functionName }
|
||||
val lib = libraryClass.getDeclaredConstructor(String::class.java, String::class.java)
|
||||
.newInstance(klibFile.canonicalPath, null)
|
||||
val lib = libraryClass.getDeclaredConstructor(String::class.java, String::class.java).newInstance(klibFile.canonicalPath, null)
|
||||
|
||||
val output = StringBuilder()
|
||||
entryPoint.invoke(lib, output, *args)
|
||||
@@ -30,3 +30,19 @@ internal fun TestCompilationArtifact.KLIB.dumpIr(
|
||||
): String {
|
||||
return invokeKlibTool(kotlinNativeClassLoader, klibFile, "dumpIr", printSignatures)
|
||||
}
|
||||
|
||||
internal fun TestCompilationArtifact.KLIB.dumpIrSignatures(
|
||||
kotlinNativeClassLoader: ClassLoader,
|
||||
signatureVersion: KotlinIrSignatureVersion,
|
||||
): String {
|
||||
// This ceremony is required to load `KotlinIrSignatureVersion` class from the isolated class loader and thus avoid
|
||||
// "argument type mismatch" exception raised by the Java reflection API.
|
||||
// TODO: migrate on CLI-based scheme of invocation of all KLIB tool commands
|
||||
val signatureVersionForIsolatedClassLoader = Class.forName(
|
||||
signatureVersion::class.java.canonicalName,
|
||||
true,
|
||||
kotlinNativeClassLoader
|
||||
).getDeclaredConstructor(Int::class.java).newInstance(signatureVersion.number)!!
|
||||
|
||||
return invokeKlibTool(kotlinNativeClassLoader, klibFile, "dumpIrSignatures", signatureVersionForIsolatedClassLoader)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user