parallel test execution throws ConcurrentModificationException
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
- Generate a minimal application:
mn create-app -b=gradle --jdk=11 -l=java -t=spock demo - Change into
demo:cd demo - Overwrite the spock version in
build.gradle:testImplementation("org.spockframework:spock-core:2.0-M4-groovy-3.0") - Make test resources directory:
mkdir -p src/test/resources - Enable parallel test execution by adding file
src/test/resources/SpockConfig.groovy:runner { parallel { enabled true } } - Make the example test run a few times, e.g. by adding a
whereblock:@MicronautTest class DemoSpec extends Specification { @Inject EmbeddedApplication<?> application void 'test it works'() { expect: application.running where: id << (0..100).asList() } } - 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)
I guess this maps could be changed to ConcurrentHashMaps.
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
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.
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.
JUnit parallel test execution also fails.
Is there any plan to support this?