You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cannot use this plugin in tandem with Kotlin Multiplatform Tests #116
> Configure project :
Kotlin Multiplatform Projects are an Alpha feature. See: https://kotlinlang.org/docs/reference/evolution/components-stability.html. To hide this message, add 'kotlin.mpp.stability.nowarn=true' to the Gradle properties.
> Task :jvmTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':jvmTest'.
> Unexpected test executer: org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest$Executor@1073de17
tasks.withType<KotlinJvmTest>().configureEach {
applyTestRetryCompatibilityWorkaround()
}
/** * Test retry plugin is incompatible with test tasks that override the `createTestExecuter` method. * This includes the [KotlinJvmTest] task which wraps the test executor with its own wrapper. * * This workaround heavily relies on the internal implementation details of the test-retry plugin and KGP. * * The test retry plugin adds a `doFirst` action, which: * - Retrieves the test executer using `createTestExecuter` (KGP returns wrapped test executer here) * - Wraps it with `RetryTestExecuter` * - Sets the executer using `setTestExecuter` * * In the `doLast` action, it expects that `createTestExecuter` returns the previously created `RetryTestExecuter` instance. * However, KGP wraps every result of `createTestExecutor` with its own wrapper, resulting in the following nesting: * KotlinJvmTarget$Executer(RetryTestExecuter(KotlinJvmTarget$Executer(DefaultTestExecuter))) * * KGP wraps the executer only if `targetName` is present, as it is needed to add the target name suffix to the test name. * The workaround sets `targetName` to `null` after the first KGP wrapper is created, * so `createTestExecuter` returns the previously created executer: * RetryTestExecuter(KotlinJvmTarget$Executer(DefaultTestExecuter)) * * Issue: https://github.com/gradle/test-retry-gradle-plugin/issues/116 (KT-49155)*/privatefun KotlinJvmTest.applyTestRetryCompatibilityWorkaround() {
if (targetName ==null) returnval executeTestsActionIndex = taskActions.indexOfLast { it.displayName =="Execute executeTests" }
check(executeTestsActionIndex !=-1) { "Action executeTests not found" }
// Add the workaround action and then move it to the correct position right before tests execution.
doFirst("workaround for compatibility with testRetry") {
targetName =null
}
val injectedAction = taskActions.removeFirst()
taskActions.add(executeTestsActionIndex, injectedAction)
// Restore targetName value at the end as other plugins might rely on it.// For example, kover uses it to find test tasks by target name
doLast("restore targetName") { targetName = originalTargetName }
}
I hope it doesn't break any stuff related to task inputs as targetName is marked as @Input
In my opinion, the problem is in createTestExecuter method semantics violation. Method name implies creation of a new instance on each call, while its implementation in the Test task looks like this:
What could be done on a KGP side (or any other plugin's overriding an executer) is to check if the super.createTestExecuter returns the default implementation:
overridefuncreateTestExecuter(): TestExecuter<JvmTestExecutionSpec> {
val executer =super.createTestExecuter()
returnif (executer isDefaultTestExecuter) {
// Wrap the executer or create a new one
} else {
// Executer was set by test-retry plugin, return it "as is"
executer
}
}
Though it would be even better to resolve this problem in Gradle. Probably by introducing a new method getTestExecuter like this:
Third-party plugins will be able to override createTestExecuter while getTestExecuter will return the executor set by test-retry plugin. The only problem is that this solution requires changes to the Gradle codebase, so probably this issue should be moved there.
Activity
abelkov commentedon Oct 8, 2021
Mirror issue on Kotlin side: https://youtrack.jetbrains.com/issue/KT-49155
osipxd commentedon Oct 11, 2024
Found a workaround:
I hope it doesn't break any stuff related to task inputs as
targetNameis marked as@Inputosipxd commentedon Oct 14, 2024
In my opinion, the problem is in
createTestExecutermethod semantics violation. Method name implies creation of a new instance on each call, while its implementation in theTesttask looks like this:What could be done on a KGP side (or any other plugin's overriding an executer) is to check if the
super.createTestExecuterreturns the default implementation:Though it would be even better to resolve this problem in Gradle. Probably by introducing a new method
getTestExecuterlike this:Third-party plugins will be able to override
createTestExecuterwhilegetTestExecuterwill return the executor set bytest-retryplugin. The only problem is that this solution requires changes to the Gradle codebase, so probably this issue should be moved there.