gradle-plugin: Improve test harness
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ class DefaultSpecification extends BaseKonanSpecification {
|
||||
plugins { id 'konan' }
|
||||
konanArtifacts {
|
||||
interop('stdio')
|
||||
program('main')
|
||||
library('main')
|
||||
}
|
||||
""".stripIndent())
|
||||
it.generateDefFile("stdio.def", "")
|
||||
|
||||
+19
-27
@@ -15,8 +15,8 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
return new Tuple(project, firstResult, secondResult)
|
||||
}
|
||||
|
||||
Tuple buildTwice(Closure change) {
|
||||
return buildTwice(KonanProject.createWithInterop(projectDirectory), change)
|
||||
Tuple buildTwice(ArtifactType mainArtifactType = ArtifactType.LIBRARY, Closure change) {
|
||||
return buildTwice(KonanProject.createWithInterop(projectDirectory, mainArtifactType), change)
|
||||
}
|
||||
|
||||
Boolean noRecompilationHappened(KonanProject project, BuildResult firstResult, BuildResult secondResult) {
|
||||
@@ -74,14 +74,6 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
recompilationAndInteropProcessingHappened(*results)
|
||||
}
|
||||
|
||||
def 'Compilation is up-to-date if there is no changes in empty project'() {
|
||||
when:
|
||||
def results = buildTwice {}
|
||||
|
||||
then:
|
||||
noRecompilationHappened(*results)
|
||||
}
|
||||
|
||||
@Unroll("#parameter change for a compilation task should cause only recompilation")
|
||||
def 'Parameter changes should cause only recompilaton'() {
|
||||
when:
|
||||
@@ -98,24 +90,22 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
"baseDir" | "'build/new/outputDir'"
|
||||
"enableOptimizations" | "true"
|
||||
"linkerOpts" | "'--help'"
|
||||
"languageVersion" | "'1.2'"
|
||||
"apiVersion" | "'1.0'"
|
||||
"enableAssertions" | "true"
|
||||
"enableDebug" | "true"
|
||||
"outputName" | "'foo'"
|
||||
"artifactName" | "'foo'"
|
||||
"extraOpts" | "'--time'"
|
||||
"noDefaultLibs" | "true"
|
||||
}
|
||||
|
||||
def 'inputFiles change for a compilation task should cause only recompilation'() {
|
||||
def 'srcFiles change for a compilation task should cause only recompilation'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory) { KonanProject it ->
|
||||
def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) { KonanProject it ->
|
||||
it.generateSrcFile(["src", "foo", "kotlin"], 'bar.kt', """
|
||||
fun main(args: Array<String>) { println("Hello!") }
|
||||
""".stripIndent())
|
||||
}
|
||||
def results = buildTwice(project) { KonanProject it ->
|
||||
it.addSetting("main", "inputFiles", "project.fileTree('src/foo/kotlin')")
|
||||
it.addSetting("main", "srcFiles", "project.fileTree('src/foo/kotlin')")
|
||||
}
|
||||
|
||||
then:
|
||||
@@ -124,12 +114,12 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
|
||||
def 'Library change for a compilation task should cause only recompilation'() {
|
||||
when:
|
||||
def project = KonanProject.create(projectDirectory) { KonanProject it ->
|
||||
def project = KonanProject.create(projectDirectory, ArtifactType.LIBRARY) { KonanProject it ->
|
||||
it.generateSrcFile(["src", "lib", "kotlin"], "lib.kt", "fun bar() { println(\"Hello!\") }")
|
||||
it.buildFile.append("""
|
||||
konanArtifacts {
|
||||
library('lib') {
|
||||
inputFiles fileTree('src/lib/kotlin')
|
||||
srcFiles fileTree('src/lib/kotlin')
|
||||
}
|
||||
}
|
||||
""".stripIndent())
|
||||
@@ -142,14 +132,14 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
onlyRecompilationHappened(*results)
|
||||
}
|
||||
|
||||
def 'Library changes should cause only recompilaton'() {
|
||||
def 'Native library change for a compilation task should cause only recompilaton'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory) { KonanProject it ->
|
||||
def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) { KonanProject it ->
|
||||
it.generateSrcFile(["src", "lib", "kotlin"], "lib.kt", "fun bar() { println(\"Hello!\") }")
|
||||
it.buildFile.append("""
|
||||
konanArtifacts {
|
||||
bitcode('lib') {
|
||||
inputFiles fileTree('src/lib/kotlin')
|
||||
srcFiles fileTree('src/lib/kotlin')
|
||||
}
|
||||
}
|
||||
""".stripIndent())
|
||||
@@ -176,7 +166,7 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
|
||||
where:
|
||||
parameter | value
|
||||
"pkg" | "'org.sample'"
|
||||
"packageName" | "'org.sample'"
|
||||
"compilerOpts" | "'-g'"
|
||||
"linkerOpts" | "'--help'"
|
||||
"includeDirs" | "'src'"
|
||||
@@ -186,7 +176,7 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
|
||||
def 'defFile change for an interop task should cause recompilation and interop reprocessing'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory)
|
||||
def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY)
|
||||
def defFile = project.generateDefFile("foo.def", "#some content")
|
||||
def results = buildTwice(project) { KonanProject it ->
|
||||
it.addSetting("stdio", "defFile", defFile)
|
||||
@@ -198,7 +188,7 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
|
||||
def 'header change for an interop task should cause recompilation and interop reprocessing'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory)
|
||||
def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY)
|
||||
def header = project.generateSrcFile('header.h', "#define CONST 1")
|
||||
def results = buildTwice(project) { KonanProject it ->
|
||||
it.addSetting("stdio", "headers", header)
|
||||
@@ -210,12 +200,12 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
|
||||
def 'link change for an interop task should cause recompilation and interop reprocessing'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory) { KonanProject it ->
|
||||
def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) { KonanProject it ->
|
||||
it.generateSrcFile(["src", "lib", "kotlin"], 'lib.kt', 'fun foo() { println(42) }')
|
||||
it.buildFile.append("""
|
||||
konanArtifacts {
|
||||
bitcode('lib') {
|
||||
inputFiles fileTree('src/lib/kotlin')
|
||||
srcFiles fileTree('src/lib/kotlin')
|
||||
}
|
||||
}
|
||||
""".stripIndent())
|
||||
@@ -231,7 +221,7 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
|
||||
def 'konan version change should cause recompilation and interop reprocessing'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory) { KonanProject it ->
|
||||
def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) { KonanProject it ->
|
||||
it.propertiesFile.append("konan.version=0.3\n")
|
||||
}
|
||||
def results = buildTwice(project) { KonanProject it ->
|
||||
@@ -243,5 +233,7 @@ class IncrementalSpecification extends BaseKonanSpecification {
|
||||
recompilationAndInteropProcessingHappened(*results)
|
||||
}
|
||||
|
||||
// TODO: Add incremental tests for the 'libraries' block.
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
+51
-31
@@ -8,6 +8,17 @@ import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
enum ArtifactType {
|
||||
PROGRAM("program"),
|
||||
LIBRARY("library"),
|
||||
BITCODE("bitcode"),
|
||||
INTEROP("interop")
|
||||
|
||||
String type
|
||||
ArtifactType(String type) { this.type = type }
|
||||
String toString() { return type }
|
||||
}
|
||||
|
||||
class KonanProject {
|
||||
|
||||
static String DEFAULT_ARTIFACT_NAME = 'main'
|
||||
@@ -37,12 +48,6 @@ class KonanProject {
|
||||
List<String> getBuildingTasks() { return compilationTasks + interopTasks }
|
||||
List<String> getKonanTasks() { return getBuildingTasks() + downloadTask }
|
||||
|
||||
// TODO: Must be an enum.
|
||||
static String PROGRAM = "program"
|
||||
static String LIBRARY = "library"
|
||||
static String BITCODE = "bitcode"
|
||||
static String INTEROP = "interop"
|
||||
|
||||
static String DEFAULT_SRC_CONTENT = """
|
||||
fun main(args: Array<String>) {
|
||||
println(42)
|
||||
@@ -133,10 +138,10 @@ class KonanProject {
|
||||
*/
|
||||
File generateBuildFile() {
|
||||
def result = generateBuildFile("""
|
||||
plugins { id 'konan' }
|
||||
|
||||
konanTargets = [${targets.collect { "'$it'" }.join(", ")}]
|
||||
""".stripIndent()
|
||||
|plugins { id 'konan' }
|
||||
|
|
||||
|konan.targets = [${targets.collect { "'$it'" }.join(", ")}]
|
||||
""".stripMargin()
|
||||
)
|
||||
compilationTasks = [":compileKonan", ":build"]
|
||||
return result
|
||||
@@ -233,68 +238,83 @@ class KonanProject {
|
||||
}
|
||||
|
||||
/** Returns the path of compileKonan... task for the default artifact. */
|
||||
String defaultCompilationTask(String target = HOST) {
|
||||
static String defaultCompilationTask(String target = HOST) {
|
||||
return compilationTask(DEFAULT_ARTIFACT_NAME, target)
|
||||
}
|
||||
|
||||
String defaultInteropTask(String target = HOST) {
|
||||
static String defaultInteropTask(String target = HOST) {
|
||||
return compilationTask(DEFAULT_INTEROP_NAME, target)
|
||||
}
|
||||
|
||||
/** Returns the path of compileKonan... task for the artifact specified. */
|
||||
String compilationTask(String artifactName, String target = HOST) {
|
||||
static String compilationTask(String artifactName, String target = HOST) {
|
||||
return ":compileKonan${artifactName.capitalize()}${target.capitalize()}"
|
||||
}
|
||||
|
||||
String defaultCompilationConfig() {
|
||||
static String defaultCompilationConfig() {
|
||||
return artifactConfig(DEFAULT_ARTIFACT_NAME)
|
||||
}
|
||||
|
||||
String defaultInteropConfig() {
|
||||
static String defaultInteropConfig() {
|
||||
return artifactConfig(DEFAULT_INTEROP_NAME)
|
||||
}
|
||||
|
||||
String artifactConfig(String artifactName) {
|
||||
static String artifactConfig(String artifactName) {
|
||||
return "konanArtifacts.$artifactName"
|
||||
}
|
||||
|
||||
void addCompilerArtifact(String name, String content = "", String type = PROGRAM) {
|
||||
static String outputAccessCode(String artifact, String target = HOST) {
|
||||
return "${artifactConfig(artifact)}.${target}.artifact"
|
||||
}
|
||||
|
||||
void addCompilerArtifact(String name, String content = "", ArtifactType type = ArtifactType.PROGRAM) {
|
||||
def newTasks = targets.collect { compilationTask(name, it) } + ":compileKonan${name.capitalize()}".toString()
|
||||
if (type == INTEROP) {
|
||||
buildFile.append("konanArtifacts { $type('$name') }\n")
|
||||
if (type == ArtifactType.INTEROP) {
|
||||
defFiles += generateDefFile("${name}.def", content)
|
||||
interopTasks += newTasks
|
||||
} else {
|
||||
srcFiles += generateSrcFile(projectPath.resolve("src/$name/kotlin"), "source.kt", content)
|
||||
def src = generateSrcFile(projectPath.resolve("src/$name/kotlin"), "source.kt", content)
|
||||
addSetting(name, "srcFiles", src)
|
||||
srcFiles += src
|
||||
compilationTasks += newTasks
|
||||
}
|
||||
buildFile.append("konanArtifacts { $type('$name') }\n")
|
||||
|
||||
}
|
||||
|
||||
/** Creates a project with default build and source files. */
|
||||
static KonanProject create(File projectDir, List<String> targets = [HOST]) {
|
||||
static KonanProject create(File projectDir,
|
||||
ArtifactType artifactType = ArtifactType.PROGRAM,
|
||||
List<String> targets = [HOST]) {
|
||||
return createEmpty(projectDir, targets) { KonanProject p ->
|
||||
p.addCompilerArtifact(DEFAULT_ARTIFACT_NAME, DEFAULT_SRC_CONTENT)
|
||||
p.addCompilerArtifact(DEFAULT_ARTIFACT_NAME, DEFAULT_SRC_CONTENT, artifactType)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add 'type parameter'
|
||||
|
||||
/** Creates a project with default build and source files. */
|
||||
static KonanProject create(File projectDir, List<String> targets = [HOST], Closure config) {
|
||||
def result = create(projectDir, targets)
|
||||
static KonanProject create(File projectDir,
|
||||
ArtifactType artifactType = ArtifactType.PROGRAM,
|
||||
List<String> targets = [HOST],
|
||||
Closure config) {
|
||||
def result = create(projectDir, artifactType, targets)
|
||||
config(result)
|
||||
return result
|
||||
}
|
||||
|
||||
static KonanProject createWithInterop(File projectDir, List<String> targets = [HOST]) {
|
||||
return create(projectDir, targets) { KonanProject p ->
|
||||
p.addCompilerArtifact(DEFAULT_INTEROP_NAME, DEFAULT_DEF_CONTENT, INTEROP)
|
||||
static KonanProject createWithInterop(File projectDir,
|
||||
ArtifactType mainArtifactType = ArtifactType.PROGRAM,
|
||||
List<String> targets = [HOST]) {
|
||||
return create(projectDir, mainArtifactType, targets) { KonanProject p ->
|
||||
p.addCompilerArtifact(DEFAULT_INTEROP_NAME, DEFAULT_DEF_CONTENT, ArtifactType.INTEROP)
|
||||
p.addLibraryToArtifact()
|
||||
}
|
||||
}
|
||||
|
||||
static KonanProject createWithInterop(File projectDir, List<String> targets = [HOST], Closure config) {
|
||||
def result = createWithInterop(projectDir, targets)
|
||||
static KonanProject createWithInterop(File projectDir,
|
||||
ArtifactType mainArtifactType = ArtifactType.PROGRAM,
|
||||
List<String> targets = [HOST],
|
||||
Closure config) {
|
||||
def result = createWithInterop(projectDir, mainArtifactType, targets)
|
||||
config(result)
|
||||
return result
|
||||
}
|
||||
|
||||
+12
-17
@@ -1,8 +1,6 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.test
|
||||
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.TargetManager
|
||||
|
||||
class PathSpecification extends BaseKonanSpecification {
|
||||
|
||||
@@ -13,10 +11,9 @@ class PathSpecification extends BaseKonanSpecification {
|
||||
def 'Plugin should create all necessary directories'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory)
|
||||
project.addCompilerArtifact("lib", "fun foo() {}", KonanProject.LIBRARY)
|
||||
project.addCompilerArtifact("bit", "fun bar() {}", KonanProject.BITCODE)
|
||||
println(project.buildFile.text)
|
||||
def result = project.createRunner().withArguments('build').build()
|
||||
project.addCompilerArtifact("lib", "fun foo() {}", ArtifactType.LIBRARY)
|
||||
project.addCompilerArtifact("bit", "fun bar() {}", ArtifactType.BITCODE)
|
||||
project.createRunner().withArguments('build').build()
|
||||
|
||||
then:
|
||||
project.konanBuildDir.toPath().resolve("bin/$KonanProject.HOST").toFile().listFiles().findAll {
|
||||
@@ -31,7 +28,7 @@ class PathSpecification extends BaseKonanSpecification {
|
||||
def 'Plugin should stop building if the compiler classpath is empty'() {
|
||||
when:
|
||||
def project = KonanProject.create(projectDirectory)
|
||||
project.propertiesFile.write("konan.home=${projectDirectory.canonicalPath}}")
|
||||
project.propertiesFile.write("konan.home=fakepath")
|
||||
def result = project.createRunner().withArguments('build').buildAndFail()
|
||||
|
||||
then:
|
||||
@@ -41,7 +38,7 @@ class PathSpecification extends BaseKonanSpecification {
|
||||
def 'Plugin should stop building if the stub generator classpath is empty'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory)
|
||||
project.propertiesFile.write("konan.home=${projectDirectory.canonicalPath}}")
|
||||
project.propertiesFile.write("konan.home=fakepath")
|
||||
def result = project.createRunner().withArguments('build').buildAndFail()
|
||||
|
||||
then:
|
||||
@@ -51,26 +48,24 @@ class PathSpecification extends BaseKonanSpecification {
|
||||
def 'Plugin should remove custom output directories'() {
|
||||
when:
|
||||
def customOutputDir = projectDirectory.toPath().resolve("foo").toFile()
|
||||
def project = KonanProject.create(projectDirectory) { KonanProject it ->
|
||||
def project = KonanProject.create(projectDirectory, ArtifactType.LIBRARY) { KonanProject it ->
|
||||
it.addSetting("baseDir", customOutputDir)
|
||||
}
|
||||
|
||||
def res1 = project.createRunner().withArguments("build").build()
|
||||
def artifactExistsAfterBuild = customOutputDir.toPath()
|
||||
.resolve("${KonanProject.HOST}").toFile()
|
||||
.listFiles()
|
||||
.findAll { it.name.matches("^${KonanProject.DEFAULT_ARTIFACT_NAME}\\.[^.]+") }.size() > 0
|
||||
.resolve("${KonanProject.HOST}/${KonanProject.DEFAULT_ARTIFACT_NAME}.klib").toFile()
|
||||
.exists()
|
||||
|
||||
def res2 = project.createRunner().withArguments("clean").build()
|
||||
def artifactDoesntNotExistAfterClean = customOutputDir.toPath()
|
||||
.resolve("${KonanProject.HOST}").toFile()
|
||||
.listFiles()
|
||||
.findAll { it.name.matches("^${KonanProject.DEFAULT_ARTIFACT_NAME}\\.[^.]+") }.isEmpty()
|
||||
def artifactExistsAfterClean = customOutputDir.toPath()
|
||||
.resolve("${KonanProject.HOST}/${KonanProject.DEFAULT_ARTIFACT_NAME}.klib").toFile()
|
||||
.exists()
|
||||
|
||||
then:
|
||||
res1.taskPaths(TaskOutcome.SUCCESS).containsAll(project.buildingTasks)
|
||||
res2.taskPaths(TaskOutcome.SUCCESS).contains(":clean")
|
||||
artifactExistsAfterBuild
|
||||
artifactDoesntNotExistAfterClean
|
||||
!artifactExistsAfterClean
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ class RegressionSpecification extends BaseKonanSpecification {
|
||||
fun main(args: Array<String>) {
|
||||
foo()
|
||||
}
|
||||
""", KonanProject.PROGRAM)
|
||||
""", ArtifactType.PROGRAM)
|
||||
}
|
||||
def result = project.createRunner().withArguments('build').buildAndFail()
|
||||
|
||||
|
||||
+4
-9
@@ -3,13 +3,11 @@ package org.jetbrains.kotlin.gradle.plugin.test
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
|
||||
import java.nio.file.Paths
|
||||
|
||||
class TaskSpecification extends BaseKonanSpecification {
|
||||
|
||||
def 'Configs should allow user to add dependencies to them'() {
|
||||
when:
|
||||
def project = KonanProject.createWithInterop(projectDirectory)
|
||||
def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY)
|
||||
project.buildFile.append("""
|
||||
task beforeInterop(type: DefaultTask) { doLast { println("Before Interop") } }
|
||||
task beforeCompilation(type: DefaultTask) { doLast { println("Before compilation") } }
|
||||
@@ -27,18 +25,16 @@ class TaskSpecification extends BaseKonanSpecification {
|
||||
|
||||
def 'Compiler should print time measurements if measureTime flag is set'() {
|
||||
when:
|
||||
def project = KonanProject.create(projectDirectory)
|
||||
def project = KonanProject.create(projectDirectory, ArtifactType.LIBRARY)
|
||||
project.addSetting("measureTime", "true")
|
||||
def result = project.createRunner().withArguments('build').build()
|
||||
|
||||
then:
|
||||
result.output.findAll(~/FRONTEND:\s+\d+\s+msec/).size() == 1
|
||||
result.output.findAll(~/BACKEND:\s+\d+\s+msec/).size() == 1
|
||||
result.output.findAll(~/LINK_STAGE:\s+\d+\s+msec/).size() == 1
|
||||
}
|
||||
|
||||
BuildResult failOnPropertyAccess(String property) {
|
||||
def project = KonanProject.createWithInterop(projectDirectory)
|
||||
BuildResult failOnPropertyAccess(KonanProject project, String property) {
|
||||
project.buildFile.append("""
|
||||
task testTask(type: DefaultTask) {
|
||||
doLast {
|
||||
@@ -49,8 +45,7 @@ class TaskSpecification extends BaseKonanSpecification {
|
||||
return project.createRunner().withArguments("testTask").buildAndFail()
|
||||
}
|
||||
|
||||
BuildResult failOnTaskAccess(String task) {
|
||||
def project = KonanProject.createWithInterop(projectDirectory)
|
||||
BuildResult failOnTaskAccess(KonanProject project, String task) {
|
||||
project.buildFile.append("""
|
||||
task testTask(type: DefaultTask) {
|
||||
dependsOn $task
|
||||
|
||||
Reference in New Issue
Block a user