[Native][tests] Use more compact paths to produced binaries

This commit is contained in:
Dmitriy Dolovov
2021-11-23 14:59:52 +03:00
parent 34627633c4
commit 536bfe5bf9
5 changed files with 168 additions and 10 deletions
+1
View File
@@ -12,6 +12,7 @@ dependencies {
testImplementation(project(":kotlin-reflect"))
testImplementation(intellijCoreDep()) { includeJars("intellij-core") }
testImplementation(intellijPluginDep("java"))
testImplementation(intellijDep()) { includeJars("commons-lang-2.4") }
testImplementation(project(":kotlin-compiler-runner-unshaded"))
testImplementation(projectTests(":compiler:tests-common"))
testImplementation(projectTests(":compiler:tests-common-new"))
@@ -0,0 +1,92 @@
/*
* Copyright 2010-2021 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.blackboxtest
import org.jetbrains.kotlin.konan.blackboxtest.support.util.compressedName
import org.jetbrains.kotlin.konan.blackboxtest.support.util.compressedPackageName
import org.jetbrains.kotlin.konan.blackboxtest.support.util.compressedSimpleName
import org.jetbrains.kotlin.konan.target.Architecture
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import kotlin.coroutines.Continuation
class CompressedNamesTest {
@Test
fun targetNameCompression() {
val knownTargets: Set<KonanTarget> = KonanTarget.predefinedTargets.values.toSet()
val compressedNameToTargets: Map<String, KonanTarget> = knownTargets.associateBy { it.compressedName }
val missingTargets: Set<KonanTarget> = compressedNameToTargets.values.toSet() - knownTargets
assertTrue(missingTargets.isEmpty()) { "There are missing targets: $missingTargets" }
assertEquals(knownTargets.size, compressedNameToTargets.size)
val shortestCompressedName = compressedNameToTargets.keys.minByOrNull { it.length }!!
assertTrue(shortestCompressedName.isNotEmpty()) { "Found empty compressed name: $shortestCompressedName" }
val longestCompressedName = compressedNameToTargets.keys.maxByOrNull { it.length }!!
assertTrue(longestCompressedName.length < 6) { "Found too long compressed name: $longestCompressedName" }
}
@Test
fun familyNameCompression() {
val knownFamilies: Set<Family> = Family.values().toSet()
val compressedNameToFamily: Map<Char, Family> = knownFamilies.associateBy { it.compressedName }
val missingFamilies: Set<Family> = compressedNameToFamily.values.toSet() - knownFamilies
assertTrue(missingFamilies.isEmpty()) { "There are missing families: $missingFamilies" }
assertEquals(knownFamilies.size, compressedNameToFamily.size)
}
@Test
fun architectureNameCompression() {
val knownArchitectures: Set<Architecture> = Architecture.values().toSet()
val compressedNameToArchitecture: Map<String, Architecture> = knownArchitectures.associateBy { it.compressedName }
val missingArchitecture: Set<Architecture> = compressedNameToArchitecture.values.toSet() - knownArchitectures
assertTrue(missingArchitecture.isEmpty()) { "There are missing architectures: $missingArchitecture" }
assertEquals(knownArchitectures.size, compressedNameToArchitecture.size)
val nameLengths: Map<Int, List<String>> = compressedNameToArchitecture.keys.groupBy { it.length }
assertEquals(setOf(3), nameLengths.keys) { "Found compressed names with unexpected lengths: $nameLengths" }
}
@Test
fun classNameCompression() {
assertEquals("LinHasMap", LinkedHashMap::class.java.compressedSimpleName)
assertEquals("Con", Continuation::class.java.compressedSimpleName)
assertEquals("AbsNatBlaBoxTes", AbstractNativeBlackBoxTest::class.java.compressedSimpleName)
}
@Test
fun packageNameCompression() {
assertEquals(
"foo_bar_baz",
"foo.bar.baz".compressedPackageName
)
assertEquals(
"foo_bar_baz_foo_bar_baz",
"foo.bar.baz.foo.bar.baz".compressedPackageName
)
assertEquals(
"foo_bar_baz_foo_bar_baz_foo_bar_baz",
"foo.bar.baz.foo.bar.baz.foo.bar.baz".compressedPackageName
)
assertEquals(
"foo_bar_baz_foo_bar_baz_foo_bar-de3b161b",
"foo.bar.baz.foo.bar.baz.foo.bar.baz.foo.bar.baz".compressedPackageName
)
assertEquals(
"foo_bar_baz_foo_bar_baz_foo_bar-a4571752",
"foo.bar.baz.foo.bar.baz.foo.bar.baz.foo.bar.baz.foo.bar.baz".compressedPackageName
)
}
}
@@ -39,15 +39,19 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
private val NAMESPACE = ExtensionContext.Namespace.create(NativeBlackBoxTestSupport::class.java.simpleName)
/** Creates a single instance of [TestRunProvider] per test class. */
private fun ExtensionContext.getOrCreateTestRunProvider(): TestRunProvider =
root.getStore(NAMESPACE).getOrComputeIfAbsent(enclosingTestClass.sanitizedName) { sanitizedName ->
private fun ExtensionContext.getOrCreateTestRunProvider(): TestRunProvider {
val enclosingTestClass = enclosingTestClass
return root.getStore(NAMESPACE).getOrComputeIfAbsent(enclosingTestClass.sanitizedName) {
val globalEnvironment = getOrCreateGlobalEnvironment()
val testRoots = computeTestRoots()
val uniqueEnclosingClassDirName = globalEnvironment.target.compressedName + "_" + enclosingTestClass.compressedSimpleName
val testSourcesDir = globalEnvironment.baseBuildDir
.resolve("blackbox-test-sources")
.resolve(sanitizedName)
.resolve("bbtest.src")
.resolve(uniqueEnclosingClassDirName)
.ensureExistsAndIsEmptyDirectory() // Clean-up the directory with all potentially stale generated sources.
val sharedSourcesDir = testSourcesDir
@@ -55,9 +59,8 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
.ensureExistsAndIsEmptyDirectory()
val testBinariesDir = globalEnvironment.baseBuildDir
.resolve("blackbox-test-binaries")
.resolve(globalEnvironment.target.name)
.resolve(sanitizedName)
.resolve("bbtest.bin")
.resolve(uniqueEnclosingClassDirName)
.ensureExistsAndIsEmptyDirectory() // Clean-up the directory with all potentially stale artifacts.
val sharedBinariesDir = testBinariesDir
@@ -77,6 +80,7 @@ class NativeBlackBoxTestSupport : BeforeEachCallback {
TestRunProvider(environment, testCaseGroupProvider)
}.cast()
}
private fun ExtensionContext.getOrCreateGlobalEnvironment(): GlobalTestEnvironment =
root.getStore(NAMESPACE).getOrComputeIfAbsent(GlobalTestEnvironment::class.java.sanitizedName) {
@@ -99,7 +99,7 @@ internal class TestCompilationFactory(private val environment: TestEnvironment)
private fun singleModuleArtifactFile(module: TestModule.Exclusive, extension: String): File {
val artifactFileName = buildString {
append(module.testCase.nominalPackageName.replace('.', '_')).append('.')
append(module.testCase.nominalPackageName.compressedPackageName).append('.')
if (extension == "klib") append(module.name).append('.')
append(extension)
}
@@ -129,7 +129,7 @@ internal class TestCompilationFactory(private val environment: TestEnvironment)
append(prefix).append('-')
if (commonPackageName != null)
append(commonPackageName.replace('.', '_')).append('-')
append(commonPackageName.compressedPackageName).append('-')
append(prettyHash(hash))
@@ -141,7 +141,7 @@ internal class TestCompilationFactory(private val environment: TestEnvironment)
private fun artifactDirForPackageName(packageName: PackageFQN?): File {
val baseDir = environment.testBinariesDir
val outputDir = if (packageName != null) baseDir.resolve(packageName.replace('.', '_')) else baseDir
val outputDir = if (packageName != null) baseDir.resolve(packageName.compressedPackageName) else baseDir
outputDir.mkdirs()
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2021 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.blackboxtest.support.util
import org.apache.commons.lang.StringUtils.splitByCharacterTypeCamelCase
import org.jetbrains.kotlin.konan.blackboxtest.support.PackageFQN
import org.jetbrains.kotlin.konan.target.Architecture
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget
internal val KonanTarget.compressedName: String
get() = buildString {
append(family.compressedName)
name.splitToSequence('_')
.drop(1)
.filter { it.none(Char::isDigit) }
.forEach { append(it[0]) }
append(architecture.compressedName)
}
internal val Family.compressedName: Char
get() = when (this) {
Family.OSX -> 'o'
Family.IOS -> 'i'
Family.TVOS -> 't'
Family.WATCHOS -> 'w'
Family.LINUX -> 'l'
Family.MINGW -> 'm'
Family.ANDROID -> 'a'
Family.WASM -> 'j' // because 'w', 'a' and 'm' are already occupied
Family.ZEPHYR -> 'z'
}
internal val Architecture.compressedName: String
get() = when (this) {
Architecture.X64 -> "x64"
Architecture.X86 -> "x86"
Architecture.ARM64 -> "a64"
Architecture.ARM32 -> "a32"
Architecture.MIPS32 -> "m32"
Architecture.MIPSEL32 -> "e32"
Architecture.WASM32 -> "w32"
}
internal val Class<*>.compressedSimpleName: String
get() = splitByCharacterTypeCamelCase(simpleName).joinToString("") { it.take(3) }
internal val PackageFQN.compressedPackageName: String
get() {
val sanitizedName = replace('.', '_')
return if (sanitizedName.length > COMPRESSED_PACKAGE_FQN_MAX_LENGTH) {
val suffix = "-" + prettyHash(sanitizedName.hashCode())
sanitizedName.substring(0, COMPRESSED_PACKAGE_FQN_MAX_LENGTH - suffix.length) + suffix
} else
sanitizedName
}
private const val COMPRESSED_PACKAGE_FQN_MAX_LENGTH = 40