Skip to content

Add a new option to supply a custom UuidGenerator when building runtime #3039

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 89 additions & 43 deletions cucumber-core/src/main/java/io/cucumber/core/runtime/Runtime.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.cucumber.core.runtime;

import io.cucumber.core.eventbus.EventBus;
import io.cucumber.core.eventbus.UuidGenerator;
import io.cucumber.core.feature.FeatureParser;
import io.cucumber.core.filter.Filters;
import io.cucumber.core.gherkin.Feature;
Expand Down Expand Up @@ -117,96 +118,141 @@ public static class Builder {
private Supplier<ClassLoader> classLoader = ClassLoaders::getDefaultClassLoader;
private RuntimeOptions runtimeOptions = RuntimeOptions.defaultOptions();
private BackendSupplier backendSupplier;
private ObjectFactorySupplier objectFactorySupplier;
private FeatureSupplier featureSupplier;
private List<Plugin> additionalPlugins = emptyList();
private Supplier<UuidGenerator> uuidGeneratorSupplier;

private Builder() {
}

public Builder withRuntimeOptions(final RuntimeOptions runtimeOptions) {
public Builder withRuntimeOptions(RuntimeOptions runtimeOptions) {
this.runtimeOptions = runtimeOptions;
return this;
}

public Builder withClassLoader(final Supplier<ClassLoader> classLoader) {
public Builder withClassLoader(Supplier<ClassLoader> classLoader) {
this.classLoader = classLoader;
return this;
}

public Builder withBackendSupplier(final BackendSupplier backendSupplier) {
public Builder withBackendSupplier(BackendSupplier backendSupplier) {
this.backendSupplier = backendSupplier;
return this;
}

public Builder withFeatureSupplier(final FeatureSupplier featureSupplier) {
public Builder withObjectFactorySupplier(ObjectFactorySupplier objectFactorySupplier) {
this.objectFactorySupplier = objectFactorySupplier;
return this;
}

public Builder withFeatureSupplier(FeatureSupplier featureSupplier) {
this.featureSupplier = featureSupplier;
return this;
}

public Builder withAdditionalPlugins(final Plugin... plugins) {
public Builder withUuidGeneratorSupplier(Supplier<UuidGenerator> uuidGenerator) {
this.uuidGeneratorSupplier = uuidGenerator;
return this;
}

public Builder withAdditionalPlugins(Plugin... plugins) {
this.additionalPlugins = Arrays.asList(plugins);
return this;
}

public Builder withEventBus(final EventBus eventBus) {
public Builder withEventBus(EventBus eventBus) {
this.eventBus = eventBus;
return this;
}

public Runtime build() {
final ObjectFactoryServiceLoader objectFactoryServiceLoader = new ObjectFactoryServiceLoader(classLoader,
runtimeOptions);

final ObjectFactorySupplier objectFactorySupplier = runtimeOptions.isMultiThreaded()
? new ThreadLocalObjectFactorySupplier(objectFactoryServiceLoader)
: new SingletonObjectFactorySupplier(objectFactoryServiceLoader);

final BackendSupplier backendSupplier = this.backendSupplier != null
? this.backendSupplier
: new BackendServiceLoader(this.classLoader, objectFactorySupplier);
EventBus eventBus = synchronize(createEventBus());
ExitStatus exitStatus = createPluginsAndExitStatus(eventBus);
RunnerSupplier runnerSupplier = createRunnerSupplier(eventBus);
CucumberExecutionContext context = new CucumberExecutionContext(eventBus, exitStatus, runnerSupplier);
Predicate<Pickle> filter = new Filters(runtimeOptions);
int limit = runtimeOptions.getLimitCount();
FeatureSupplier featureSupplier = createFeatureSupplier(eventBus);
ExecutorService executor = createExecutorService();
PickleOrder pickleOrder = runtimeOptions.getPickleOrder();
return new Runtime(exitStatus, context, filter, limit, featureSupplier, executor, pickleOrder);
}

final Plugins plugins = new Plugins(new PluginFactory(), runtimeOptions);
for (final Plugin plugin : additionalPlugins) {
plugins.addPlugin(plugin);
}
final ExitStatus exitStatus = new ExitStatus(runtimeOptions);
private ExitStatus createPluginsAndExitStatus(EventBus eventBus) {
Plugins plugins = createPlugins();
ExitStatus exitStatus = new ExitStatus(runtimeOptions);
plugins.addPlugin(exitStatus);

if (this.eventBus == null) {
final UuidGeneratorServiceLoader uuidGeneratorServiceLoader = new UuidGeneratorServiceLoader(
classLoader,
runtimeOptions);
this.eventBus = new TimeServiceEventBus(Clock.systemUTC(),
uuidGeneratorServiceLoader.loadUuidGenerator());
}
final EventBus eventBus = synchronize(this.eventBus);

if (runtimeOptions.isMultiThreaded()) {
plugins.setSerialEventBusOnEventListenerPlugins(eventBus);
} else {
plugins.setEventBusOnEventListenerPlugins(eventBus);
}
return exitStatus;
}

final RunnerSupplier runnerSupplier = runtimeOptions.isMultiThreaded()
private RunnerSupplier createRunnerSupplier(EventBus eventBus) {
ObjectFactorySupplier objectFactorySupplier = createObjectFactorySupplier();
BackendSupplier backendSupplier = createBackendSupplier(objectFactorySupplier);
return runtimeOptions.isMultiThreaded()
? new ThreadLocalRunnerSupplier(runtimeOptions, eventBus, backendSupplier, objectFactorySupplier)
: new SingletonRunnerSupplier(runtimeOptions, eventBus, backendSupplier, objectFactorySupplier);
}

final ExecutorService executor = runtimeOptions.isMultiThreaded()
? Executors.newFixedThreadPool(runtimeOptions.getThreads(), new CucumberThreadFactory())
: new SameThreadExecutorService();
private ObjectFactorySupplier createObjectFactorySupplier() {
if (this.objectFactorySupplier != null) {
return objectFactorySupplier;
}
ObjectFactoryServiceLoader objectFactoryServiceLoader = new ObjectFactoryServiceLoader(classLoader,
runtimeOptions);
return runtimeOptions.isMultiThreaded()
? new ThreadLocalObjectFactorySupplier(objectFactoryServiceLoader)
: new SingletonObjectFactorySupplier(objectFactoryServiceLoader);
}

final FeatureParser parser = new FeatureParser(eventBus::generateId);
private BackendSupplier createBackendSupplier(ObjectFactorySupplier objectFactorySupplier) {
return this.backendSupplier != null
? this.backendSupplier
: new BackendServiceLoader(this.classLoader, objectFactorySupplier);
}

final FeatureSupplier featureSupplier = this.featureSupplier != null
? this.featureSupplier
: new FeaturePathFeatureSupplier(classLoader, runtimeOptions, parser);
private EventBus createEventBus() {
if (this.eventBus != null) {
return this.eventBus;
}
UuidGenerator uuidGenerator = createUuidGenerator();
return new TimeServiceEventBus(Clock.systemUTC(), uuidGenerator);
}

final Predicate<Pickle> filter = new Filters(runtimeOptions);
final int limit = runtimeOptions.getLimitCount();
final PickleOrder pickleOrder = runtimeOptions.getPickleOrder();
final CucumberExecutionContext context = new CucumberExecutionContext(eventBus, exitStatus, runnerSupplier);
private UuidGenerator createUuidGenerator() {
if (uuidGeneratorSupplier != null) {
return uuidGeneratorSupplier.get();
} else {
return new UuidGeneratorServiceLoader(classLoader, runtimeOptions).loadUuidGenerator();
}
}

return new Runtime(exitStatus, context, filter, limit, featureSupplier, executor, pickleOrder);
private FeatureSupplier createFeatureSupplier(EventBus eventBus) {
if (this.featureSupplier != null) {
return this.featureSupplier;
}
FeatureParser parser = new FeatureParser(eventBus::generateId);
return new FeaturePathFeatureSupplier(classLoader, runtimeOptions, parser);
}

private ExecutorService createExecutorService() {
return runtimeOptions.isMultiThreaded()
? Executors.newFixedThreadPool(runtimeOptions.getThreads(), new CucumberThreadFactory())
: new SameThreadExecutorService();
}

private Plugins createPlugins() {
Plugins plugins = new Plugins(new PluginFactory(), runtimeOptions);
for (Plugin plugin : additionalPlugins) {
plugins.addPlugin(plugin);
}
return plugins;
}

}
Expand Down
Loading