From e8b1fc3dee2e4d0c03923a2e38cb939f62dbada4 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Wed, 28 Jun 2017 19:19:15 +0700 Subject: [PATCH] gradle-plugin: Add test infrastructure --- .../kotlin-native-gradle-plugin/build.gradle | 42 +++++- .../src/integrationTest/groovy/Specs.groovy | 134 ++++++++++++++++++ 2 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 tools/kotlin-native-gradle-plugin/src/integrationTest/groovy/Specs.groovy diff --git a/tools/kotlin-native-gradle-plugin/build.gradle b/tools/kotlin-native-gradle-plugin/build.gradle index 835f6520588..08c071e27fd 100644 --- a/tools/kotlin-native-gradle-plugin/build.gradle +++ b/tools/kotlin-native-gradle-plugin/build.gradle @@ -14,11 +14,12 @@ buildscript { classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' } } - apply plugin: 'java' apply plugin: 'kotlin' +apply plugin: 'groovy' apply plugin: 'maven-publish' apply plugin: 'com.jfrog.bintray' +apply plugin: 'java-gradle-plugin' group = 'org.jetbrains.kotlin' version = konanVersion @@ -44,16 +45,53 @@ allprojects { repositories { mavenCentral() + jcenter() } evaluationDependsOn(':tools:helpers') + +sourceSets { + integrationTest { + groovy.srcDir file('src/integrationTest/groovy') + + compileClasspath += sourceSets.main.output + compileClasspath += configurations.integrationTestCompile + compileClasspath += configurations.testCompile + runtimeClasspath += output + compileClasspath + } +} + +gradlePlugin { + testSourceSets sourceSets.integrationTest +} + dependencies { compile project(':shared') compile project(':tools:helpers') compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile gradleApi() + + integrationTestCompile gradleTestKit() + integrationTestCompile 'junit:junit:4.12' + integrationTestCompile('org.spockframework:spock-core:1.1-groovy-2.4') { + exclude module: 'groovy-all' + } + + // integrationTestCompile 'com.netflix.nebula:nebula-test:6.0.1' + // testCompile 'com.netflix.nebula:nebula-test:6.0.1' } +task integrationTest(type: Test) { + dependsOn(test) + testLogging.showStandardStreams = true + testClassesDir = sourceSets.integrationTest.output.classesDir + classpath = sourceSets.integrationTest.runtimeClasspath + systemProperty("konan.home", rootProject.file('dist')) + systemProperty("konan.root", rootProject.projectDir) +} + +check.dependsOn integrationTest + jar { dependsOn(':tools:helpers:jar') from (rootProject.findProject(':tools:helpers').sourceSets.main.output) @@ -95,4 +133,4 @@ bintray { override = project.hasProperty("override") } publications = ['gradlePlugin'] -} +} \ No newline at end of file diff --git a/tools/kotlin-native-gradle-plugin/src/integrationTest/groovy/Specs.groovy b/tools/kotlin-native-gradle-plugin/src/integrationTest/groovy/Specs.groovy new file mode 100644 index 00000000000..6b0ddde9a19 --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/integrationTest/groovy/Specs.groovy @@ -0,0 +1,134 @@ +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +class KonanProjectGenerator { + static void generateBuildFile(File buildFile) { + buildFile.write(""" + plugins { id 'konan' } + + konanInterop { + stdio { } + } + + konanArtifacts { + main { useInterop 'stdio' } + } + """.stripIndent() + ) + } + + static void generateSrcFile(File srcFile) { + srcFile.write(""" + import kotlinx.cinterop.* + import stdio.* + + fun main(args: Array) { + printf("%d\\n", 42) + } + """.stripIndent() + ) + } + + static void generateDefFile(File defFile) { + defFile.write(""" + headers = stdio.h stdlib.h string.h + excludeDependentModules.osx = true + """.stripIndent() + ) + } + + static void generatePropertiesFile(File propertiesFile, String konanHome) { + propertiesFile.write("konan.home=$konanHome") + } +} + +class IncrementalSpecification extends Specification { + + @Rule + TemporaryFolder projectDir = new TemporaryFolder() + + File buildFile + File srcFile + File defFile + File propertiesFile + + String konanHome = System.getProperty("konan.home") ?: { throw new IllegalStateException("konan.home isn't specified") }() + String konanRoot = System.getProperty("konan.root") ?: { throw new IllegalStateException("konan.root isn't specified") }() + + def interopTasks = [":genStdioInteropStubs", ":compileStdioInteropStubs"].toSet() + def compilationTasks = [":compileKonanMain", ":compileKonan", ":build"].toSet() + + def buildingTasks = interopTasks + compilationTasks + def downloadTask = ":downloadKonanCompiler" + def konanTasks = buildingTasks + downloadTask + + def setup() { + buildFile = projectDir.newFile("build.gradle") + projectDir.newFolder("src", "main", "kotlin") + projectDir.newFolder("src", "main", "c_interop") + srcFile = projectDir.newFile("src/main/kotlin/main.kt") + defFile = projectDir.newFile("src/main/c_interop/stdio.def") + propertiesFile = projectDir.newFile("gradle.properties") + + KonanProjectGenerator.generateBuildFile(buildFile) + KonanProjectGenerator.generateDefFile(defFile) + KonanProjectGenerator.generateSrcFile(srcFile) + KonanProjectGenerator.generatePropertiesFile(propertiesFile, konanHome) + } + + def 'Compilation is up-to-date if there is no changes'() { + when: + def runner = GradleRunner.create() + .withProjectDir(projectDir.root) + .withArguments('build') + .withPluginClasspath() + def result = runner.build() + def upToDateResult = runner.build() + + then: + result.tasks.collect { it.path }.containsAll(buildingTasks) + result.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) + upToDateResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(buildingTasks) + result.task(downloadTask).outcome == TaskOutcome.SUCCESS + upToDateResult.task(downloadTask).outcome == TaskOutcome.SUCCESS + } + + def 'Source change should cause recompilation'() { + when: + def runner = GradleRunner.create() + .withProjectDir(projectDir.root) + .withArguments('build') + .withPluginClasspath() + def result = runner.build() + srcFile.append("\n // Some change in the source file") + def secondResult = runner.build() + + then: + result.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) + secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(compilationTasks) + secondResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(interopTasks) + } + + def 'Def-file change should cause recompilation'() { + when: + def runner = GradleRunner.create() + .withProjectDir(projectDir.root) + .withArguments('build') + .withPluginClasspath() + def result = runner.build() + defFile.append("\n # Some change in the def-file") + def secondResult = runner.build() + + then: + result.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) + secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) + } + + // TODO: Add checks for artifact/interop parameters. + +} + +