diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/ConfigCucumberTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/ConfigCucumberTest.java
index d38c8339dd..29b543987d 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/ConfigCucumberTest.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/ConfigCucumberTest.java
@@ -12,17 +12,17 @@
import org.junit.platform.suite.api.Suite;
/**
- * Class for running the tests associated with "stable" e2e tests (no fake disconnection) for the
- * in-process provider
+ * Runs the flagd-testbed's config.feature, which checks option defaults, environment variables
+ * and builder validation. No backend is involved.
*/
@Order(value = Integer.MAX_VALUE)
@Suite
@IncludeEngines("cucumber")
@SelectFile("test-harness/gherkin/config.feature")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "summary")
-@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.steps.config")
+@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.config")
// The TCK ships its own Cucumber ObjectFactory, so two are on the test classpath and Cucumber
-// refuses to guess. The e2e suites name the same one; this suite needs it for the same reason.
+// refuses to guess.
@ConfigurationParameter(key = OBJECT_FACTORY_PROPERTY_NAME, value = "io.cucumber.picocontainer.PicoFactory")
// Config scenarios read System env vars in FlagdOptions.build() and some scenarios also
// mutate them. Parallel execution causes env-var races (e.g. FLAGD_PORT=3456 leaking into
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/ConfigState.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/ConfigState.java
new file mode 100644
index 0000000000..0a3d36167b
--- /dev/null
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/ConfigState.java
@@ -0,0 +1,10 @@
+package dev.openfeature.contrib.providers.flagd.config;
+
+import dev.openfeature.contrib.providers.flagd.FlagdOptions;
+
+/** Scenario state shared by the config steps, one instance per scenario. */
+public class ConfigState {
+ public FlagdOptions options;
+ public FlagdOptions.FlagdOptionsBuilder builder = FlagdOptions.builder();
+ public boolean hasError;
+}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/config/ConfigSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/ConfigSteps.java
similarity index 90%
rename from providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/config/ConfigSteps.java
rename to providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/ConfigSteps.java
index 7418fe1b03..8e4cfece54 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/config/ConfigSteps.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/ConfigSteps.java
@@ -1,12 +1,8 @@
-package dev.openfeature.contrib.providers.flagd.e2e.steps.config;
+package dev.openfeature.contrib.providers.flagd.config;
import static org.assertj.core.api.Assertions.assertThat;
import dev.openfeature.contrib.providers.flagd.Config;
-import dev.openfeature.contrib.providers.flagd.e2e.State;
-import dev.openfeature.contrib.providers.flagd.e2e.steps.AbstractSteps;
-import dev.openfeature.contrib.providers.flagd.e2e.steps.EnvironmentVariableUtils;
-import dev.openfeature.contrib.providers.flagd.e2e.steps.Utils;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
@@ -19,7 +15,9 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class ConfigSteps extends AbstractSteps {
+public class ConfigSteps {
+ private final ConfigState state;
+
/**
* Not all properties are correctly implemented, hence that we need to ignore them till this is
* fixed
@@ -30,8 +28,8 @@ public class ConfigSteps extends AbstractSteps {
}
};
- public ConfigSteps(State state) {
- super(state);
+ public ConfigSteps(ConfigState state) {
+ this.state = state;
}
@When("a config was initialized")
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/EnvironmentVariableUtils.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/EnvironmentVariableUtils.java
similarity index 98%
rename from providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/EnvironmentVariableUtils.java
rename to providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/EnvironmentVariableUtils.java
index f7427cfa26..b493950962 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/EnvironmentVariableUtils.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/EnvironmentVariableUtils.java
@@ -1,4 +1,4 @@
-package dev.openfeature.contrib.providers.flagd.e2e.steps;
+package dev.openfeature.contrib.providers.flagd.config;
/*
* Copy of JUnit Pioneer's EnvironmentVariable Utils
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/Utils.java
similarity index 97%
rename from providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java
rename to providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/Utils.java
index e53a83d290..c88eaac278 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/Utils.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/config/Utils.java
@@ -1,4 +1,4 @@
-package dev.openfeature.contrib.providers.flagd.e2e.steps;
+package dev.openfeature.contrib.providers.flagd.config;
import dev.openfeature.contrib.providers.flagd.Config;
import dev.openfeature.contrib.providers.flagd.resolver.rpc.cache.CacheType;
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerEntry.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerEntry.java
deleted file mode 100644
index 820f808692..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerEntry.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.Duration;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.testcontainers.containers.ComposeContainer;
-import org.testcontainers.containers.wait.strategy.Wait;
-
-/** A single pre-warmed Docker Compose stack (flagd + envoy) and its associated temp directory. */
-public class ContainerEntry {
-
- public static final int FORBIDDEN_PORT = 9212;
-
- public final ComposeContainer container;
- public final Path tempDir;
-
- private ContainerEntry(ComposeContainer container, Path tempDir) {
- this.container = container;
- this.tempDir = tempDir;
- }
-
- /** Start a new container entry. Blocks until all services are ready. */
- public static ContainerEntry start() throws IOException {
- Path tempDir = Files.createDirectories(
- Paths.get("tmp/" + RandomStringUtils.randomAlphanumeric(8).toLowerCase() + "/"));
-
- ComposeContainer container = new ComposeContainer(new File("test-harness/docker-compose.yaml"))
- .withEnv("FLAGS_DIR", tempDir.toAbsolutePath().toString())
- .withExposedService("flagd", 8013, Wait.forListeningPort())
- .withExposedService("flagd", 8015, Wait.forListeningPort())
- .withExposedService("flagd", 8080, Wait.forListeningPort())
- .withExposedService("envoy", 9211, Wait.forListeningPort())
- .withExposedService("envoy", FORBIDDEN_PORT, Wait.forListeningPort())
- .withStartupTimeout(Duration.ofSeconds(45));
- container.start();
-
- return new ContainerEntry(container, tempDir);
- }
-
- /** Stop the container and clean up the temp directory. */
- public void stop() throws IOException {
- container.stop();
- FileUtils.deleteDirectory(tempDir.toFile());
- }
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerPool.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerPool.java
deleted file mode 100644
index 4d687c57c2..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerPool.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * A pool of pre-warmed {@link ContainerEntry} instances.
- *
- * All containers are started in parallel during {@link #initialize()}, paying the ~45s Docker
- * Compose startup cost only once. Scenarios borrow a container via {@link #acquire()} and return
- * it via {@link #release(ContainerEntry)} after teardown, allowing the next scenario to reuse it
- * immediately without any cold-start overhead.
- *
- *
Pool size is controlled by the system property {@code flagd.e2e.pool.size} (default: 2).
- *
- *
Multiple test classes may share the same JVM fork (Surefire {@code reuseForks=true}). Each
- * class calls {@link #initialize()} and {@link #shutdown()} once. A reference counter ensures
- * that containers are only started on the first {@code initialize()} call and only stopped when
- * the last {@code shutdown()} call is made, preventing one class from destroying containers that
- * are still in use by another class running concurrently in the same JVM.
- */
-@Slf4j
-public class ContainerPool {
-
- private static final int POOL_SIZE = Integer.getInteger(
- "flagd.e2e.pool.size", Math.min(Runtime.getRuntime().availableProcessors(), 4));
-
- private static final BlockingQueue pool = new LinkedBlockingQueue<>();
- private static final List all = new ArrayList<>();
- private static final java.util.concurrent.atomic.AtomicInteger refCount =
- new java.util.concurrent.atomic.AtomicInteger(0);
-
- public static void initialize() throws Exception {
- if (refCount.getAndIncrement() > 0) {
- log.info("Container pool already initialized (refCount={}), reusing existing pool.", refCount.get());
- return;
- }
- log.info("Starting container pool of size {}...", POOL_SIZE);
- ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
- List> futures = new ArrayList<>();
- try {
- for (int i = 0; i < POOL_SIZE; i++) {
- futures.add(executor.submit(ContainerEntry::start));
- }
- for (Future future : futures) {
- ContainerEntry entry = future.get();
- pool.add(entry);
- all.add(entry);
- }
- } catch (Exception e) {
- // Collect any containers that started successfully (including from in-flight futures)
- for (Future future : futures) {
- try {
- ContainerEntry entry = future.get();
- if (!all.contains(entry)) {
- all.add(entry);
- }
- } catch (Exception ignored) {
- // future failed; nothing to stop for it
- }
- }
- all.forEach(entry -> {
- try {
- entry.stop();
- } catch (IOException suppressed) {
- e.addSuppressed(suppressed);
- }
- });
- pool.clear();
- all.clear();
- refCount.decrementAndGet();
- throw e;
- } finally {
- executor.shutdown();
- }
- log.info("Container pool ready ({} containers).", POOL_SIZE);
- }
-
- public static void shutdown() {
- int remaining = refCount.decrementAndGet();
- if (remaining > 0) {
- log.info("Container pool still in use by {} class(es), deferring shutdown.", remaining);
- return;
- }
- log.info("Last shutdown call — stopping all containers.");
- all.forEach(entry -> {
- try {
- entry.stop();
- } catch (IOException e) {
- log.warn("Error stopping container entry", e);
- }
- });
- pool.clear();
- all.clear();
- }
-
- /**
- * Borrow a container from the pool, blocking until one becomes available.
- * The caller MUST call {@link #release(ContainerEntry)} when done.
- */
- public static ContainerEntry acquire() throws InterruptedException {
- return pool.take();
- }
-
- /** Return a container to the pool so the next scenario can use it. */
- public static void release(ContainerEntry entry) {
- pool.add(entry);
- }
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerUtil.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerUtil.java
deleted file mode 100644
index b639672230..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerUtil.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e;
-
-import dev.openfeature.contrib.providers.flagd.Config;
-import java.util.Optional;
-import org.testcontainers.containers.ComposeContainer;
-import org.testcontainers.containers.ContainerState;
-
-public class ContainerUtil {
- public static int getPort(ComposeContainer container, Config.Resolver resolver) {
- Optional flagd = container.getContainerByServiceName("flagd");
-
- return flagd.map(containerState -> {
- switch (resolver) {
- case RPC:
- return containerState.getMappedPort(8013);
- case IN_PROCESS:
- return containerState.getMappedPort(8015);
- default:
- return 0;
- }
- })
- .orElseThrow(() -> new RuntimeException("Could not map port"));
- }
-
- public static String getLaunchpadUrl(ComposeContainer container) {
- Optional flagd = container.getContainerByServiceName("flagd");
- return flagd.map(containerState -> {
- return containerState.getHost() + ":" + containerState.getMappedPort(8080);
- })
- .orElseThrow(() -> new RuntimeException("Could not find launchpad url"));
- }
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFileTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFileTest.java
deleted file mode 100644
index c7387b6e33..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFileTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e;
-
-import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
-import static io.cucumber.junit.platform.engine.Constants.OBJECT_FACTORY_PROPERTY_NAME;
-import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
-
-import dev.openfeature.contrib.providers.flagd.Config;
-import org.apache.logging.log4j.core.config.Order;
-import org.junit.platform.suite.api.BeforeSuite;
-import org.junit.platform.suite.api.ConfigurationParameter;
-import org.junit.platform.suite.api.ExcludeTags;
-import org.junit.platform.suite.api.IncludeEngines;
-import org.junit.platform.suite.api.IncludeTags;
-import org.junit.platform.suite.api.SelectDirectories;
-import org.junit.platform.suite.api.Suite;
-import org.testcontainers.junit.jupiter.Testcontainers;
-
-/**
- * Class for running the reconnection tests for the RPC provider
- */
-@Order(value = Integer.MAX_VALUE)
-@Suite
-@IncludeEngines("cucumber")
-@SelectDirectories("test-harness/gherkin")
-// if you want to run just one feature file, use the following line instead of @SelectDirectories
-// @SelectFile("test-harness/gherkin/connection.feature")
-@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "summary")
-@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.steps")
-@ConfigurationParameter(key = OBJECT_FACTORY_PROPERTY_NAME, value = "io.cucumber.picocontainer.PicoFactory")
-@IncludeTags("file")
-@ExcludeTags({
- "unixsocket",
- "targetURI",
- "reconnect",
- "customCert",
- "events",
- "contextEnrichment",
- "fractional-v1",
- "fractional-v2",
- "deprecated",
- // reads 2^53-1 via 32-bit getInteger; Long scenarios: open-feature/flagd-testbed#379
- "large-integers"
-})
-@Testcontainers
-public class RunFileTest {
-
- @BeforeSuite
- public static void before() {
- State.resolverType = Config.Resolver.FILE;
- }
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunInProcessTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunInProcessTest.java
deleted file mode 100644
index 05eb219db1..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunInProcessTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e;
-
-import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
-import static io.cucumber.junit.platform.engine.Constants.OBJECT_FACTORY_PROPERTY_NAME;
-import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
-
-import dev.openfeature.contrib.providers.flagd.Config;
-import org.apache.logging.log4j.core.config.Order;
-import org.junit.platform.suite.api.BeforeSuite;
-import org.junit.platform.suite.api.ConfigurationParameter;
-import org.junit.platform.suite.api.ExcludeTags;
-import org.junit.platform.suite.api.IncludeEngines;
-import org.junit.platform.suite.api.IncludeTags;
-import org.junit.platform.suite.api.SelectDirectories;
-import org.junit.platform.suite.api.Suite;
-import org.testcontainers.junit.jupiter.Testcontainers;
-
-/**
- * Class for running the reconnection tests for the RPC provider
- */
-@Order(value = Integer.MAX_VALUE)
-@Suite
-@IncludeEngines("cucumber")
-@SelectDirectories("test-harness/gherkin")
-// if you want to run just one feature file, use the following line instead of @SelectDirectories
-// @SelectFile("test-harness/gherkin/selector.feature")
-@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "summary")
-@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.steps")
-@ConfigurationParameter(key = OBJECT_FACTORY_PROPERTY_NAME, value = "io.cucumber.picocontainer.PicoFactory")
-@IncludeTags("in-process")
-// large-integers reads 2^53-1 via 32-bit getInteger; Long scenarios: open-feature/flagd-testbed#379
-@ExcludeTags({"unixsocket", "fractional-v1", "fractional-v2", "deprecated", "large-integers"})
-@Testcontainers
-public class RunInProcessTest {
-
- @BeforeSuite
- public static void before() {
- State.resolverType = Config.Resolver.IN_PROCESS;
- }
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunRpcTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunRpcTest.java
deleted file mode 100644
index 4fe721d093..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunRpcTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e;
-
-import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
-import static io.cucumber.junit.platform.engine.Constants.OBJECT_FACTORY_PROPERTY_NAME;
-import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
-
-import dev.openfeature.contrib.providers.flagd.Config;
-import org.apache.logging.log4j.core.config.Order;
-import org.junit.platform.suite.api.BeforeSuite;
-import org.junit.platform.suite.api.ConfigurationParameter;
-import org.junit.platform.suite.api.ExcludeTags;
-import org.junit.platform.suite.api.IncludeEngines;
-import org.junit.platform.suite.api.IncludeTags;
-import org.junit.platform.suite.api.SelectDirectories;
-import org.junit.platform.suite.api.Suite;
-import org.testcontainers.junit.jupiter.Testcontainers;
-
-/**
- * Class for running the reconnection tests for the RPC provider
- */
-@Order(value = Integer.MAX_VALUE)
-@Suite
-@IncludeEngines("cucumber")
-@SelectDirectories("test-harness/gherkin")
-// if you want to run just one feature file, use the following line instead of @SelectDirectories
-// @SelectFile("test-harness/gherkin/rpc-caching.feature")
-@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "summary")
-@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.steps")
-@ConfigurationParameter(key = OBJECT_FACTORY_PROPERTY_NAME, value = "io.cucumber.picocontainer.PicoFactory")
-@IncludeTags({"rpc"})
-// large-integers reads 2^53-1 via 32-bit getInteger; Long scenarios: open-feature/flagd-testbed#379
-@ExcludeTags({"unixsocket", "fractional-v1", "fractional-v2", "deprecated", "large-integers"})
-@Testcontainers
-public class RunRpcTest {
-
- @BeforeSuite
- public static void before() {
- State.resolverType = Config.Resolver.RPC;
- }
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/State.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/State.java
deleted file mode 100644
index 2c671d5425..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/State.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e;
-
-import dev.openfeature.contrib.providers.flagd.Config;
-import dev.openfeature.contrib.providers.flagd.FlagdOptions;
-import dev.openfeature.contrib.providers.flagd.e2e.steps.Event;
-import dev.openfeature.contrib.providers.flagd.e2e.steps.FlagSteps;
-import dev.openfeature.contrib.providers.flagd.e2e.steps.ProviderType;
-import dev.openfeature.sdk.Client;
-import dev.openfeature.sdk.FeatureProvider;
-import dev.openfeature.sdk.FlagEvaluationDetails;
-import dev.openfeature.sdk.MutableContext;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-public class State {
- public ProviderType providerType;
- public Client client;
- public FeatureProvider provider;
- /** The domain name under which this scenario's provider is registered with OpenFeatureAPI. */
- public String providerName;
- /** The container borrowed from {@link ContainerPool} for this scenario. */
- public ContainerEntry containerEntry;
-
- // events not yet consumed by a positive assertion; drained as they are matched
- public ConcurrentLinkedQueue assertedEvents = new ConcurrentLinkedQueue<>();
- // complete log of every event emitted, used for "never fired" assertions
- public ConcurrentLinkedQueue allEvents = new ConcurrentLinkedQueue<>();
- public Optional lastEvent;
- public FlagSteps.Flag flag;
- public MutableContext context = new MutableContext();
- public FlagEvaluationDetails evaluation;
- public FlagdOptions options;
- public FlagdOptions.FlagdOptionsBuilder builder = FlagdOptions.builder();
- public static Config.Resolver resolverType;
- public boolean hasError;
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/AbstractSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/AbstractSteps.java
deleted file mode 100644
index 4a74400c48..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/AbstractSteps.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e.steps;
-
-import dev.openfeature.contrib.providers.flagd.e2e.State;
-
-public abstract class AbstractSteps {
- protected State state;
-
- protected AbstractSteps(State state) {
- this.state = state;
- }
-}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ContextSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ContextSteps.java
deleted file mode 100644
index b92c994b7e..0000000000
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ContextSteps.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package dev.openfeature.contrib.providers.flagd.e2e.steps;
-
-import dev.openfeature.contrib.providers.flagd.e2e.State;
-import dev.openfeature.sdk.ImmutableStructure;
-import dev.openfeature.sdk.MutableContext;
-import dev.openfeature.sdk.Value;
-import io.cucumber.datatable.DataTable;
-import io.cucumber.java.en.Given;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ContextSteps extends AbstractSteps {
-
- public ContextSteps(State state) {
- super(state);
- }
-
- @Given("^a context containing a key \"([^\"]*)\", with type \"([^\"]*)\" and with value \"(.*)\"$")
- public void a_context_containing_a_key_with_type_and_with_value(String key, String type, String value)
- throws ClassNotFoundException, IOException {
- Map map = new HashMap<>(state.context.asMap());
- map.put(key, Value.objectToValue(Utils.convert(value, type)));
- state.context = new MutableContext(state.context.getTargetingKey(), map);
- }
-
- @Given("a context with the following keys:")
- public void a_context_with_the_following_keys(DataTable dataTable) throws ClassNotFoundException, IOException {
- List