[Gradle] Make KotlinTest, KotlinTestReport partially cc-compatible

This commit is contained in:
Alexander Likhachev
2021-01-27 10:18:08 +03:00
parent c7421e2bea
commit 432c6486d5
5 changed files with 96 additions and 57 deletions
@@ -29,11 +29,14 @@ import javax.inject.Inject
open class KotlinJsTest
@Inject
constructor(
@Internal override var compilation: KotlinJsCompilation
@Transient
@Internal
override var compilation: KotlinJsCompilation
) :
KotlinTest(),
RequiresNpmDependencies {
private val nodeJs get() = NodeJsRootPlugin.apply(project.rootProject)
private val nodeJs= NodeJsRootPlugin.apply(project.rootProject)
private val npmProject = compilation.npmProject
private val projectPath = project.path
@@ -69,22 +72,30 @@ constructor(
var debug: Boolean = false
@Suppress("unused")
val runtimeClasspath: FileCollection
@InputFiles get() = compilation.runtimeDependencyFiles
@get:InputFiles
val runtimeClasspath: FileCollection by lazy {
compilation.runtimeDependencyFiles
}
@Suppress("unused")
internal val compilationOutputs: FileCollection
@InputFiles get() = compilation.output.allOutputs
@get:InputFiles
internal val compilationOutputs: FileCollection by lazy {
compilation.output.allOutputs
}
@Suppress("unused")
val compilationId: String
@Input get() = compilation.let {
@get:Input
val compilationId: String by lazy {
compilation.let {
val target = it.target
target.project.path + "@" + target.name + ":" + it.compilationName
}
}
val nodeModulesToLoad: List<String>
@Internal get() = listOf("./" + compilation.npmProject.main)
@get:Internal
val nodeModulesToLoad: List<String> by lazy {
listOf("./" + compilation.npmProject.main)
}
override val nodeModulesRequired: Boolean
@Internal get() = testFramework!!.nodeModulesRequired
@@ -115,7 +126,7 @@ constructor(
fun useKarma() = useKarma {}
fun useKarma(body: KotlinKarma.() -> Unit) = use(
KotlinKarma(compilation, services, path),
KotlinKarma(compilation, { services }, path),
body
)
fun useKarma(fn: Closure<*>) {
@@ -142,7 +153,7 @@ constructor(
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
val forkOptions = DefaultProcessForkOptions(fileResolver)
forkOptions.workingDir = compilation.npmProject.dir
forkOptions.workingDir = npmProject.dir
forkOptions.executable = nodeJs.requireConfigured().nodeExecutable
val nodeJsArgs = mutableListOf<String>()
@@ -36,9 +36,15 @@ import org.jetbrains.kotlin.gradle.utils.property
import org.slf4j.Logger
import java.io.File
class KotlinKarma(override val compilation: KotlinJsCompilation, private val services: ServiceRegistry, private val basePath: String) :
class KotlinKarma(
@Transient override val compilation: KotlinJsCompilation,
private val services: () -> ServiceRegistry,
private val basePath: String
) :
KotlinJsTestFramework {
@Transient
private val project: Project = compilation.target.project
private val npmProject = compilation.npmProject
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
private val versions = nodeJs.versions
@@ -49,9 +55,11 @@ class KotlinKarma(override val compilation: KotlinJsCompilation, private val ser
private val envJsCollector = mutableMapOf<String, String>()
private val confJsWriters = mutableListOf<(Appendable) -> Unit>()
private var sourceMaps = false
private val defaultConfigDirectory = project.projectDir.resolve("karma.config.d")
private var configDirectory: File by property {
project.projectDir.resolve("karma.config.d")
defaultConfigDirectory
}
private val isTeamCity = project.hasProperty(TC_PROJECT_PROPERTY)
override val requiredNpmDependencies: Set<RequiredKotlinJsDependency>
get() = requiredDependencies + webpackConfig.getRequiredDependencies(versions)
@@ -277,8 +285,6 @@ class KotlinKarma(override val compilation: KotlinJsCompilation, private val ser
file: String,
debug: Boolean
): File {
val npmProject = compilation.npmProject
val adapterJs = npmProject.dir.resolve("adapter-browser.js")
adapterJs.printWriter().use { writer ->
val karmaRunner = npmProject.require("kotlin-test-js-runner/kotlin-test-karma-runner.js")
@@ -301,8 +307,6 @@ class KotlinKarma(override val compilation: KotlinJsCompilation, private val ser
nodeJsArgs: MutableList<String>,
debug: Boolean
): TCServiceMessagesTestExecutionSpec {
val npmProject = compilation.npmProject
val file = task.nodeModulesToLoad
.map { npmProject.require(it) }
.single()
@@ -341,7 +345,7 @@ class KotlinKarma(override val compilation: KotlinJsCompilation, private val ser
prependSuiteName = true,
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
ignoreOutOfRootNodes = true,
escapeTCMessagesInLog = project.hasProperty(TC_PROJECT_PROPERTY)
escapeTCMessagesInLog = isTeamCity
)
config.basePath = npmProject.nodeModulesDir.absolutePath
@@ -407,7 +411,7 @@ class KotlinKarma(override val compilation: KotlinJsCompilation, private val ser
lateinit var progressLogger: ProgressLogger
override fun wrapExecute(body: () -> Unit) {
services.operation("Running and building tests with karma and webpack") {
services().operation("Running and building tests with karma and webpack") {
progressLogger = this
body()
}
@@ -21,11 +21,14 @@ import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinTestRunnerCliArgs
import java.io.File
class KotlinMocha(override val compilation: KotlinJsCompilation, private val basePath: String) :
class KotlinMocha(@Transient override val compilation: KotlinJsCompilation, private val basePath: String) :
KotlinJsTestFramework {
@Transient
private val project: Project = compilation.target.project
private val npmProject = compilation.npmProject
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
private val versions = nodeJs.versions
private val isTeamCity = project.hasProperty(TC_PROJECT_PROPERTY)
override val settingsState: String
get() = "mocha"
@@ -54,11 +57,9 @@ class KotlinMocha(override val compilation: KotlinJsCompilation, private val bas
prependSuiteName = true,
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
ignoreOutOfRootNodes = true,
escapeTCMessagesInLog = project.hasProperty(TC_PROJECT_PROPERTY)
escapeTCMessagesInLog = isTeamCity
)
val npmProject = compilation.npmProject
val cliArgs = KotlinTestRunnerCliArgs(
include = task.includePatterns,
exclude = task.excludePatterns
@@ -105,8 +106,6 @@ class KotlinMocha(override val compilation: KotlinJsCompilation, private val bas
private fun createAdapterJs(
file: String
): File {
val npmProject = compilation.npmProject
val adapterJs = npmProject.dir.resolve(ADAPTER_NODEJS)
adapterJs.printWriter().use { writer ->
val adapter = npmProject.require("kotlin-test-js-runner/kotlin-test-nodejs-runner.js")
@@ -58,11 +58,15 @@ abstract class KotlinTest : AbstractTestTask() {
runListeners.add(listener)
}
private val ignoreTcsmOverflow by lazy {
PropertiesProvider(project).ignoreTcsmOverflow
}
override fun createTestExecuter() = TCServiceMessagesTestExecutor(
execHandleFactory,
buildOperationExecutor,
runListeners,
PropertiesProvider(project).ignoreTcsmOverflow,
ignoreTcsmOverflow,
ignoreRunFailures
)
}
@@ -41,18 +41,24 @@ import java.net.URI
* event if child tasks will be executed.
*/
open class KotlinTestReport : TestReport() {
@Transient
@Internal
val testTasks = mutableListOf<AbstractTestTask>()
@Transient
private var parent: KotlinTestReport? = null
// TODO: used in task action when the task is aggregate report, non compatible with configuration cache
@Internal
val children = mutableListOf<TaskProvider<KotlinTestReport>>()
@Transient
private val projectProperties = PropertiesProvider(project)
val overrideReporting: Boolean
@Input get() = projectProperties.individualTaskReports == null
@get:Input
val overrideReporting: Boolean by lazy {
projectProperties.individualTaskReports == null
}
@Input
var checkFailedTests: Boolean = false
@@ -60,28 +66,14 @@ open class KotlinTestReport : TestReport() {
@Input
var ignoreFailures: Boolean = false
private var hasOwnFailedTests = false
private val hasOwnFailedTests
get() = failedTestsListener.hasOwnFailedTests ?: false
private val hasFailedTests: Boolean
get() = hasOwnFailedTests || children.any { it.get().hasFailedTests }
private val ownSuppressedRunningFailures = mutableListOf<Pair<KotlinTest, Error>>()
private val suppressedRunningFailureListeners: MutableSet<SuppressedTestRunningFailureListener> = mutableSetOf()
private val failedTestsListener = object : TestListener {
override fun beforeTest(testDescriptor: TestDescriptor) {
}
override fun afterSuite(suite: TestDescriptor, result: TestResult) {
}
override fun beforeSuite(suite: TestDescriptor) {
}
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {
if (result.failedTestCount > 0) {
hasOwnFailedTests = true
}
}
}
private val failedTestsListener = FailedTestListener()
fun addChild(childProvider: TaskProvider<KotlinTestReport>) {
val child = childProvider.get()
@@ -108,11 +100,11 @@ open class KotlinTestReport : TestReport() {
testTasks.add(task)
task.addTestListener(failedTestsListener)
if (task is KotlinTest) task.addRunListener(object : KotlinTestRunnerListener {
override fun runningFailure(failure: Error) {
ownSuppressedRunningFailures.add(task to failure)
}
})
if (task is KotlinTest) {
val listener = SuppressedTestRunningFailureListener(task.path)
task.addRunListener(listener)
suppressedRunningFailureListeners.add(listener)
}
reportOn(task)
addToParents(task)
@@ -163,11 +155,11 @@ open class KotlinTestReport : TestReport() {
}
private fun checkSuppressedRunningFailures() {
val allSuppressedRunningFailures = mutableListOf<Pair<KotlinTest, Error>>()
val allSuppressedRunningFailures = mutableListOf<Pair<String, Error>>()
fun visitSuppressedRunningFailures(report: KotlinTestReport) {
report.ownSuppressedRunningFailures.forEach {
allSuppressedRunningFailures.add(it)
report.suppressedRunningFailureListeners.filter { it.failure != null }.forEach {
allSuppressedRunningFailures.add(it.taskPath to it.failure!!)
}
report.children.forEach {
@@ -181,8 +173,8 @@ open class KotlinTestReport : TestReport() {
val allErrors = mutableListOf<Error>()
val msg = buildString {
appendln("Failed to execute all tests:")
allSuppressedRunningFailures.groupBy { it.first }.forEach { test, errors ->
append(test.path)
allSuppressedRunningFailures.groupBy { it.first }.forEach { path, errors ->
append(path)
append(": ")
var first = true
errors.forEach { (_, error) ->
@@ -251,4 +243,33 @@ open class KotlinTestReport : TestReport() {
task.reports.junitXml.isEnabled = false
}
private class SuppressedTestRunningFailureListener(val taskPath: String) : KotlinTestRunnerListener {
@Transient
var failure: Error? = null
override fun runningFailure(failure: Error) {
this.failure = failure
}
}
private class FailedTestListener : TestListener {
@Transient
var hasOwnFailedTests: Boolean? = false
override fun beforeTest(testDescriptor: TestDescriptor) {
}
override fun afterSuite(suite: TestDescriptor, result: TestResult) {
}
override fun beforeSuite(suite: TestDescriptor) {
}
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {
if (result.failedTestCount > 0) {
hasOwnFailedTests = true
}
}
}
}