renatoathaydes / spock-reports

This project creates a global extension to Spock to create test reports.
Apache License 2.0
273 stars 68 forks source link

ConcurrentModificationException when running tests parallel with spock 2.0 and spock-reports #217

Closed as-design closed 2 years ago

as-design commented 2 years ago

Hi, we are using spock2 with parallel test execution and sometimes we get the following exception. We are using spock-core 2.0-groovy-3.0 and spock-reports 2.1-groovy-3.0

java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997) at com.athaydes.spockframework.report.SpecInfoListener.featureRunFor(SpockReportExtension.groovy:249) at com.athaydes.spockframework.report.SpecInfoListener.beforeIteration(SpockReportExtension.groovy:152) at org.spockframework.runtime.model.MethodInfo.invoke(MethodInfo.java:148) 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)

renatoathaydes commented 2 years ago

The List is synchronized, but I forgot that this line iterates through the list, so it must synchronize externally:

specData.featureRuns.find { it.feature == targetFeature }

Will try to get it fixed tomorrow.

renatoathaydes commented 2 years ago

@as-design would you be able to test the fix in branch dev with your project?

I cannot reproduce the problem on my project, but I added some synchronization where the mutable lists are iterated over, so the problem should be fixed now.

renatoathaydes commented 2 years ago

Released fix in 2.1.1-groovy-3.0.