[Commonizer] Implement associative commonization

^KT-47301 Verification Pending
This commit is contained in:
sebastian.sellmair
2021-06-11 15:19:35 +02:00
committed by Space
parent 5fdbcb3dd1
commit 42f60d981f
58 changed files with 957 additions and 1091 deletions
@@ -23,7 +23,7 @@ class CliCommonizerTest {
konanHome = konanHome,
inputLibraries = emptySet(),
dependencyLibraries = emptySet(),
outputCommonizerTarget = CommonizerTarget(KonanTarget.LINUX_X64, KonanTarget.MACOS_X64),
outputTargets = setOf(CommonizerTarget(KonanTarget.LINUX_X64, KonanTarget.MACOS_X64)),
outputDirectory = temporaryOutputDirectory.root
)
}
@@ -34,24 +34,13 @@ class CommonizeLibcurlTest {
KonanDistribution(konanHome).platformLibsDir.resolve(LINUX_ARM64.name).listFiles().orEmpty()
.map { TargetedCommonizerDependency(LeafCommonizerTarget(LINUX_ARM64), it) }
.toSet(),
outputCommonizerTarget = CommonizerTarget(LINUX_ARM64, LINUX_X64),
outputDirectory = temporaryOutputDirectory.root
outputTargets = setOf(CommonizerTarget(LINUX_ARM64, LINUX_X64)),
outputDirectory = temporaryOutputDirectory.root,
logLevel = CommonizerLogLevel.Info
)
val x64OutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_X64).identityString)
val arm64OutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_ARM64).identityString)
val commonOutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_X64, LINUX_ARM64).identityString)
assertTrue(
x64OutputDirectory.exists(),
"Missing output directory for x64 target"
)
assertTrue(
arm64OutputDirectory.exists(),
"Missing output directory for arm64 target"
)
assertTrue(
commonOutputDirectory.exists(),
"Missing output directory for commonized x64&arm64 target"
@@ -64,18 +53,8 @@ class CommonizeLibcurlTest {
)
}
assertContainsKnmFiles(x64OutputDirectory)
assertContainsKnmFiles(arm64OutputDirectory)
assertContainsKnmFiles(commonOutputDirectory)
assertContainsManifestWithContent(x64OutputDirectory, "native_targets=linux_x64")
assertContainsManifestWithContent(arm64OutputDirectory, "native_targets=linux_arm64")
assertContainsManifestWithContent(commonOutputDirectory, "native_targets=linux_arm64 linux_x64")
assertContainsManifestWithContent(x64OutputDirectory, "commonizer_target=linux_x64")
assertContainsManifestWithContent(arm64OutputDirectory, "commonizer_target=linux_arm64")
assertContainsManifestWithContent(commonOutputDirectory, "commonizer_native_targets=linux_arm64 linux_x64")
assertContainsManifestWithContent(
commonOutputDirectory, "commonizer_target=${CommonizerTarget(LINUX_X64, LINUX_ARM64).identityString}"
@@ -98,22 +77,14 @@ class CommonizeLibcurlTest {
KonanDistribution(konanHome).platformLibsDir.resolve(LINUX_ARM64.name).listFiles().orEmpty()
.map { TargetedCommonizerDependency(LeafCommonizerTarget(LINUX_ARM64), it) }
.toSet(),
outputCommonizerTarget = CommonizerTarget(LINUX_ARM64, LINUX_X64, MACOS_X64),
outputTargets = setOf(CommonizerTarget(LINUX_ARM64, LINUX_X64, MACOS_X64)),
outputDirectory = temporaryOutputDirectory.root
)
val x64OutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_X64).identityString)
val arm64OutputDirectory = temporaryOutputDirectory.root.resolve(CommonizerTarget(LINUX_ARM64).identityString)
val commonOutputDirectory = temporaryOutputDirectory.root
.resolve(CommonizerTarget(LINUX_X64, LINUX_ARM64, MACOS_X64).identityString)
assertContainsManifestWithContent(x64OutputDirectory, "native_targets=linux_x64")
assertContainsManifestWithContent(arm64OutputDirectory, "native_targets=linux_arm64")
assertContainsManifestWithContent(commonOutputDirectory, "native_targets=linux_arm64 linux_x64")
assertContainsManifestWithContent(x64OutputDirectory, "commonizer_target=linux_x64")
assertContainsManifestWithContent(arm64OutputDirectory, "commonizer_target=linux_arm64")
assertContainsManifestWithContent(commonOutputDirectory, "commonizer_native_targets=linux_arm64 linux_x64 macos_x64")
assertContainsManifestWithContent(
commonOutputDirectory, "commonizer_target=${CommonizerTarget(LINUX_X64, LINUX_ARM64, MACOS_X64).identityString}"
@@ -0,0 +1,44 @@
/*
* 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.commonizer
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.getCommonizedDirectory
import org.jetbrains.kotlin.commonizer.utils.konanHome
import org.jetbrains.kotlin.konan.target.KonanTarget.*
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import kotlin.test.assertTrue
class CommonizeNativeDistributionTest {
@get:Rule
val temporaryOutputDirectory = TemporaryFolder()
@Test
fun commonizeLinuxPlatforms() {
val linuxTarget1 = CommonizerTarget(LINUX_X64, LINUX_ARM64)
val linuxTarget2 = CommonizerTarget(LINUX_X64, LINUX_ARM64, LINUX_ARM32_HFP)
CliCommonizer(this::class.java.classLoader).commonizeNativeDistribution(
konanHome = konanHome,
outputTargets = setOf(linuxTarget1, linuxTarget2),
outputDirectory = temporaryOutputDirectory.root,
logLevel = CommonizerLogLevel.Info
)
assertTrue(
getCommonizedDirectory(temporaryOutputDirectory.root, linuxTarget1).isDirectory,
"Expected directory for $linuxTarget1"
)
assertTrue(
getCommonizedDirectory(temporaryOutputDirectory.root, linuxTarget2).isDirectory,
"Expected directory for $linuxTarget2"
)
}
}
@@ -14,8 +14,8 @@ class CommonizerDependencyTest {
@Test
fun `sample identityString`() {
assertEquals(
"((a, b), c)::${File("/").canonicalPath}hello.txt",
TargetedCommonizerDependency(parseCommonizerTarget("((a,b), c)"), File("/hello.txt")).identityString
"(a, b, c)::${File("/").canonicalPath}hello.txt",
TargetedCommonizerDependency(parseCommonizerTarget("(a, b, c)"), File("/hello.txt")).identityString
)
}
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.commonizer
import org.jetbrains.kotlin.commonizer.HierarchicalCommonizerOutputLayout.fileName
import org.jetbrains.kotlin.commonizer.HierarchicalCommonizerOutputLayout.maxFileNameLength
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.fileName
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.maxFileNameLength
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import kotlin.test.Test
@@ -33,60 +33,14 @@ class CommonizerTargetIdentityStringTest {
}
@Test
fun `hierarchical commonizer targets`() {
val hierarchy = SharedCommonizerTarget(
CommonizerTarget(LINUX_X64, MACOS_X64),
CommonizerTarget(IOS_ARM64, IOS_X64)
)
assertEquals(setOf(LINUX_X64, MACOS_X64, IOS_ARM64, IOS_X64), hierarchy.konanTargets)
assertEquals(hierarchy, parseCommonizerTarget(hierarchy.identityString))
}
@Test
fun `multilevel hierarchical commonizer targets`() {
val hierarchy = SharedCommonizerTarget(
SharedCommonizerTarget(
SharedCommonizerTarget(
SharedCommonizerTarget(
CommonizerTarget(LINUX_X64, MACOS_X64),
CommonizerTarget(IOS_X64, IOS_ARM64)
),
CommonizerTarget(LINUX_ARM32_HFP)
),
CommonizerTarget(LINUX_MIPSEL32)
),
CommonizerTarget(WATCHOS_X86, WATCHOS_ARM64)
)
assertEquals(hierarchy, parseCommonizerTarget(hierarchy.identityString))
}
@Test
fun `parsing CommonizerTarget`() {
fun `parsing CommonizerTarget with 1 5 20 notation`() {
val target = parseCommonizerTarget("(x, (x, y, (a, b), (b, c)))")
assertEquals(
SharedCommonizerTarget(
LeafCommonizerTarget("x"),
SharedCommonizerTarget(
LeafCommonizerTarget("x"),
LeafCommonizerTarget("y"),
SharedCommonizerTarget(
LeafCommonizerTarget("a"),
LeafCommonizerTarget("b"),
),
SharedCommonizerTarget(
LeafCommonizerTarget("b"),
LeafCommonizerTarget("c")
)
)
),
target
)
assertEquals(SharedCommonizerTarget(setOf("x", "y", "a", "b", "c").map(::LeafCommonizerTarget).toSet()), target)
}
@Test
fun `empty shared target`() {
assertEquals(SharedCommonizerTarget(emptySet<CommonizerTarget>()), parseCommonizerTarget("()"))
assertEquals(SharedCommonizerTarget(emptySet<LeafCommonizerTarget>()), parseCommonizerTarget("()"))
}
@Test(expected = IllegalArgumentException::class)
@@ -1,90 +0,0 @@
/*
* 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.commonizer
import org.junit.Test
import kotlin.test.assertEquals
class CommonizerTargetPrettyNameTest {
@Test
fun leafTargetNames() {
listOf(
Triple("foo", "[foo]", FOO),
Triple("bar", "[bar]", BAR),
Triple("baz_123", "[baz_123]", BAZ),
).forEach { (name, prettyName, target: LeafCommonizerTarget) ->
assertEquals(name, target.name)
assertEquals(prettyName, target.prettyName)
}
}
@Test
fun sharedTargetNames() {
listOf(
"[foo]" to SharedTarget(FOO),
"[bar, foo]" to SharedTarget(FOO, BAR),
"[bar, baz_123, foo]" to SharedTarget(FOO, BAR, BAZ),
"[bar, baz_123, foo, [bar, foo]]" to SharedTarget(FOO, BAR, BAZ, SharedTarget(FOO, BAR))
).forEach { (prettyName, target: SharedCommonizerTarget) ->
assertEquals(prettyName, target.prettyName)
}
}
@Test
fun prettyCommonizedName() {
val sharedTarget = SharedTarget(FOO, BAR, BAZ)
listOf(
"[bar, baz_123, foo(*)]" to FOO,
"[bar(*), baz_123, foo]" to BAR,
"[bar, baz_123(*), foo]" to BAZ,
"[bar, baz_123, foo]" to sharedTarget,
).forEach { (prettyCommonizerName, target: CommonizerTarget) ->
assertEquals(prettyCommonizerName, sharedTarget.prettyName(target))
}
}
@Test
fun prettyNestedName() {
val target = parseCommonizerTarget("(a, b, (c, (d, e)))") as SharedCommonizerTarget
assertEquals(
"[a, b, [c, [d, e]]]", target.prettyName
)
assertEquals(
"[a, b, [c, [d, e(*)]]]", target.prettyName(LeafCommonizerTarget("e"))
)
assertEquals(
"[a, b, [c, [d, e](*)]]", target.prettyName(parseCommonizerTarget("(d, e)"))
)
assertEquals(
"[a, b, [c, [d, e]](*)]", target.prettyName(parseCommonizerTarget("(c, (d, e))"))
)
assertEquals(
"[a, b(*), [c, [d, e]]]", target.prettyName(LeafCommonizerTarget("b"))
)
}
@Test
fun sharedTargetNoInnerTargets() {
assertEquals(
"[]", SharedCommonizerTarget(emptySet<CommonizerTarget>()).prettyName
)
}
private companion object {
val FOO = LeafCommonizerTarget("foo")
val BAR = LeafCommonizerTarget("bar")
val BAZ = LeafCommonizerTarget("baz_123")
@Suppress("TestFunctionName")
fun SharedTarget(vararg targets: CommonizerTarget) = SharedCommonizerTarget(linkedSetOf(*targets))
}
}
@@ -7,53 +7,9 @@ package org.jetbrains.kotlin.commonizer
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class CommonizerTargetUtilsTest {
@Test
fun `isAncestorOf isDescendentOf`() {
val child = LeafCommonizerTarget("a")
val parent = SharedCommonizerTarget(LeafCommonizerTarget("a"))
assertTrue(child isDescendentOf parent, "Expected child isDescendent of parent")
assertTrue(parent isAncestorOf child, "Expected parent isAncestor of child")
assertFalse(child isDescendentOf child, "Expected same target not being descendent of itself")
assertFalse(parent isDescendentOf parent, "Expected same target not being descendent of itself")
assertFalse(LeafCommonizerTarget("b") isDescendentOf parent, "Expected orphan target not being descendent of parent")
val hierarchicalParent = SharedCommonizerTarget(parent, parseCommonizerTarget("((c, d), e)"))
assertTrue(child isDescendentOf hierarchicalParent, "Expected child being descendent of hierarchical parent")
assertTrue(hierarchicalParent isAncestorOf child, "Expected hierarchicalParent being ancestor of child")
assertTrue(parseCommonizerTarget("(c, d)") isDescendentOf hierarchicalParent)
assertTrue(LeafCommonizerTarget("e") isDescendentOf hierarchicalParent)
}
@Test
fun withAllAncestors() {
val target = parseCommonizerTarget("((a, b), (c, d), (e, (f, g)))")
assertEquals(
setOf(
target,
parseCommonizerTarget("(a, b)"),
parseCommonizerTarget("(c, d)"),
parseCommonizerTarget("(e, (f, g))"),
parseCommonizerTarget("(f, g)"),
LeafCommonizerTarget("a"),
LeafCommonizerTarget("b"),
LeafCommonizerTarget("c"),
LeafCommonizerTarget("d"),
LeafCommonizerTarget("e"),
LeafCommonizerTarget("f"),
LeafCommonizerTarget("g")
),
target.withAllAncestors(),
"Expected all targets present"
)
}
@Test
fun allLeaves() {
val target = parseCommonizerTarget("((a, b), (c, d), (e, (f, g)))")
@@ -76,5 +32,18 @@ class CommonizerTargetUtilsTest {
"Expected LeafCommonizerTarget returns itself in 'allLeaves'"
)
}
@Test
fun `withAllLeaves LeafCommonizerTarget`() {
assertEquals(setOf(LeafCommonizerTarget("a")), LeafCommonizerTarget("a").withAllLeaves())
}
@Test
fun `withAllLeaves SharedCommonizerTarget`() {
assertEquals(
setOf(parseCommonizerTarget("(a, b)"), LeafCommonizerTarget("a"), LeafCommonizerTarget("b")),
parseCommonizerTarget("(a, b)").withAllLeaves()
)
}
}