Skip to content

Commit 5687ee9

Browse files
committed
[Core] Synchronize event bus before use
We can not exclude the possibility that an event is published to the event bus after test execution has completed. For example because the test framework may have decided that a test case has timed out and is now terminating test execution. As such events from the pending testcase on the synchronized bus may race with the events from the unsynchronized bus. This in turn may break the `LinkedList` in the `CanonicalOrderEventPublisher`. Fixes: #2288 (mabye??)
1 parent f16aa9a commit 5687ee9

File tree

4 files changed

+11
-2
lines changed

4 files changed

+11
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616
### Removed
1717

1818
### Fixed
19+
* [Core] Synchronize event bus before use ([#2358](https://github.com/cucumber/cucumber-jvm/pull/2358)) M.P. Korstanje)
1920

2021
## [6.11.0] (2021-08-05)
2122

core/src/main/java/io/cucumber/core/runtime/Runtime.java

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.function.Predicate;
3232
import java.util.function.Supplier;
3333

34+
import static io.cucumber.core.runtime.SynchronizedEventBus.synchronize;
3435
import static java.util.Collections.emptyList;
3536
import static java.util.stream.Collectors.collectingAndThen;
3637
import static java.util.stream.Collectors.toList;
@@ -174,6 +175,9 @@ public Runtime build() {
174175
}
175176
final ExitStatus exitStatus = new ExitStatus(runtimeOptions);
176177
plugins.addPlugin(exitStatus);
178+
179+
final EventBus eventBus = synchronize(this.eventBus);
180+
177181
if (runtimeOptions.isMultiThreaded()) {
178182
plugins.setSerialEventBusOnEventListenerPlugins(eventBus);
179183
} else {

junit/src/main/java/io/cucumber/junit/Cucumber.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.cucumber.core.runtime.ObjectFactoryServiceLoader;
2222
import io.cucumber.core.runtime.ObjectFactorySupplier;
2323
import io.cucumber.core.runtime.ScanningTypeRegistryConfigurerSupplier;
24+
import io.cucumber.core.runtime.SynchronizedEventBus;
2425
import io.cucumber.core.runtime.ThreadLocalObjectFactorySupplier;
2526
import io.cucumber.core.runtime.ThreadLocalRunnerSupplier;
2627
import io.cucumber.core.runtime.TimeServiceEventBus;
@@ -44,6 +45,7 @@
4445
import java.util.function.Predicate;
4546
import java.util.function.Supplier;
4647

48+
import static io.cucumber.core.runtime.SynchronizedEventBus.synchronize;
4749
import static io.cucumber.junit.FileNameCompatibleNames.uniqueSuffix;
4850
import static java.util.stream.Collectors.groupingBy;
4951
import static java.util.stream.Collectors.toList;
@@ -148,7 +150,7 @@ public Cucumber(Class<?> clazz) throws InitializationError {
148150
.parse(CucumberProperties.fromSystemProperties())
149151
.build(junitEnvironmentOptions);
150152

151-
this.bus = new TimeServiceEventBus(Clock.systemUTC(), UUID::randomUUID);
153+
this.bus = synchronize(new TimeServiceEventBus(Clock.systemUTC(), UUID::randomUUID));
152154

153155
// Parse the features early. Don't proceed when there are lexer errors
154156
FeatureParser parser = new FeatureParser(bus::generateId);

testng/src/main/java/io/cucumber/testng/TestNGCucumberRunner.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.cucumber.core.runtime.ObjectFactoryServiceLoader;
2222
import io.cucumber.core.runtime.ObjectFactorySupplier;
2323
import io.cucumber.core.runtime.ScanningTypeRegistryConfigurerSupplier;
24+
import io.cucumber.core.runtime.SynchronizedEventBus;
2425
import io.cucumber.core.runtime.ThreadLocalObjectFactorySupplier;
2526
import io.cucumber.core.runtime.ThreadLocalRunnerSupplier;
2627
import io.cucumber.core.runtime.TimeServiceEventBus;
@@ -33,6 +34,7 @@
3334
import java.util.function.Predicate;
3435
import java.util.function.Supplier;
3536

37+
import static io.cucumber.core.runtime.SynchronizedEventBus.synchronize;
3638
import static io.cucumber.testng.TestCaseResultObserver.observe;
3739
import static java.util.stream.Collectors.toList;
3840

@@ -99,7 +101,7 @@ public TestNGCucumberRunner(Class<?> clazz, CucumberPropertiesProvider propertie
99101
.enablePublishPlugin()
100102
.build(environmentOptions);
101103

102-
EventBus bus = new TimeServiceEventBus(Clock.systemUTC(), UUID::randomUUID);
104+
EventBus bus = synchronize(new TimeServiceEventBus(Clock.systemUTC(), UUID::randomUUID));
103105

104106
Supplier<ClassLoader> classLoader = ClassLoaders::getDefaultClassLoader;
105107
FeatureParser parser = new FeatureParser(bus::generateId);

0 commit comments

Comments
 (0)