pitest icon indicating copy to clipboard operation
pitest copied to clipboard

Possible problem with Kotlin coroutines

Open Octogonapus opened this issue 6 years ago • 5 comments

I am getting this problem when running pitest in a project that uses Kotlin coroutines: https://gist.github.com/Octogonapus/6a14d814b107c0c78e74979f79e88718

I'm not sure what pitest is trying to accomplish here. arrow.typeclasses.ContinuationUtilsKt appears frequently, could there be a problem related to custom coroutines? I think that pitest should stay out of dependency class files in general (arrow is one of my dependencies).

This is my pitest configuration:

    pitest {
        testPlugin.set("junit5")
        pitestVersion.set("1.4.10")
        threads.set(4)
        avoidCallsTo.set(setOf("kotlin.jvm.internal", "kotlinx.coroutines", "arrow"))
        excludedMethods.set(
            setOf(
                "hashCode",
                "equals",
                "checkIndexOverflow",
                "throwIndexOverflow",
                "collectionSizeOrDefault"
            )
        )
        excludedClasses.set(
            setOf(
                "NoSuchElementException",
                "NoWhenBranchMatchedException",
                "IllegalStateException"
            )
        )
        timeoutConstInMillis.set(10000)
        mutators.set(setOf("NEW_DEFAULTS"))
    }

Pitest version: 1.4.10 Pitest Gradle plugin version: 1.4.5 Gradle version: 5.6.4 Kotlin version: 1.3.60 JVM version: 11.0.4+10-b520.11 amd64

Octogonapus avatar Dec 01 '19 18:12 Octogonapus

Something looks to be trying to write to the coverage probe array that pitest adds, but fails to do so because it's final.

If you can put together a complete, minimal example project that reproduces the issue I can take a look.

hcoles avatar Dec 02 '19 19:12 hcoles

@hcoles Here you go: https://github.com/Octogonapus/reproduce-pitest-problem I tested cloning it and running ./gradlew :dsl:pitest to reproduce the problem.

Octogonapus avatar Dec 02 '19 21:12 Octogonapus

I think this may be a bug in arrow.

This class looks to be trying to set values for all fields in a class, including the one pitest adds to hold the coverage probes.

https://github.com/arrow-kt/arrow/blob/master/modules/core/arrow-core-data/src/main/kotlin/arrow/typeclasses/ContinuationUtils.kt

The field pitest adds is marked as

  • synthetic
  • static
  • final

I don't know anything about arrow, but I think it highly likely that it shouldn't be trying to touch fields with any one of those markers, and certainly not all three.

It looks to work with jacoco as jacoco doesn't mark field it adds as final, so there is no error when it tries to set it. It still probably isn't desirable behaviour however.

I could remove the final marker from the pit probe field, but this feels like the wrong thing todo, unless someone from arrow can explain why overwriting a synthetic final static field is desired.

If this is fixed in arrow there will likely still be issues with coroutines as pitest will probably produce a lot of junk mutations in the code the compiler generates unless some filters are added to remove them.

hcoles avatar Dec 04 '19 19:12 hcoles

I've created an issue on the arrow side

https://github.com/arrow-kt/arrow/issues/1830

hcoles avatar Dec 04 '19 20:12 hcoles

For anyone using pitest with kotlin coroutines, the arcmutate kotlin plugin now provides some support.

hcoles avatar Mar 02 '22 11:03 hcoles