diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8d3388624..cbb4dde40 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,27 +11,6 @@ on:
jobs:
main:
runs-on: ubuntu-latest
- services:
- # flagd-testbed for flagd RPC provider e2e tests
- flagd:
- image: ghcr.io/open-feature/flagd-testbed:v0.5.5
- ports:
- - 8013:8013
- # flagd-testbed for flagd RPC provider reconnect e2e tests
- flagd-unstable:
- image: ghcr.io/open-feature/flagd-testbed-unstable:v0.5.5
- ports:
- - 8014:8013
- # sync-testbed for flagd in-process provider e2e tests
- sync:
- image: ghcr.io/open-feature/sync-testbed:v0.5.5
- ports:
- - 9090:9090
- # sync-testbed for flagd in-process provider reconnect e2e tests
- sync-unstable:
- image: ghcr.io/open-feature/sync-testbed-unstable:v0.5.5
- ports:
- - 9091:9090
steps:
- name: Checkout Repository
diff --git a/providers/flagd/docker-compose.yaml b/providers/flagd/docker-compose.yaml
deleted file mode 100644
index d8630fc5f..000000000
--- a/providers/flagd/docker-compose.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-services:
- flagd:
- image: ghcr.io/open-feature/flagd-testbed:v0.5.5
- ports:
- - 8013:8013
- flagd-unstable:
- image: ghcr.io/open-feature/flagd-testbed-unstable:v0.5.5
- ports:
- - 8014:8013
- flagd-sync:
- image: ghcr.io/open-feature/sync-testbed:v0.5.5
- ports:
- - 9090:9090
- flagd-sync-unstable:
- image: ghcr.io/open-feature/sync-testbed-unstable:v0.5.5
- ports:
- - 9091:9090
\ No newline at end of file
diff --git a/providers/flagd/pom.xml b/providers/flagd/pom.xml
index 087baadbf..42a46aa26 100644
--- a/providers/flagd/pom.xml
+++ b/providers/flagd/pom.xml
@@ -132,6 +132,25 @@
1.17.0
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.8.1
+ test
+
+
+ org.testcontainers
+ testcontainers
+ 1.19.8
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ 1.19.8
+ test
+
+
@@ -402,4 +421,4 @@
-
\ No newline at end of file
+
diff --git a/providers/flagd/schemas b/providers/flagd/schemas
index e72b08b71..8c72c14ee 160000
--- a/providers/flagd/schemas
+++ b/providers/flagd/schemas
@@ -1 +1 @@
-Subproject commit e72b08b71ad8654e8a31ec6f75a9c8b4d47db8ca
+Subproject commit 8c72c14eebff2a5b20fe2afb90c7ad44c1184ae8
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerConfig.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerConfig.java
new file mode 100644
index 000000000..6b8ba78d6
--- /dev/null
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/ContainerConfig.java
@@ -0,0 +1,71 @@
+package dev.openfeature.contrib.providers.flagd.e2e;
+
+import org.jetbrains.annotations.NotNull;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.utility.DockerImageName;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class ContainerConfig {
+ private static final String version;
+
+ static {
+ Properties properties = new Properties();
+ try {
+ properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("flagdTestbed.properties"));
+ version = properties.getProperty("version");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ *
+ * @return a {@link org.testcontainers.containers.GenericContainer} instance of a stable sync flagd server with the port 9090 exposed
+ */
+ public static GenericContainer sync() {
+ return sync(false);
+ }
+
+ /**
+ *
+ * @param unstable if an unstable version of the container, which terminates the connection regularly should be used.
+ * @return a {@link org.testcontainers.containers.GenericContainer} instance of a sync flagd server with the port 9090 exposed
+ */
+ public static GenericContainer sync(boolean unstable) {
+ String container = generateContainerName("sync", unstable);
+ return new GenericContainer(DockerImageName.parse(container))
+ .withExposedPorts(9090);
+ }
+
+ /**
+ *
+ * @return a {@link org.testcontainers.containers.GenericContainer} instance of a stable flagd server with the port 8013 exposed
+ */
+ public static GenericContainer flagd() {
+ return flagd(false);
+ }
+
+ /**
+ *
+ * @param unstable if an unstable version of the container, which terminates the connection regularly should be used.
+ * @return a {@link org.testcontainers.containers.GenericContainer} instance of a flagd server with the port 8013 exposed
+ */
+ public static GenericContainer flagd(boolean unstable) {
+ String container = generateContainerName("flagd", unstable);
+ return new GenericContainer(DockerImageName.parse(container))
+ .withExposedPorts(8013);
+ }
+
+ private static @NotNull String generateContainerName(String type, boolean unstable) {
+ String container = "ghcr.io/open-feature/";
+ container += type;
+ container += "-testbed";
+ if (unstable) {
+ container += "-unstable";
+ }
+ container += ":" + version;
+ return container;
+ }
+}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessCucumberTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessCucumberTest.java
index f250ced7d..048a1f328 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessCucumberTest.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessCucumberTest.java
@@ -5,6 +5,7 @@
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;
+import org.testcontainers.junit.jupiter.Testcontainers;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
@@ -20,6 +21,7 @@
@SelectClasspathResource("features/flagd.feature")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.process,dev.openfeature.contrib.providers.flagd.e2e.steps")
+@Testcontainers
public class RunFlagdInProcessCucumberTest {
-
+
}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessReconnectCucumberTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessReconnectCucumberTest.java
index bda21e110..97fe2d355 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessReconnectCucumberTest.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdInProcessReconnectCucumberTest.java
@@ -5,12 +5,13 @@
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;
+import org.testcontainers.junit.jupiter.Testcontainers;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
/**
- * Class for running the reconnection tests for the in-process provider
+ * Class for running the reconnection tests for the in-process provider
*/
@Order(value = Integer.MAX_VALUE)
@Suite
@@ -18,6 +19,7 @@
@SelectClasspathResource("features/flagd-reconnect.feature")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.reconnect.process,dev.openfeature.contrib.providers.flagd.e2e.reconnect.steps")
+@Testcontainers
public class RunFlagdInProcessReconnectCucumberTest {
-
+
}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcCucumberTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcCucumberTest.java
index 05591d20b..11bdea0e7 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcCucumberTest.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcCucumberTest.java
@@ -5,6 +5,7 @@
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;
+import org.testcontainers.junit.jupiter.Testcontainers;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
@@ -20,7 +21,8 @@
@SelectClasspathResource("features/flagd.feature")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.rpc,dev.openfeature.contrib.providers.flagd.e2e.steps")
+@Testcontainers
public class RunFlagdRpcCucumberTest {
-
+
}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcReconnectCucumberTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcReconnectCucumberTest.java
index 0c41c06f7..fa226c1a6 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcReconnectCucumberTest.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/RunFlagdRpcReconnectCucumberTest.java
@@ -5,12 +5,13 @@
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;
+import org.testcontainers.junit.jupiter.Testcontainers;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
/**
- * Class for running the reconnection tests for the RPC provider
+ * Class for running the reconnection tests for the RPC provider
*/
@Order(value = Integer.MAX_VALUE)
@Suite
@@ -18,7 +19,8 @@
@SelectClasspathResource("features/flagd-reconnect.feature")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.reconnect.rpc,dev.openfeature.contrib.providers.flagd.e2e.reconnect.steps")
+@Testcontainers
public class RunFlagdRpcReconnectCucumberTest {
-
+
}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/process/FlagdInProcessSetup.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/process/FlagdInProcessSetup.java
index 2dbf171be..d23caf42a 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/process/FlagdInProcessSetup.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/process/FlagdInProcessSetup.java
@@ -1,5 +1,7 @@
package dev.openfeature.contrib.providers.flagd.e2e.process;
+import dev.openfeature.contrib.providers.flagd.e2e.ContainerConfig;
+import io.cucumber.java.AfterAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.parallel.Isolated;
@@ -9,20 +11,30 @@
import dev.openfeature.contrib.providers.flagd.e2e.steps.StepDefinitions;
import dev.openfeature.sdk.FeatureProvider;
import io.cucumber.java.BeforeAll;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.utility.DockerImageName;
@Isolated()
@Order(value = Integer.MAX_VALUE)
public class FlagdInProcessSetup {
private static FeatureProvider provider;
-
+
+ private static final GenericContainer flagdContainer = ContainerConfig.sync();
+
@BeforeAll()
public static void setup() throws InterruptedException {
+ flagdContainer.start();
FlagdInProcessSetup.provider = new FlagdProvider(FlagdOptions.builder()
.resolverType(Config.Resolver.IN_PROCESS)
.deadline(3000)
- .port(9090)
+ .port(flagdContainer.getFirstMappedPort())
.build());
StepDefinitions.setProvider(provider);
}
+
+ @AfterAll
+ public static void tearDown() {
+ flagdContainer.stop();
+ }
}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/process/FlagdInProcessSetup.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/process/FlagdInProcessSetup.java
index 5dd736351..3ad3ac5f4 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/process/FlagdInProcessSetup.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/process/FlagdInProcessSetup.java
@@ -1,5 +1,7 @@
package dev.openfeature.contrib.providers.flagd.e2e.reconnect.process;
+import dev.openfeature.contrib.providers.flagd.e2e.ContainerConfig;
+import io.cucumber.java.AfterAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.parallel.Isolated;
@@ -9,17 +11,20 @@
import dev.openfeature.contrib.providers.flagd.e2e.reconnect.steps.StepDefinitions;
import dev.openfeature.sdk.FeatureProvider;
import io.cucumber.java.BeforeAll;
+import org.testcontainers.containers.GenericContainer;
@Isolated()
@Order(value = Integer.MAX_VALUE)
public class FlagdInProcessSetup {
-
+
+ private static final GenericContainer flagdContainer = ContainerConfig.sync(true);
@BeforeAll()
public static void setup() throws InterruptedException {
+ flagdContainer.start();
FeatureProvider workingProvider = new FlagdProvider(FlagdOptions.builder()
.resolverType(Config.Resolver.IN_PROCESS)
.deadline(3000)
- .port(9091)
+ .port(flagdContainer.getFirstMappedPort())
.build());
StepDefinitions.setUnstableProvider(workingProvider);
@@ -30,4 +35,9 @@ public static void setup() throws InterruptedException {
.build());
StepDefinitions.setUnavailableProvider(unavailableProvider);
}
+
+ @AfterAll
+ public static void tearDown() {
+ flagdContainer.stop();
+ }
}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/rpc/FlagdRpcSetup.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/rpc/FlagdRpcSetup.java
index ae46a5b36..945baa3cc 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/rpc/FlagdRpcSetup.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/reconnect/rpc/FlagdRpcSetup.java
@@ -1,5 +1,7 @@
package dev.openfeature.contrib.providers.flagd.e2e.reconnect.rpc;
+import dev.openfeature.contrib.providers.flagd.e2e.ContainerConfig;
+import io.cucumber.java.AfterAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.parallel.Isolated;
@@ -10,16 +12,22 @@
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType;
import dev.openfeature.sdk.FeatureProvider;
import io.cucumber.java.BeforeAll;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.utility.DockerImageName;
@Isolated()
@Order(value = Integer.MAX_VALUE)
public class FlagdRpcSetup {
+ private static final GenericContainer flagdContainer = ContainerConfig.flagd(true);
@BeforeAll()
public static void setup() throws InterruptedException {
+ flagdContainer.start();
+
FeatureProvider workingProvider = new FlagdProvider(FlagdOptions.builder()
.resolverType(Config.Resolver.RPC)
- .port(8014)
+ .port(flagdContainer.getFirstMappedPort())
// set a generous deadline, to prevent timeouts in actions
.deadline(3000)
.cacheType(CacheType.DISABLED.getValue())
@@ -35,4 +43,9 @@ public static void setup() throws InterruptedException {
.build());
StepDefinitions.setUnavailableProvider(unavailableProvider);
}
+
+ @AfterAll
+ public static void tearDown() {
+ flagdContainer.stop();
+ }
}
diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/rpc/FlagdRpcSetup.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/rpc/FlagdRpcSetup.java
index a137a5e34..27ab4ea6d 100644
--- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/rpc/FlagdRpcSetup.java
+++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/rpc/FlagdRpcSetup.java
@@ -1,6 +1,8 @@
package dev.openfeature.contrib.providers.flagd.e2e.rpc;
+import dev.openfeature.contrib.providers.flagd.e2e.ContainerConfig;
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType;
+import io.cucumber.java.AfterAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.parallel.Isolated;
@@ -10,21 +12,34 @@
import dev.openfeature.contrib.providers.flagd.e2e.steps.StepDefinitions;
import dev.openfeature.sdk.FeatureProvider;
import io.cucumber.java.BeforeAll;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.utility.DockerImageName;
@Isolated()
@Order(value = Integer.MAX_VALUE)
public class FlagdRpcSetup {
private static FeatureProvider provider;
+ private static final GenericContainer flagdContainer = ContainerConfig.flagd();
@BeforeAll()
public static void setup() {
+ flagdContainer.start();
FlagdRpcSetup.provider = new FlagdProvider(FlagdOptions.builder()
.resolverType(Config.Resolver.RPC)
+ .port(flagdContainer.getFirstMappedPort())
// set a generous deadline, to prevent timeouts in actions
.deadline(3000)
.cacheType(CacheType.DISABLED.getValue())
.build());
StepDefinitions.setProvider(provider);
}
+
+ @AfterAll
+ public static void tearDown() {
+ flagdContainer.stop();
+ }
+
}
diff --git a/providers/flagd/src/test/resources/flagdTestbed.properties b/providers/flagd/src/test/resources/flagdTestbed.properties
new file mode 100644
index 000000000..a5b5463d7
--- /dev/null
+++ b/providers/flagd/src/test/resources/flagdTestbed.properties
@@ -0,0 +1,3 @@
+# todo: properly configure renovate with a regex matcher to update this version
+# renovate: datasource=docker packageName=docker versioning=docker
+version=v0.5.5