[KLIB] Native K1 & K2 tests for dumping KLIB ABI

^KT-54402
This commit is contained in:
Dmitriy Dolovov
2023-07-27 14:46:47 +02:00
committed by Space Team
parent ab9b91180f
commit ac3c000ab1
10 changed files with 306 additions and 135 deletions
+2
View File
@@ -37,3 +37,5 @@ projectTest(jUnitMode = JUnitMode.JUnit5) {
}
val generateTests by generator("org.jetbrains.kotlin.library.abi.GenerateLibraryAbiReaderTestsKt")
testsJar()
@@ -1,42 +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.library.abi
import org.jetbrains.kotlin.library.abi.impl.AbiSignatureVersions
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEqualsToFile
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.TestInfo
import java.io.File
@OptIn(ExperimentalLibraryAbiReader::class)
abstract class AbstractOldLibraryAbiReaderTest {
private lateinit var testName: String
private lateinit var buildDir: File
@BeforeEach
fun setUp(testInfo: TestInfo) {
testName = getTestName(testInfo)
buildDir = setUpBuildDir(testInfo)
}
fun runTest(relativePath: String) {
val (sourceFile, dumpFiles) = computeTestFiles(relativePath, AbiSignatureVersions.Supported.entries)
val (moduleName, filters) = computeModuleNameAndFiltersFromTestDirectives(sourceFile)
val library = buildLibrary(sourceFile, moduleName, buildDir)
val libraryAbi = LibraryAbiReader.readAbiInfo(library, filters)
dumpFiles.entries.forEach { (signatureVersion, dumpFile) ->
val abiDump = LibraryAbiRenderer.render(
libraryAbi,
AbiRenderingSettings(signatureVersion)
)
assertEqualsToFile(dumpFile, abiDump)
}
}
}
@@ -10,14 +10,6 @@ import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
fun main() {
System.setProperty("java.awt.headless", "true")
generateTestGroupSuiteWithJUnit5 {
testGroup("compiler/util-klib-abi/tests-gen", "compiler/util-klib-abi/testData") {
testClass<AbstractOldLibraryAbiReaderTest>(suiteTestClassName = "OldLibraryAbiReaderTest") {
model("content")
}
}
}
generateTestGroupSuiteWithJUnit5 {
testGroup("compiler/util-klib-abi/tests-gen", "compiler/util-klib-abi/testData") {
testClass<AbstractFirJsLibraryAbiReaderTest> {
@@ -30,11 +30,7 @@ import org.jetbrains.kotlin.konan.properties.saveToFile
import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.test.util.KtTestUtil.getHomeDirectory
import org.jetbrains.kotlin.test.utils.TestDisposable
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.TestInfo
import java.io.ByteArrayOutputStream
@@ -46,8 +42,6 @@ import org.jetbrains.kotlin.konan.file.File as KFile
private val TestInfo.className: String get() = testClass.orElseGet { fail("Can't get test class name") }.simpleName
private val TestInfo.methodName: String get() = testMethod.orElseGet { fail("Can't get test method name") }.name
internal fun getTestName(testInfo: TestInfo): String = testInfo.methodName
internal fun setUpBuildDir(testInfo: TestInfo): File {
val projectBuildDir = System.getenv(ENV_VAR_PROJECT_BUILD_DIR)
?.let { File(it) }
@@ -61,80 +55,6 @@ internal fun setUpBuildDir(testInfo: TestInfo): File {
}
}
@OptIn(ExperimentalLibraryAbiReader::class)
internal fun computeTestFiles(
relativePath: String,
signatureVersions: List<AbiSignatureVersion>
): Pair<File, Map<AbiSignatureVersion, File>> {
assertTrue(signatureVersions.isNotEmpty()) { "Signature versions not specified" }
val sourceFile = File(getHomeDirectory()).resolve(relativePath)
assertEquals("kt", sourceFile.extension) { "Invalid source file: $sourceFile" }
assertTrue(sourceFile.isFile) { "Source file does not exist: $sourceFile" }
return sourceFile to signatureVersions.associateWith { signatureVersion ->
val dumpFile = sourceFile.withReplacedExtensionOrNull("kt", "v${signatureVersion.versionNumber}.txt")!!
assertTrue(dumpFile.isFile) { "Dump file does not exist: $dumpFile" }
dumpFile
}
}
@OptIn(ExperimentalLibraryAbiReader::class)
internal fun computeModuleNameAndFiltersFromTestDirectives(sourceFile: File): Pair<String, List<AbiReadingFilter>> {
fun String.parseQualifiedName() = AbiQualifiedName(
packageName = AbiCompoundName(substringBefore('/', missingDelimiterValue = "")),
relativeName = AbiCompoundName(substringAfter('/'))
)
var moduleName: String? = null
val excludedPackages = mutableListOf<AbiCompoundName>()
val excludedClasses = mutableListOf<AbiQualifiedName>()
val nonPublicMarkers = mutableListOf<AbiQualifiedName>()
for (line in sourceFile.bufferedReader().lineSequence()) {
if (!line.parseTestDirective(DIRECTIVE_EXCLUDED_PACKAGES, ::AbiCompoundName, excludedPackages::add)
&& !line.parseTestDirective(DIRECTIVE_EXCLUDED_CLASSES, String::parseQualifiedName, excludedClasses::add)
&& !line.parseTestDirective(DIRECTIVE_NON_PUBLIC_MARKERS, String::parseQualifiedName, nonPublicMarkers::add)
&& !line.parseTestDirective(DIRECTIVE_MODULE, { it }, { moduleName = it })
&& !line.startsWith("//")
&& line.isNotBlank()
) {
break
}
}
assert(moduleName != null) { "No module name specified with MODULE test directive" }
return moduleName!! to listOfNotNull(
excludedPackages.ifNotEmpty(AbiReadingFilter::ExcludedPackages),
excludedClasses.ifNotEmpty(AbiReadingFilter::ExcludedClasses),
nonPublicMarkers.ifNotEmpty(AbiReadingFilter::NonPublicMarkerAnnotations)
)
}
private inline fun <T> String.parseTestDirective(
directivePrefix: String,
parser: (String) -> T,
consumer: (T) -> Unit,
): Boolean {
if (!startsWith(directivePrefix))
return false
val remainder = substring(directivePrefix.length)
try {
val items = parseSpaceSeparatedArgs(remainder)
items.forEach { item -> consumer(parser(item)) }
return true
} catch (e: Exception) {
throw fail<Nothing>("Failure during parsing test directive: $this", e)
}
}
private const val DIRECTIVE_MODULE = "// MODULE:"
private const val DIRECTIVE_EXCLUDED_PACKAGES = "// EXCLUDED_PACKAGES:"
private const val DIRECTIVE_EXCLUDED_CLASSES = "// EXCLUDED_CLASSES:"
private const val DIRECTIVE_NON_PUBLIC_MARKERS = "// NON_PUBLIC_MARKERS:"
internal fun buildLibrary(sourceFile: File, libraryName: String, buildDir: File): File {
val configuration = CompilerConfiguration()
val environment = createForParallelTests(TestDisposable(), configuration, EnvironmentConfigFiles.JS_CONFIG_FILES)
@@ -1,158 +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.library.abi;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.library.abi.GenerateLibraryAbiReaderTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/util-klib-abi/testData/content")
@TestDataPath("$PROJECT_ROOT")
public class OldLibraryAbiReaderTest extends AbstractOldLibraryAbiReaderTest {
@Test
public void testAllFilesPresentInContent() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/util-klib-abi/testData/content"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("callables.kt")
public void testCallables() throws Exception {
runTest("compiler/util-klib-abi/testData/content/callables.kt");
}
@Test
@TestMetadata("classifiers.kt")
public void testClassifiers() throws Exception {
runTest("compiler/util-klib-abi/testData/content/classifiers.kt");
}
@Test
@TestMetadata("excluded_classes_1.kt")
public void testExcluded_classes_1() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_classes_1.kt");
}
@Test
@TestMetadata("excluded_classes_2.kt")
public void testExcluded_classes_2() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_classes_2.kt");
}
@Test
@TestMetadata("excluded_classes_3.kt")
public void testExcluded_classes_3() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_classes_3.kt");
}
@Test
@TestMetadata("excluded_packages_non_root_1.kt")
public void testExcluded_packages_non_root_1() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_packages_non_root_1.kt");
}
@Test
@TestMetadata("excluded_packages_non_root_2.kt")
public void testExcluded_packages_non_root_2() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_packages_non_root_2.kt");
}
@Test
@TestMetadata("excluded_packages_non_root_3.kt")
public void testExcluded_packages_non_root_3() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_packages_non_root_3.kt");
}
@Test
@TestMetadata("excluded_packages_non_root_4.kt")
public void testExcluded_packages_non_root_4() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_packages_non_root_4.kt");
}
@Test
@TestMetadata("excluded_packages_root_1.kt")
public void testExcluded_packages_root_1() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_packages_root_1.kt");
}
@Test
@TestMetadata("excluded_packages_root_2.kt")
public void testExcluded_packages_root_2() throws Exception {
runTest("compiler/util-klib-abi/testData/content/excluded_packages_root_2.kt");
}
@Test
@TestMetadata("inheritance.kt")
public void testInheritance() throws Exception {
runTest("compiler/util-klib-abi/testData/content/inheritance.kt");
}
@Test
@TestMetadata("root_package.kt")
public void testRoot_package() throws Exception {
runTest("compiler/util-klib-abi/testData/content/root_package.kt");
}
@Test
@TestMetadata("type_parameters.kt")
public void testType_parameters() throws Exception {
runTest("compiler/util-klib-abi/testData/content/type_parameters.kt");
}
@Test
@TestMetadata("value_parameters.kt")
public void testValue_parameters() throws Exception {
runTest("compiler/util-klib-abi/testData/content/value_parameters.kt");
}
@Test
@TestMetadata("visibilities.kt")
public void testVisibilities() throws Exception {
runTest("compiler/util-klib-abi/testData/content/visibilities.kt");
}
@Test
@TestMetadata("with_non_public_markers_1.kt")
public void testWith_non_public_markers_1() throws Exception {
runTest("compiler/util-klib-abi/testData/content/with_non_public_markers_1.kt");
}
@Test
@TestMetadata("with_non_public_markers_2.kt")
public void testWith_non_public_markers_2() throws Exception {
runTest("compiler/util-klib-abi/testData/content/with_non_public_markers_2.kt");
}
@Test
@TestMetadata("with_non_public_markers_3.kt")
public void testWith_non_public_markers_3() throws Exception {
runTest("compiler/util-klib-abi/testData/content/with_non_public_markers_3.kt");
}
@Test
@TestMetadata("with_non_public_markers_4.kt")
public void testWith_non_public_markers_4() throws Exception {
runTest("compiler/util-klib-abi/testData/content/with_non_public_markers_4.kt");
}
@Test
@TestMetadata("with_non_public_markers_5.kt")
public void testWith_non_public_markers_5() throws Exception {
runTest("compiler/util-klib-abi/testData/content/with_non_public_markers_5.kt");
}
@Test
@TestMetadata("with_non_public_markers_private_annotations.kt")
public void testWith_non_public_markers_private_annotations() throws Exception {
runTest("compiler/util-klib-abi/testData/content/with_non_public_markers_private_annotations.kt");
}
}