Scripting: code coverage Added a way to collect code coverage from scripting autotest in isolation ^OSIP-1298
diff --git a/compiler/test-coverage/scripting/build.gradle.kts b/compiler/test-coverage/scripting/build.gradle.kts new file mode 100644 index 0000000..c824961 --- /dev/null +++ b/compiler/test-coverage/scripting/build.gradle.kts
@@ -0,0 +1,214 @@ +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.api.tasks.testing.Test +import org.gradle.testing.jacoco.plugins.JacocoTaskExtension +import org.gradle.testing.jacoco.tasks.JacocoReport + +plugins { + id("base") + id("jacoco") +} + +description = "Aggregated JaCoCo coverage for compiler code exercised by Kotlin scripting tests" + +jacoco { + toolVersion = libs.versions.jacoco.get() +} + +val scriptingTestProjects = listOf( + ":plugins:scripting:scripting-tests", + ":kotlin-scripting-common", + ":kotlin-scripting-jvm", + ":kotlin-scripting-jvm-host-test", + ":kotlin-scripting-dependencies", + ":kotlin-scripting-dependencies-maven", + ":kotlin-scripting-jsr223-test", + ":kotlin-main-kts", + ":kotlin-main-kts-test", + ":examples:scripting-jvm-simple-script-host", + ":examples:scripting-jvm-maven-deps-host", + ":examples:scripting-jvm-embeddable-host", + ":examples:scripting-jsr223-daemon", + ":examples:scripting-jsr223-bta", +) + +// These projects use Kotlin's custom projectTests/Test tasks rather than published +// JVM-test-suite coverage variants. Evaluate them first so the task collection below +// sees every custom Test task, then apply JaCoCo directly and consume each task's +// configured destination file instead of relying on jacocoAggregation resolution. +scriptingTestProjects.forEach { evaluationDependsOn(it) } + +val scriptingExecutionData = objects.fileCollection() +scriptingTestProjects.forEach { path -> + val producer = project(path) + producer.pluginManager.apply("jacoco") + producer.tasks.withType<Test>().configureEach { + extensions.configure<JacocoTaskExtension> { + isEnabled = true + scriptingExecutionData.from(destinationFile) + } + } +} + + +// Class/source providers: these are report inputs only, never execution-data producers. +val reportClassScopeProjects = listOf( + // The compiler-side scripting implementation is here, not in scripting-tests. + ":kotlin-scripting-compiler", + ":kotlin-scripting-compiler-impl", + ":kotlin-scripting-common", + ":kotlin-scripting-jvm", + ":kotlin-scripting-dependencies", + ":kotlin-scripting-dependencies-maven", + ":kotlin-main-kts", + ":examples:scripting-jvm-simple-script-host", + ":examples:scripting-jvm-maven-deps-host", + ":examples:scripting-jvm-embeddable-host", + ":examples:scripting-jsr223-daemon", + ":examples:scripting-jsr223-bta", + ":compiler", + ":compiler:util", + ":compiler:config", + ":compiler:config.jvm", + ":compiler:arguments.common", + ":compiler:arguments", + ":compiler:container", + ":compiler:resolution.common", + ":compiler:resolution.common.js", + ":compiler:resolution.common.jvm", + ":compiler:resolution", + ":compiler:serialization.common", + ":compiler:serialization", + ":compiler:psi:psi-api", + ":compiler:psi:psi-impl", + ":compiler:psi:psi-utils", + ":compiler:psi:psi-frontend-utils", + ":compiler:psi:parser", + ":compiler:multiplatform-parsing", + ":compiler:frontend", + ":compiler:frontend.common", + ":compiler:frontend.common-psi", + ":compiler:frontend.java", + ":compiler:frontend.common.jvm", + ":compiler:frontend:cfg", + ":compiler:ir.tree", + ":compiler:ir.psi2ir", + ":compiler:ir.objcinterop", + ":compiler:ir.backend.common", + ":compiler:ir.backend.native", + ":compiler:ir.actualization", + ":compiler:ir.serialization.common", + ":compiler:ir.serialization.jvm", + ":compiler:ir.serialization.js", + ":compiler:ir.serialization.native", + ":compiler:ir.serialization.jklib", + ":compiler:ir.inline", + ":compiler:ir.validation", + ":compiler:backend", + ":compiler:backend.common.jvm", + ":compiler:backend.jvm", + ":compiler:backend.jvm.lower", + ":compiler:backend.jvm.codegen", + ":compiler:backend.jvm.entrypoint", + ":compiler:backend.js", + ":compiler:backend.wasm", + ":compiler:plugin-api", + ":compiler:java-direct", + ":compiler:cli-base", + ":compiler:cli", + ":compiler:cli-jvm", + ":compiler:cli-js", + ":compiler:cli-jklib", + ":compiler:cli-metadata", + ":compiler:cli:cli-native-klib", + ":compiler:incremental-compilation-impl", + ":compiler:fir:cones", + ":compiler:fir:tree", + ":compiler:fir:semantics.api", + ":compiler:fir:resolve", + ":compiler:fir:plugin.api", + ":compiler:fir:fir-serialization", + ":compiler:fir:fir-deserialization", + ":compiler:fir:fir-jvm", + ":compiler:fir:fir-native", + ":compiler:fir:checkers:checkers.api", + ":compiler:fir:checkers:checkers.common", + ":compiler:fir:checkers:checkers.jvm", + ":compiler:fir:checkers:checkers.js", + ":compiler:fir:checkers:checkers.native", + ":compiler:fir:checkers:checkers.wasm", + ":compiler:fir:checkers:checkers.web.common", + ":compiler:fir:diagnostic-renderers", + ":compiler:fir:entrypoint", + ":compiler:fir:raw-fir:raw-fir.common", + ":compiler:fir:fir2ir", + ":compiler:fir:fir2ir:jvm-backend", + ":core:names", + ":core:language.model", + ":core:language.targets", + ":core:language.targets.jvm", + ":core:language.version-settings", + ":core:compiler.common", + ":core:compiler.common.jvm", + ":core:compiler.common.js", + ":core:compiler.common.native", + ":core:compiler.common.wasm", + ":core:compiler.common.web", + ":core:descriptors", + ":core:descriptors.jvm", + ":core:deserialization", + ":core:deserialization.common", + ":core:deserialization.common.jvm", + ":core:descriptors.runtime", + ":core:metadata", + ":core:metadata.jvm", + ":core:util.runtime", +) + +val reportJvmClassScopeProjects = reportClassScopeProjects.filter { path -> + val candidate = project(path) + candidate.extensions.findByType<SourceSetContainer>()?.findByName("main") != null && + candidate.tasks.findByName("classes") != null +} + +val reportClassDirectories = objects.fileCollection() +val reportSourceDirectories = objects.fileCollection() + +reportJvmClassScopeProjects.forEach { path -> + val mainSourceSet = project(path).extensions.getByType<SourceSetContainer>().findByName("main")!! + reportClassDirectories.from(mainSourceSet.output.classesDirs) + reportSourceDirectories.from(mainSourceSet.allSource.srcDirs) +} + +tasks.register<JacocoReport>("scriptingCoverageReport") { + group = "verification" + description = "Generates compiler-wide coverage from scripting tests only" + + // Run every scripting producer before evaluating the report's built-in + // "any execution data exists" predicate. + scriptingTestProjects.forEach { path -> + dependsOn(project(path).tasks.withType<Test>()) + } + executionData.setFrom(scriptingExecutionData) + + // Build class-only inputs. Test projects contribute execution data only. + dependsOn(reportJvmClassScopeProjects.map { "$it:classes" }) + classDirectories.setFrom( + reportClassDirectories.asFileTree.matching { + include( + // Compiler/plugin-side scripting implementation and JSR-223 integration. + "org/jetbrains/kotlin/**", + // Public scripting API/host implementations use this package root. + "kotlin/script/experimental/**" + ) + exclude("org/jetbrains/kotlin/util/vavr/VavrAdaptersKt.class") + } + ) + sourceDirectories.setFrom(reportSourceDirectories) + + reports { + html.required = true + xml.required = true + csv.required = false + } + +}
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index e63ed36..310070c 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml
@@ -2622,11 +2622,21 @@ <sha256 value="20be9853385bdfc65a5929643412d09243d14514304b89ba23a265158cc8792b" origin="Generated by Gradle"/> </artifact> </component> + <component group="org.jacoco" name="org.jacoco.agent" version="0.8.15"> + <artifact name="org.jacoco.agent-0.8.15.jar"> + <sha256 value="81607adaa5b03a687a04049dee6b07e9665708c3e6f7b0626892ca9659be587c" origin="Generated by Gradle"/> + </artifact> + </component> <component group="org.jacoco" name="org.jacoco.ant" version="0.8.14"> <artifact name="org.jacoco.ant-0.8.14.jar"> <sha256 value="9fff68954d5de3aad2bf838eaf886ed67d2c22a2d6c6f095548bade8c45caeae" origin="Generated by Gradle"/> </artifact> </component> + <component group="org.jacoco" name="org.jacoco.ant" version="0.8.15"> + <artifact name="org.jacoco.ant-0.8.15.jar"> + <sha256 value="54fb6af97c95352d7deeb49113d7ad63f190eaa8cc9ae8e068fdb2f2a6de009e" origin="Generated by Gradle"/> + </artifact> + </component> <component group="org.jacoco" name="org.jacoco.cli" version="0.8.14"> <artifact name="org.jacoco.cli-0.8.14.jar"> <sha256 value="12d5d78351c638efeea71ac840f6a5cf7bcff89001ddb05eb89f956d1079a2c6" origin="Generated by Gradle"/> @@ -2637,11 +2647,21 @@ <sha256 value="28abbf0eea5a08e4f24097f2fbac663ca17c341c25c3a04d90d6cd325943c995" origin="Generated by Gradle"/> </artifact> </component> + <component group="org.jacoco" name="org.jacoco.core" version="0.8.15"> + <artifact name="org.jacoco.core-0.8.15.jar"> + <sha256 value="ade1e0fdb4cd80d8537b57c6edb70a1360c47fdc518c20c65314517479bc4d0d" origin="Generated by Gradle"/> + </artifact> + </component> <component group="org.jacoco" name="org.jacoco.report" version="0.8.14"> <artifact name="org.jacoco.report-0.8.14.jar"> <sha256 value="a3e2026060ab8b8d5c650706406234bb4c033dfd5376afeb8b1666e8ed27c453" origin="Generated by Gradle"/> </artifact> </component> + <component group="org.jacoco" name="org.jacoco.report" version="0.8.15"> + <artifact name="org.jacoco.report-0.8.15.jar"> + <sha256 value="66a79e36edc77a1ebf6689e76a976e12ab4f1af515cbd09555840fba775714f4" origin="Generated by Gradle"/> + </artifact> + </component> <component group="org.javassist" name="javassist" version="3.28.0-GA"> <artifact name="javassist-3.28.0-GA.jar"> <sha256 value="57d0a9e9286f82f4eaa851125186997f811befce0e2060ff0a15a77f5a9dd9a7" origin="Generated by Gradle"/> @@ -4885,6 +4905,11 @@ <sha256 value="0df97574914aee92fd349d0cb4e00f3345d45b2c239e0bb50f0a90ead47888e0" origin="Generated by Gradle"/> </artifact> </component> + <component group="org.ow2.asm" name="asm" version="9.10.1"> + <artifact name="asm-9.10.1.jar"> + <sha256 value="ed825d10ab1399c8c0cb669e688cf0c8c82629b4c8399b58352b68e92ca10fcb" origin="Generated by Gradle"/> + </artifact> + </component> <component group="org.ow2.asm" name="asm" version="9.2"> <artifact name="asm-9.2.jar"> <sha256 value="b9d4fe4d71938df38839f0eca42aaaa64cf8b313d678da036f0cb3ca199b47f5" origin="Generated by Gradle"/> @@ -4925,6 +4950,11 @@ <sha256 value="6a15d28e8bd29ba4fd5bca4baf9b50e8fba2d7b51fbf78cfa0c875a7214c678b" origin="Generated by Gradle"/> </artifact> </component> + <component group="org.ow2.asm" name="asm-commons" version="9.10.1"> + <artifact name="asm-commons-9.10.1.jar"> + <sha256 value="6d0abefb7cbf972ea16edb37ec14835372505063a45f976ab7ea889ed9497895" origin="Generated by Gradle"/> + </artifact> + </component> <component group="org.ow2.asm" name="asm-commons" version="9.6"> <artifact name="asm-commons-9.6.jar"> <sha256 value="7aefd0d5c0901701c69f7513feda765fb6be33af2ce7aa17c5781fc87657c511" origin="Generated by Gradle"/> @@ -4940,6 +4970,11 @@ <sha256 value="db2f6f26150bbe7c126606b4a1151836bcc22a1e05a423b3585698bece995ff8" origin="Generated by Gradle"/> </artifact> </component> + <component group="org.ow2.asm" name="asm-tree" version="9.10.1"> + <artifact name="asm-tree-9.10.1.jar"> + <sha256 value="3dfb0d5b6a106cd40b5b250e39935fbf2f927f4477546a5369a3ac609cf0506b" origin="Generated by Gradle"/> + </artifact> + </component> <component group="org.ow2.asm" name="asm-tree" version="9.6"> <artifact name="asm-tree-9.6.jar"> <sha256 value="c43ecf17b539c777e15da7b5b86553b377e2d39a683de6285567d5283888e7ef" origin="Generated by Gradle"/>
diff --git a/libraries/tools/kotlin-main-kts-test/build.gradle.kts b/libraries/tools/kotlin-main-kts-test/build.gradle.kts index 093256f..154ef06 100644 --- a/libraries/tools/kotlin-main-kts-test/build.gradle.kts +++ b/libraries/tools/kotlin-main-kts-test/build.gradle.kts
@@ -36,7 +36,7 @@ } projectTests { - testTask { + testTask(javaLauncher = JdkMajorVersion.JDK_17_0) { dependsOn(":dist", ":kotlinx-serialization-compiler-plugin.embeddable:embeddable") workingDir = rootDir val localKotlinxSerializationPluginClasspath: FileCollection = kotlinxSerializationGradlePluginClasspath
diff --git a/plugins/scripting/scripting-tests/build.gradle.kts b/plugins/scripting/scripting-tests/build.gradle.kts index dcec92a..739c0a9 100644 --- a/plugins/scripting/scripting-tests/build.gradle.kts +++ b/plugins/scripting/scripting-tests/build.gradle.kts
@@ -58,6 +58,11 @@ ) ) { workingDir = rootDir + // `kotlinc` launcher script started by the tests must run on JDK 17+ + val jdkHome = project.getToolchainJdkHomeFor(JdkMajorVersion.JDK_17_0) + doFirst { + environment("JAVA_HOME", jdkHome.get()) + } addClasspathProperty(testSourceSet.output.classesDirs, "kotlin.test.script.classpath") addClasspathProperty(powerAssertCompilerPluginJar, "kotlin.power.assert.compiler.plugin.jar") addClasspathProperty(kotlinxSerializationGradlePluginClasspath, "kotlin.script.test.kotlinx.serialization.plugin.classpath")
diff --git a/settings.gradle.kts b/settings.gradle.kts index d9095c8..b62b4fa 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts
@@ -547,6 +547,7 @@ include( ":compiler:test-coverage", + ":compiler:test-coverage:scripting", ":compiler:test-infrastructure", ":compiler:test-infrastructure:grouping-test-engine", ":compiler:test-infrastructure-utils",