[K/N][tests] Added a bunch of tests on incremental compilation
This commit is contained in:
@@ -0,0 +1 @@
|
||||
fun foo() = 42
|
||||
@@ -0,0 +1 @@
|
||||
fun bar() = 117
|
||||
@@ -0,0 +1,7 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(42, foo())
|
||||
assertEquals(117, bar())
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun runTest() = assertEquals(42, foo())
|
||||
@@ -0,0 +1,6 @@
|
||||
package test1
|
||||
|
||||
interface I {
|
||||
fun baz(): String
|
||||
fun foo(): Int
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test1
|
||||
|
||||
interface I {
|
||||
fun foo(): Int
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test2
|
||||
|
||||
import test1.*
|
||||
|
||||
fun bar(x: I) = x.foo()
|
||||
@@ -0,0 +1,13 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
class IImpl : I {
|
||||
override fun baz() = "zzz"
|
||||
override fun foo() = 42
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(42, bar(IImpl()))
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
class IImpl : I {
|
||||
override fun foo() = 42
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(42, bar(IImpl()))
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package test1
|
||||
|
||||
interface I {
|
||||
fun baz(): String
|
||||
fun foo(): Int
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package test1
|
||||
|
||||
interface I {
|
||||
fun foo(): Int
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package test1
|
||||
|
||||
interface J : I {
|
||||
fun bar(): String
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test2
|
||||
|
||||
import test1.*
|
||||
|
||||
fun bar(x: J) = x.bar()
|
||||
@@ -0,0 +1,14 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
class JImpl : J {
|
||||
override fun baz() = "qxx"
|
||||
override fun foo() = 42
|
||||
override fun bar() = "zzz"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals("zzz", bar(JImpl()))
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
class JImpl : J {
|
||||
override fun foo() = 42
|
||||
override fun bar() = "zzz"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals("zzz", bar(JImpl()))
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package test1
|
||||
|
||||
open class A {
|
||||
open fun baz() = "zzz"
|
||||
open fun foo() = 117
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test1
|
||||
|
||||
open class A {
|
||||
open fun foo() = 117
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test2
|
||||
|
||||
import test1.*
|
||||
|
||||
fun bar(a: A) = a.foo()
|
||||
@@ -0,0 +1,12 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
class B : A() {
|
||||
override fun foo() = 42
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(42, bar(B()))
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package test1
|
||||
|
||||
open class A {
|
||||
open fun baz() = "qxx"
|
||||
open fun foo() = 117
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package test1
|
||||
|
||||
open class A {
|
||||
open fun foo() = 117
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package test1
|
||||
|
||||
open class B : A() {
|
||||
open fun bar() = "zzz"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test2
|
||||
|
||||
import test1.*
|
||||
|
||||
fun bar(b: B) = b.bar()
|
||||
@@ -0,0 +1,12 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
class C : B() {
|
||||
override fun bar() = "qzz"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals("qzz", bar(C()))
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
inline fun foo(arr: IntArray, transform: (Int) -> Int): Int {
|
||||
var sum = 0
|
||||
for (x in arr) sum += transform(x)
|
||||
return sum
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
inline fun bar(arr: IntArray, transform: (Int) -> Int): Int {
|
||||
var max = Int.MIN_VALUE
|
||||
for (x in arr) {
|
||||
val y = transform(x)
|
||||
if (y > max) max = y
|
||||
}
|
||||
return max
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun checkFoo() {
|
||||
assertEquals(42, foo(intArrayOf(1, 2, 3, 4, 5, 6)) { it * 2 })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun checkBar() {
|
||||
assertEquals(42, bar(intArrayOf(1, 3, 7)) { it * 6 })
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package external
|
||||
|
||||
fun foo() = 42
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package external
|
||||
|
||||
fun foo2() = 128
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package external
|
||||
|
||||
fun foo2() = 117
|
||||
@@ -0,0 +1,6 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun doTest() {
|
||||
assertEquals(42, bar())
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun doTest2() {
|
||||
assertEquals(128, bar2())
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun doTest2() {
|
||||
assertEquals(117, bar2())
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
fun bar() = external.foo()
|
||||
@@ -0,0 +1 @@
|
||||
fun bar2() = external.foo2()
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun foo() = 20
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun foo() = 21
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun bar() = 117
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun baz() = foo() * 2
|
||||
@@ -0,0 +1,8 @@
|
||||
import kotlin.test.*
|
||||
import test.*
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(117, bar())
|
||||
assertEquals(40, baz())
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import kotlin.test.*
|
||||
import test.*
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(117, bar())
|
||||
assertEquals(42, baz())
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package test1
|
||||
|
||||
fun foo() = 20
|
||||
@@ -0,0 +1,3 @@
|
||||
package test1
|
||||
|
||||
fun foo() = 21
|
||||
@@ -0,0 +1,3 @@
|
||||
package test2
|
||||
|
||||
fun bar() = 117
|
||||
@@ -0,0 +1,5 @@
|
||||
package test2
|
||||
|
||||
import test1.*
|
||||
|
||||
fun baz() = foo() * 2
|
||||
@@ -0,0 +1,9 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(117, bar())
|
||||
assertEquals(40, baz())
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import kotlin.test.*
|
||||
import test1.*
|
||||
import test2.*
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertEquals(117, bar())
|
||||
assertEquals(42, baz())
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package tezd
|
||||
|
||||
fun foo() = 42
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun foo() = 42
|
||||
@@ -0,0 +1,5 @@
|
||||
import kotlin.test.*
|
||||
import tezd.*
|
||||
|
||||
@Test
|
||||
fun runTest() = assertEquals(42, foo())
|
||||
@@ -0,0 +1,5 @@
|
||||
import kotlin.test.*
|
||||
import test.*
|
||||
|
||||
@Test
|
||||
fun runTest() = assertEquals(42, foo())
|
||||
@@ -0,0 +1 @@
|
||||
fun foo() = 41
|
||||
@@ -0,0 +1 @@
|
||||
fun foo() = 42
|
||||
@@ -0,0 +1,4 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun runTest() = assertEquals(41, foo())
|
||||
@@ -0,0 +1,4 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun runTest() = assertEquals(42, foo())
|
||||
+8
-6
@@ -42,7 +42,7 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() {
|
||||
val lib = compileToLibrary(rootDir.resolve("lib"), buildDir)
|
||||
val main = compileToExecutable(rootDir.resolve("main"), autoCacheFrom = buildDir, emptyList(), lib)
|
||||
|
||||
assertTrue(main.executableFile.exists())
|
||||
assertTrue(main.exists())
|
||||
assertTrue(autoCacheDir.resolve(cacheFlavor).resolve("lib").exists())
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() {
|
||||
externalLib, userLib
|
||||
)
|
||||
|
||||
assertTrue(main.executableFile.exists())
|
||||
assertTrue(main.exists())
|
||||
assertTrue(autoCacheDir.resolve(cacheFlavor).resolve("externalLib").exists())
|
||||
assertFalse(autoCacheDir.resolve(cacheFlavor).resolve("userLib").exists())
|
||||
}
|
||||
@@ -75,12 +75,13 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() {
|
||||
assertTrue(cacheDir.resolve("lib-${if (makePerFileCache) "per-file-cache" else "cache"}").exists())
|
||||
val main = compileToExecutable(rootDir.resolve("main"), autoCacheFrom = buildDir, listOf(cacheDir), lib)
|
||||
|
||||
assertTrue(main.executableFile.exists())
|
||||
assertTrue(main.exists())
|
||||
assertFalse(autoCacheDir.resolve(cacheFlavor).resolve("lib").exists())
|
||||
}
|
||||
|
||||
private fun compileToExecutable(sourcesDir: File, autoCacheFrom: File, cacheDirectories: List<File>, vararg dependencies: KLIB) =
|
||||
compileToExecutable(
|
||||
private fun compileToExecutable(sourcesDir: File, autoCacheFrom: File, cacheDirectories: List<File>, vararg dependencies: KLIB): File {
|
||||
autoCacheDir.mkdirs()
|
||||
return compileToExecutable(
|
||||
sourcesDir,
|
||||
freeCompilerArgs = TestCompilerArgs(
|
||||
listOf(
|
||||
@@ -89,7 +90,8 @@ class CachesAutoBuildTest : AbstractNativeSimpleTest() {
|
||||
) + cacheDirectories.map { "-Xcache-directory=${it.absolutePath}" }
|
||||
),
|
||||
*dependencies
|
||||
).assertSuccess().resultingArtifact
|
||||
).executableFile
|
||||
}
|
||||
|
||||
private val autoCacheDir: File get() = buildDir.resolve("__auto_cache__")
|
||||
private val cacheFlavor: String
|
||||
|
||||
+542
@@ -0,0 +1,542 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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 com.intellij.testFramework.TestDataPath
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.CachesAutoBuildTest.Companion.TEST_SUITE_PATH
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.EnforcedHostTarget
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.group.UsePartialLinkage
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.CacheMode
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.OptimizationMode
|
||||
import org.jetbrains.kotlin.test.TestMetadata
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertFalse
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertNotEquals
|
||||
import org.junit.jupiter.api.Assumptions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.File
|
||||
|
||||
@Tag("caches")
|
||||
@EnforcedHostTarget
|
||||
@TestMetadata(TEST_SUITE_PATH)
|
||||
@TestDataPath("\$PROJECT_ROOT")
|
||||
@UsePartialLinkage(UsePartialLinkage.Mode.DISABLED)
|
||||
class IncrementalCompilationTest : AbstractNativeSimpleTest() {
|
||||
@BeforeEach
|
||||
fun assumeCachesAreEnabled() {
|
||||
Assumptions.assumeFalse(testRunSettings.get<CacheMode>() == CacheMode.WithoutCache)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple")
|
||||
fun testSimple() = withRootDir(File("$TEST_SUITE_PATH/simple")) {
|
||||
val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" }
|
||||
val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "")
|
||||
assertTrue(libKtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib>'s cache won't be recompiled if nothing has changed.
|
||||
val modified = libKtCacheDir.lastModified()
|
||||
compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
assertTrue(libKtCacheDir.exists())
|
||||
assertEquals(modified, libKtCacheDir.lastModified())
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("modifiedFile")
|
||||
fun testModifiedFile() = withRootDir(File("$TEST_SUITE_PATH/simple")) {
|
||||
val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" }
|
||||
val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "")
|
||||
assertTrue(libKtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib>'s cache will be recompiled after changing the file.
|
||||
val modified = libKtCacheDir.lastModified()
|
||||
val lib1 = compileLibrary("lib") { "lib/lib.1.kt" copyTo "lib.kt" }
|
||||
val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" }
|
||||
assertTrue(libKtCacheDir.exists())
|
||||
assertNotEquals(modified, libKtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("addedFile")
|
||||
fun testAddedFile() = withRootDir(File("$TEST_SUITE_PATH/addDeleteFile")) {
|
||||
val lib = compileLibrary("lib") { "lib/lib.file1.kt" copyTo "lib.file1.kt" }
|
||||
val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libFile1KtCacheDir = getLibraryFileCache("lib", "lib/lib.file1.kt", "")
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib>'s file1 cache won't change after adding an independent file.
|
||||
val modified = libFile1KtCacheDir.lastModified()
|
||||
val lib1 = compileLibrary("lib") {
|
||||
"lib/lib.file1.kt" copyTo "lib.file1.kt"
|
||||
"lib/lib.file2.kt" copyTo "lib.file2.kt"
|
||||
}
|
||||
val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" }
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
assertEquals(modified, libFile1KtCacheDir.lastModified())
|
||||
val libFile2KtCacheDir = getLibraryFileCache("lib", "lib/lib.file2.kt", "")
|
||||
assertTrue(libFile2KtCacheDir.exists())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("removedFile")
|
||||
fun testRemovedFile() = withRootDir(File("$TEST_SUITE_PATH/addDeleteFile")) {
|
||||
val lib = compileLibrary("lib") {
|
||||
"lib/lib.file1.kt" copyTo "lib.file1.kt"
|
||||
"lib/lib.file2.kt" copyTo "lib.file2.kt"
|
||||
}
|
||||
val main = compileToExecutable("main", lib) { "main/main.1.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libFile1KtCacheDir = getLibraryFileCache("lib", "lib/lib.file1.kt", "")
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
val libFile2KtCacheDir = getLibraryFileCache("lib", "lib/lib.file2.kt", "")
|
||||
assertTrue(libFile2KtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib>'s file1 cache won't change after removing an independent file.
|
||||
val modified = libFile1KtCacheDir.lastModified()
|
||||
val lib1 = compileLibrary("lib") { "lib/lib.file1.kt" copyTo "lib.file1.kt" }
|
||||
val main1 = compileToExecutable("main", lib1) { "main/main.kt" copyTo "main.kt" }
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
assertEquals(modified, libFile1KtCacheDir.lastModified())
|
||||
// Check, <lib>'s file2 cache has been removed.
|
||||
assertFalse(libFile2KtCacheDir.exists())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("renamedFile")
|
||||
fun testRenamedFile() = withRootDir(File("$TEST_SUITE_PATH/renameFileOrPackage")) {
|
||||
val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" }
|
||||
val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "test")
|
||||
assertTrue(libKtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib>'s file cache is moved to other directory.
|
||||
val lib1 = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.changed.kt" }
|
||||
val main1 = compileToExecutable("main", lib1) { "main/main.kt" copyTo "main.kt" }
|
||||
assertFalse(libKtCacheDir.exists())
|
||||
val changedLibKtCacheDir = getLibraryFileCache("lib", "lib/lib.changed.kt", "test")
|
||||
assertTrue(changedLibKtCacheDir.exists())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("renamedPackage")
|
||||
fun testRenamedPackage() = withRootDir(File("$TEST_SUITE_PATH/renameFileOrPackage")) {
|
||||
val lib = compileLibrary("lib") { "lib/lib.kt" copyTo "lib.kt" }
|
||||
val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "test")
|
||||
assertTrue(libKtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib>'s file cache is moved to other directory.
|
||||
val lib1 = compileLibrary("lib") { "lib/lib.1.kt" copyTo "lib.kt" }
|
||||
val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" }
|
||||
assertFalse(libKtCacheDir.exists())
|
||||
val changedLibKtCacheDir = getLibraryFileCache("lib", "lib/lib.kt", "tezd")
|
||||
assertTrue(changedLibKtCacheDir.exists())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("changedFileIndex")
|
||||
fun testChangedFileIndex() = withRootDir(File("$TEST_SUITE_PATH/changeFileIndex")) {
|
||||
val lib = compileLibrary("lib") {
|
||||
"lib/lib.file1.kt" copyTo "libB.kt"
|
||||
"lib/lib.file2.kt" copyTo "libC.kt"
|
||||
}
|
||||
val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libBKtCacheDir = getLibraryFileCache("lib", "lib/libB.kt", "")
|
||||
assertTrue(libBKtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
val modified = libBKtCacheDir.lastModified()
|
||||
val lib1 = compileLibrary("lib") {
|
||||
"lib/lib.file1.kt" copyTo "libB.kt"
|
||||
"lib/lib.file2.kt" copyTo "libA.kt"
|
||||
}
|
||||
val main1 = compileToExecutable("main", lib1) { "main/main.kt" copyTo "main.kt" }
|
||||
assertTrue(libBKtCacheDir.exists())
|
||||
assertEquals(modified, libBKtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("changedExternalDependencyVersion")
|
||||
fun testChangedExternalDependencyVersion() = withRootDir(File("$TEST_SUITE_PATH/externalDependency")) {
|
||||
val externalLib = compileLibrary("externalLib") {
|
||||
libraryVersion = "1.0"
|
||||
outputDir = "external"
|
||||
"externalLib/file1.kt" copyTo "file1.kt"
|
||||
}
|
||||
val userLib = compileLibrary("userLib", externalLib) { "userLib/file1.kt" copyTo "file1.kt" }
|
||||
val main = compileToExecutable("main", externalLib, userLib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libFile1KtCacheDir = getLibraryFileCache("userLib", "userLib/file1.kt", "")
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
val modified = libFile1KtCacheDir.lastModified()
|
||||
val externalLib1 = compileLibrary("externalLib") {
|
||||
libraryVersion = "1.1"
|
||||
outputDir = "external"
|
||||
"externalLib/file1.kt" copyTo "file1.kt"
|
||||
}
|
||||
val userLib1 = compileLibrary("userLib", externalLib1) { "userLib/file1.kt" copyTo "file1.kt" }
|
||||
val main1 = compileToExecutable("main", externalLib1, userLib1) { "main/main.kt" copyTo "main.kt" }
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
assertNotEquals(modified, libFile1KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("changedExternalDependency")
|
||||
fun testChangedExternalDependency() = withRootDir(File("$TEST_SUITE_PATH/externalDependency")) {
|
||||
val externalLib = compileLibrary("externalLib") {
|
||||
outputDir = "external"
|
||||
"externalLib/file1.kt" copyTo "file1.kt"
|
||||
"externalLib/file2.kt" copyTo "file2.kt"
|
||||
}
|
||||
val userLib = compileLibrary("userLib", externalLib) {
|
||||
"userLib/file1.kt" copyTo "file1.kt"
|
||||
"userLib/file2.kt" copyTo "file2.kt"
|
||||
}
|
||||
val main = compileToExecutable("main", externalLib, userLib) {
|
||||
"main/main.kt" copyTo "main.kt"
|
||||
"main/main2.kt" copyTo "main2.kt"
|
||||
}
|
||||
|
||||
assertTrue(main.executableFile.exists())
|
||||
val libFile1KtCacheDir = getLibraryFileCache("userLib", "userLib/file1.kt", "")
|
||||
val libFile2KtCacheDir = getLibraryFileCache("userLib", "userLib/file2.kt", "")
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
assertTrue(libFile2KtCacheDir.exists())
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, both file caches will be recompiled after changing only one file in the external library.
|
||||
val modified1 = libFile1KtCacheDir.lastModified()
|
||||
val modified2 = libFile2KtCacheDir.lastModified()
|
||||
val externalLib1 = compileLibrary("externalLib") {
|
||||
outputDir = "external"
|
||||
"externalLib/file1.kt" copyTo "file1.kt"
|
||||
"externalLib/file2.1.kt" copyTo "file2.kt"
|
||||
}
|
||||
val main1 = compileToExecutable("main", externalLib1, userLib) {
|
||||
"main/main.kt" copyTo "main.kt"
|
||||
"main/main2.1.kt" copyTo "main2.kt"
|
||||
}
|
||||
assertTrue(libFile1KtCacheDir.exists())
|
||||
assertNotEquals(modified1, libFile1KtCacheDir.lastModified())
|
||||
assertTrue(libFile2KtCacheDir.exists())
|
||||
assertNotEquals(modified2, libFile2KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("fileDependencies1")
|
||||
fun testFileDependencies1() = withRootDir(File("$TEST_SUITE_PATH/fileDependencies1")) {
|
||||
val lib = compileLibrary("lib") {
|
||||
"lib/lib.file1.kt" copyTo "file1.kt"
|
||||
"lib/lib.file2.kt" copyTo "file2.kt"
|
||||
"lib/lib.file3.kt" copyTo "file3.kt"
|
||||
}
|
||||
val main = compileToExecutable("main", lib) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val file1KtCacheDir = getLibraryFileCache("lib", "lib/file1.kt", "test")
|
||||
val file2KtCacheDir = getLibraryFileCache("lib", "lib/file2.kt", "test")
|
||||
val file3KtCacheDir = getLibraryFileCache("lib", "lib/file3.kt", "test")
|
||||
assertTrue(file1KtCacheDir.exists())
|
||||
assertTrue(file2KtCacheDir.exists())
|
||||
assertTrue(file3KtCacheDir.exists())
|
||||
val modified1 = file1KtCacheDir.lastModified()
|
||||
val modified2 = file2KtCacheDir.lastModified()
|
||||
val modified3 = file3KtCacheDir.lastModified()
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib>'s file1 and file3 caches will be recompiled after changing file1.
|
||||
val lib1 = compileLibrary("lib") {
|
||||
"lib/lib.file1.1.kt" copyTo "file1.kt"
|
||||
"lib/lib.file2.kt" copyTo "file2.kt"
|
||||
"lib/lib.file3.kt" copyTo "file3.kt"
|
||||
}
|
||||
val main1 = compileToExecutable("main", lib1) { "main/main.1.kt" copyTo "main.kt" }
|
||||
assertTrue(main1.executableFile.exists())
|
||||
assertTrue(file1KtCacheDir.exists())
|
||||
assertTrue(file2KtCacheDir.exists())
|
||||
assertTrue(file3KtCacheDir.exists())
|
||||
assertNotEquals(modified1, file1KtCacheDir.lastModified())
|
||||
assertEquals(modified2, file2KtCacheDir.lastModified())
|
||||
assertNotEquals(modified3, file3KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("fileDependencies2")
|
||||
fun testFileDependencies2() = withRootDir(File("$TEST_SUITE_PATH/fileDependencies2")) {
|
||||
val lib1 = compileLibrary("lib1") { "lib1/lib1.kt" copyTo "lib1.kt" }
|
||||
val lib2 = compileLibrary("lib2", lib1) {
|
||||
"lib2/lib2.file1.kt" copyTo "file1.kt"
|
||||
"lib2/lib2.file2.kt" copyTo "file2.kt"
|
||||
}
|
||||
val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val lib1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.kt", "test1")
|
||||
val lib2File1KtCacheDir = getLibraryFileCache("lib2", "lib2/file1.kt", "test2")
|
||||
val lib2File2KtCacheDir = getLibraryFileCache("lib2", "lib2/file2.kt", "test2")
|
||||
assertTrue(lib1KtCacheDir.exists())
|
||||
assertTrue(lib2File1KtCacheDir.exists())
|
||||
assertTrue(lib2File2KtCacheDir.exists())
|
||||
val modified11 = lib1KtCacheDir.lastModified()
|
||||
val modified21 = lib2File1KtCacheDir.lastModified()
|
||||
val modified22 = lib2File2KtCacheDir.lastModified()
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib2>'s file2 cache will be recompiled after changing lib1/lib1.kt.
|
||||
val lib11 = compileLibrary("lib1") { "lib1/lib1.1.kt" copyTo "lib1.kt" }
|
||||
val lib21 = compileLibrary("lib2", lib11) {
|
||||
"lib2/lib2.file1.kt" copyTo "file1.kt"
|
||||
"lib2/lib2.file2.kt" copyTo "file2.kt"
|
||||
}
|
||||
val main1 = compileToExecutable("main", lib11, lib21) { "main/main.1.kt" copyTo "main.kt" }
|
||||
assertTrue(main1.executableFile.exists())
|
||||
assertTrue(lib1KtCacheDir.exists())
|
||||
assertTrue(lib2File1KtCacheDir.exists())
|
||||
assertTrue(lib2File2KtCacheDir.exists())
|
||||
assertNotEquals(modified11, lib1KtCacheDir.lastModified())
|
||||
assertEquals(modified21, lib2File1KtCacheDir.lastModified())
|
||||
assertNotEquals(modified22, lib2File2KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("addMethodToOpenClass1")
|
||||
fun addMethodToOpenClass1() = withRootDir(File("$TEST_SUITE_PATH/addMethodToOpenClass1")) {
|
||||
val lib1 = compileLibrary("lib1") { "lib1/lib1.kt" copyTo "lib1.kt" }
|
||||
val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val lib1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.kt", "test1")
|
||||
val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2")
|
||||
assertTrue(lib1KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
val modified1 = lib1KtCacheDir.lastModified()
|
||||
val modified2 = lib2KtCacheDir.lastModified()
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib2>'s cache won't be recompiled after changing lib1/lib1.kt.
|
||||
val lib11 = compileLibrary("lib1") { "lib1/lib1.1.kt" copyTo "lib1.kt" }
|
||||
val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main1 = compileToExecutable("main", lib11, lib21) { "main/main.kt" copyTo "main.kt" }
|
||||
assertTrue(main1.executableFile.exists())
|
||||
assertTrue(lib1KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
assertNotEquals(modified1, lib1KtCacheDir.lastModified())
|
||||
assertEquals(modified2, lib2KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("addMethodToOpenClass2")
|
||||
fun addMethodToOpenClass2() = withRootDir(File("$TEST_SUITE_PATH/addMethodToOpenClass2")) {
|
||||
val lib1 = compileLibrary("lib1") {
|
||||
"lib1/lib1.file1.kt" copyTo "lib1.file1.kt"
|
||||
"lib1/lib1.file2.kt" copyTo "lib1.file2.kt"
|
||||
}
|
||||
val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val lib1File1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file1.kt", "test1")
|
||||
val lib1File2KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file2.kt", "test1")
|
||||
val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2")
|
||||
assertTrue(lib1File1KtCacheDir.exists())
|
||||
assertTrue(lib1File2KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
val modified11 = lib1File1KtCacheDir.lastModified()
|
||||
val modified12 = lib1File2KtCacheDir.lastModified()
|
||||
val modified2 = lib2KtCacheDir.lastModified()
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib2>'s cache won't be recompiled after changing lib1/lib1.file1.kt.
|
||||
val lib11 = compileLibrary("lib1") {
|
||||
"lib1/lib1.file1.1.kt" copyTo "lib1.file1.kt"
|
||||
"lib1/lib1.file2.kt" copyTo "lib1.file2.kt"
|
||||
}
|
||||
val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main1 = compileToExecutable("main", lib11, lib21) { "main/main.kt" copyTo "main.kt" }
|
||||
assertTrue(main1.executableFile.exists())
|
||||
assertTrue(lib1File1KtCacheDir.exists())
|
||||
assertTrue(lib1File2KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
assertNotEquals(modified11, lib1File1KtCacheDir.lastModified())
|
||||
assertNotEquals(modified12, lib1File2KtCacheDir.lastModified())
|
||||
assertEquals(modified2, lib2KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("addMethodToInterface1")
|
||||
fun addMethodToInterface1() = withRootDir(File("$TEST_SUITE_PATH/addMethodToInterface1")) {
|
||||
val lib1 = compileLibrary("lib1") { "lib1/lib1.kt" copyTo "lib1.kt" }
|
||||
val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val lib1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.kt", "test1")
|
||||
val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2")
|
||||
assertTrue(lib1KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
val modified1 = lib1KtCacheDir.lastModified()
|
||||
val modified2 = lib2KtCacheDir.lastModified()
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib2>'s cache won't be recompiled after changing lib1/lib1.kt.
|
||||
val lib11 = compileLibrary("lib1") { "lib1/lib1.1.kt" copyTo "lib1.kt" }
|
||||
val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main1 = compileToExecutable("main", lib11, lib21) { "main/main.1.kt" copyTo "main.kt" }
|
||||
assertTrue(main1.executableFile.exists())
|
||||
assertTrue(lib1KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
assertNotEquals(modified1, lib1KtCacheDir.lastModified())
|
||||
assertEquals(modified2, lib2KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("addMethodToInterface2")
|
||||
fun addMethodToInterface2() = withRootDir(File("$TEST_SUITE_PATH/addMethodToInterface2")) {
|
||||
val lib1 = compileLibrary("lib1") {
|
||||
"lib1/lib1.file1.kt" copyTo "lib1.file1.kt"
|
||||
"lib1/lib1.file2.kt" copyTo "lib1.file2.kt"
|
||||
}
|
||||
val lib2 = compileLibrary("lib2", lib1) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main = compileToExecutable("main", lib1, lib2) { "main/main.kt" copyTo "main.kt" }
|
||||
|
||||
// Check, <lib> has been compiled to cache.
|
||||
assertTrue(main.executableFile.exists())
|
||||
val lib1File1KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file1.kt", "test1")
|
||||
val lib1File2KtCacheDir = getLibraryFileCache("lib1", "lib1/lib1.file2.kt", "test1")
|
||||
val lib2KtCacheDir = getLibraryFileCache("lib2", "lib2/lib2.kt", "test2")
|
||||
assertTrue(lib1File1KtCacheDir.exists())
|
||||
assertTrue(lib1File2KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
val modified11 = lib1File1KtCacheDir.lastModified()
|
||||
val modified12 = lib1File2KtCacheDir.lastModified()
|
||||
val modified2 = lib2KtCacheDir.lastModified()
|
||||
runExecutableAndVerify(main.testCase, main.testExecutable)
|
||||
|
||||
// Check, <lib2>'s cache won't be recompiled after changing lib1/lib1.file1.kt.
|
||||
val lib11 = compileLibrary("lib1") {
|
||||
"lib1/lib1.file1.1.kt" copyTo "lib1.file1.kt"
|
||||
"lib1/lib1.file2.kt" copyTo "lib1.file2.kt"
|
||||
}
|
||||
val lib21 = compileLibrary("lib2", lib11) { "lib2/lib2.kt" copyTo "lib2.kt" }
|
||||
val main1 = compileToExecutable("main", lib11, lib21) { "main/main.1.kt" copyTo "main.kt" }
|
||||
assertTrue(main1.executableFile.exists())
|
||||
assertTrue(lib1File1KtCacheDir.exists())
|
||||
assertTrue(lib1File2KtCacheDir.exists())
|
||||
assertTrue(lib2KtCacheDir.exists())
|
||||
assertNotEquals(modified11, lib1File1KtCacheDir.lastModified())
|
||||
assertNotEquals(modified12, lib1File2KtCacheDir.lastModified())
|
||||
assertEquals(modified2, lib2KtCacheDir.lastModified())
|
||||
runExecutableAndVerify(main1.testCase, main1.testExecutable)
|
||||
}
|
||||
|
||||
private inline fun withRootDir(rootDir: File, block: RootDirHolder.() -> Unit) = RootDirHolder(rootDir).block()
|
||||
|
||||
private inner class RootDirHolder(val rootDir: File) {
|
||||
inline fun compileLibrary(
|
||||
targetSrc: String,
|
||||
vararg dependencies: TestCompilationArtifact.KLIB,
|
||||
block: LibraryBuilder.() -> Unit
|
||||
) = with(LibraryBuilder(this@IncrementalCompilationTest, rootDir, targetSrc, dependencies.asList())) {
|
||||
block()
|
||||
build()
|
||||
}
|
||||
|
||||
inline fun compileToExecutable(
|
||||
targetSrc: String,
|
||||
vararg dependencies: TestCompilationArtifact.KLIB,
|
||||
block: ExecutableBuilder.() -> Unit
|
||||
) = with(ExecutableBuilder(this@IncrementalCompilationTest, rootDir, targetSrc, dependencies.asList())) {
|
||||
externalLibsDir.mkdirs()
|
||||
icCacheDir.mkdirs()
|
||||
autoCacheDir.mkdirs()
|
||||
+"-Xauto-cache-from=${externalLibsDir.absolutePath}"
|
||||
+"-Xauto-cache-dir=${autoCacheDir.absolutePath}"
|
||||
+"-Xic-cache-dir=${icCacheDir.absolutePath}"
|
||||
+"-Xenable-incremental-compilation"
|
||||
+"-verbose"
|
||||
block()
|
||||
build()
|
||||
}
|
||||
}
|
||||
|
||||
private val externalLibsDir: File get() = buildDir.resolve("external")
|
||||
private val autoCacheDir: File get() = buildDir.resolve("__auto_cache__")
|
||||
private val icCacheDir: File get() = buildDir.resolve("__ic_cache__")
|
||||
private val cacheFlavor: String
|
||||
get() = CacheMode.computeCacheDirName(
|
||||
testRunSettings.get<KotlinNativeTargets>().testTarget,
|
||||
"STATIC",
|
||||
testRunSettings.get<OptimizationMode>() == OptimizationMode.DEBUG,
|
||||
partialLinkageEnabled = false
|
||||
)
|
||||
|
||||
private fun getLibraryFileCache(libName: String, libFileRelativePath: String, fqName: String): File {
|
||||
val libCacheDir = icCacheDir.resolve(cacheFlavor).resolve("$libName-per-file-cache")
|
||||
val fileId = cacheFileId(fqName, buildDir.resolve(libFileRelativePath).absolutePath)
|
||||
return libCacheDir.resolve(fileId)
|
||||
}
|
||||
|
||||
private fun cacheFileId(fqName: String, filePath: String) =
|
||||
"${if (fqName == "") "ROOT" else fqName}.${filePath.hashCode().toString(Character.MAX_RADIX)}"
|
||||
|
||||
companion object {
|
||||
const val TEST_SUITE_PATH = "native/native.tests/testData/caches/ic"
|
||||
}
|
||||
}
|
||||
+104
-3
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilati
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationDependencyType
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestExecutable
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets
|
||||
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.PipelineType
|
||||
@@ -36,6 +37,83 @@ import java.io.File
|
||||
|
||||
private val DEFAULT_EXTRAS = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT)
|
||||
|
||||
internal abstract class ArtifactBuilder<T>(
|
||||
val test: AbstractNativeSimpleTest,
|
||||
val rootDir: File,
|
||||
val targetSrc: String,
|
||||
dependencies: List<TestCompilationArtifact.KLIB>
|
||||
) {
|
||||
private val buildDir = test.buildDir
|
||||
var outputDir: String = ""
|
||||
|
||||
private val sources = mutableListOf<Pair<String, String>>()
|
||||
private val dependencies = dependencies.toMutableList()
|
||||
|
||||
infix fun String.copyTo(to: String) {
|
||||
sources.add(Pair(this, to))
|
||||
}
|
||||
|
||||
fun dependsOn(klib: TestCompilationArtifact.KLIB) {
|
||||
dependencies.add(klib)
|
||||
}
|
||||
|
||||
protected abstract fun build(sourcesDir: File, outputDir: File, dependencies: List<TestCompilationArtifact.KLIB>): T
|
||||
|
||||
fun build(): T {
|
||||
val targetSrc = buildDir.resolve(targetSrc)
|
||||
targetSrc.deleteRecursively()
|
||||
targetSrc.mkdirs()
|
||||
val outputDir = if (outputDir == "") buildDir else buildDir.resolve(outputDir)
|
||||
sources.forEach {
|
||||
val source = rootDir.resolve(it.first)
|
||||
val target = targetSrc.resolve(it.second)
|
||||
target.mkdirs()
|
||||
if (source.isFile)
|
||||
source.copyTo(target, true)
|
||||
else
|
||||
source.copyRecursively(target, true)
|
||||
}
|
||||
return build(targetSrc, outputDir, dependencies)
|
||||
}
|
||||
}
|
||||
|
||||
internal class LibraryBuilder(
|
||||
test: AbstractNativeSimpleTest,
|
||||
rootDir: File,
|
||||
targetSrc: String,
|
||||
dependencies: List<TestCompilationArtifact.KLIB>
|
||||
) : ArtifactBuilder<TestCompilationArtifact.KLIB>(test, rootDir, targetSrc, dependencies) {
|
||||
var libraryVersion: String? = null
|
||||
|
||||
override fun build(sourcesDir: File, outputDir: File, dependencies: List<TestCompilationArtifact.KLIB>) =
|
||||
test.compileToLibrary(
|
||||
sourcesDir,
|
||||
outputDir,
|
||||
freeCompilerArgs = libraryVersion?.let { TestCompilerArgs(listOf("-library-version=$it")) } ?: TestCompilerArgs.EMPTY,
|
||||
dependencies
|
||||
)
|
||||
}
|
||||
|
||||
internal class ExecutableBuilder(
|
||||
test: AbstractNativeSimpleTest,
|
||||
rootDir: File,
|
||||
targetSrc: String,
|
||||
dependencies: List<TestCompilationArtifact.KLIB>
|
||||
) : ArtifactBuilder<CompiledExecutable>(test, rootDir, targetSrc, dependencies) {
|
||||
private val freeCompilerArgs = mutableListOf<String>()
|
||||
|
||||
operator fun String.unaryPlus() {
|
||||
freeCompilerArgs.add(this)
|
||||
}
|
||||
|
||||
override fun build(sourcesDir: File, outputDir: File, dependencies: List<TestCompilationArtifact.KLIB>) =
|
||||
test.compileToExecutable(
|
||||
sourcesDir,
|
||||
freeCompilerArgs = if (freeCompilerArgs.isEmpty()) TestCompilerArgs.EMPTY else TestCompilerArgs(freeCompilerArgs),
|
||||
dependencies
|
||||
)
|
||||
}
|
||||
|
||||
internal val AbstractNativeSimpleTest.buildDir: File get() = testRunSettings.get<SimpleTestDirectories>().testBuildDir
|
||||
|
||||
internal fun TestCompilationArtifact.KLIB.asLibraryDependency() =
|
||||
@@ -54,19 +132,42 @@ internal fun AbstractNativeSimpleTest.compileToLibrary(
|
||||
sourcesDir: File,
|
||||
outputDir: File,
|
||||
vararg dependencies: TestCompilationArtifact.KLIB
|
||||
): TestCompilationArtifact.KLIB = compileToLibrary(sourcesDir, outputDir, TestCompilerArgs.EMPTY, dependencies.asList())
|
||||
|
||||
internal fun AbstractNativeSimpleTest.compileToLibrary(
|
||||
sourcesDir: File,
|
||||
outputDir: File,
|
||||
freeCompilerArgs: TestCompilerArgs,
|
||||
dependencies: List<TestCompilationArtifact.KLIB>
|
||||
): TestCompilationArtifact.KLIB {
|
||||
val testCase: TestCase = generateTestCaseWithSingleModule(sourcesDir)
|
||||
val testCase: TestCase = generateTestCaseWithSingleModule(sourcesDir, freeCompilerArgs)
|
||||
val compilationResult = compileToLibrary(testCase, outputDir, dependencies.map { it.asLibraryDependency() })
|
||||
return compilationResult.resultingArtifact
|
||||
}
|
||||
|
||||
internal class CompiledExecutable(
|
||||
val testCase: TestCase,
|
||||
val compilationResult: TestCompilationResult.Success<out TestCompilationArtifact.Executable>
|
||||
) {
|
||||
val executableFile: File get() = compilationResult.resultingArtifact.executableFile
|
||||
|
||||
val testExecutable by lazy { TestExecutable.fromCompilationResult(testCase, compilationResult) }
|
||||
}
|
||||
|
||||
internal fun AbstractNativeSimpleTest.compileToExecutable(
|
||||
sourcesDir: File,
|
||||
freeCompilerArgs: TestCompilerArgs,
|
||||
vararg dependencies: TestCompilationArtifact.KLIB
|
||||
): TestCompilationResult<out TestCompilationArtifact.Executable> {
|
||||
) = compileToExecutable(sourcesDir, freeCompilerArgs, dependencies.asList())
|
||||
|
||||
internal fun AbstractNativeSimpleTest.compileToExecutable(
|
||||
sourcesDir: File,
|
||||
freeCompilerArgs: TestCompilerArgs,
|
||||
dependencies: List<TestCompilationArtifact.KLIB>
|
||||
): CompiledExecutable {
|
||||
val testCase: TestCase = generateTestCaseWithSingleModule(sourcesDir, freeCompilerArgs)
|
||||
return compileToExecutable(testCase, dependencies.map { it.asLibraryDependency() })
|
||||
val compilationResult = compileToExecutable(testCase, dependencies.map { it.asLibraryDependency() })
|
||||
return CompiledExecutable(testCase, compilationResult.assertSuccess())
|
||||
}
|
||||
|
||||
internal fun AbstractNativeSimpleTest.compileToExecutable(testCase: TestCase, vararg dependencies: TestCompilationDependency<*>) =
|
||||
|
||||
Reference in New Issue
Block a user