micronaut-test icon indicating copy to clipboard operation
micronaut-test copied to clipboard

parallel test execution throws ConcurrentModificationException

Open vmj opened this issue 5 years ago • 6 comments

Task List

  • [x] Steps to reproduce provided
  • [x] Stacktrace (if present) provided
  • [ ] Example that reproduces the problem uploaded to Github
  • [x] Full description of the issue provided (see below)

Steps to Reproduce

  1. Generate a minimal application: mn create-app -b=gradle --jdk=11 -l=java -t=spock demo
  2. Change into demo: cd demo
  3. Overwrite the spock version in build.gradle: testImplementation("org.spockframework:spock-core:2.0-M4-groovy-3.0")
  4. Make test resources directory: mkdir -p src/test/resources
  5. Enable parallel test execution by adding file src/test/resources/SpockConfig.groovy:
    runner {
        parallel {
            enabled true
        }
    }
    
  6. Make the example test run a few times, e.g. by adding a where block:
    @MicronautTest
    class DemoSpec extends Specification {
    
        @Inject
        EmbeddedApplication<?> application
    
        void 'test it works'() {
            expect:
            application.running
    
            where:
            id << (0..100).asList()
        }
    }
    
  7. Run the tests: ./gradlew --no-build-cache clean test

Expected Behaviour

Tests should pass. I.e. BUILD SUCCESSFUL.

Actual Behaviour

About 3 out of 5 times some of the tests fail with the following error:

java.util.ConcurrentModificationException
	at java.base/java.util.HashMap.compute(HashMap.java:1229)
	at io.micronaut.test.extensions.AbstractMicronautExtension.beforeEach(AbstractMicronautExtension.java:253)
	at io.micronaut.test.extensions.spock.MicronautSpockExtension.lambda$visitSpecAnnotation$5(MicronautSpockExtension.java:133)
	at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:101)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.spockframework.runtime.model.MethodInfo.invoke(MethodInfo.java:136)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

Seems to refer to testProperties field in AbstractMicronautExtension class.

Environment Information

  • Operating System: macOS 10.15.7
  • Micronaut Version: 2.1.2
  • JDK Version:
    openjdk version "11.0.9" 2020-10-20 LTS
    OpenJDK Runtime Environment Zulu11.43+21-CA (build 11.0.9+11-LTS)
    OpenJDK 64-Bit Server VM Zulu11.43+21-CA (build 11.0.9+11-LTS, mixed mode)
    

vmj avatar Nov 02 '20 20:11 vmj

I guess this maps could be changed to ConcurrentHashMaps.

alvarosanchez avatar Nov 03 '20 09:11 alvarosanchez

I'm not sure these extensions are designed to be concurrently executed, and not sure I understand why Gradle's parallel test support is allowing parallel access to extensions

graemerocher avatar Nov 03 '20 10:11 graemerocher

I'm not sure these extensions are designed to be concurrently executed, and not sure I understand why Gradle's parallel test support is allowing parallel access to extensions

You probably meant Spock's parallel execution. It's a new feature in Spock 2.0 M4.

Yes, there's a larger question of how spock extensions should be implemented to support it.

vmj avatar Nov 03 '20 16:11 vmj

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jan 02 '21 17:01 stale[bot]

JUnit parallel test execution also fails.

ecmel avatar Jun 13 '22 06:06 ecmel

Is there any plan to support this?

supriya-tw avatar Sep 20 '22 14:09 supriya-tw