Skip to content

Commit 819abe3

Browse files
aepflitoddbaert
andauthored
feat(flagd): ssl e2e tests (#1111)
Signed-off-by: Simon Schrottner <[email protected]> Co-authored-by: Todd Baert <[email protected]>
1 parent 4c9360c commit 819abe3

File tree

9 files changed

+237
-29
lines changed

9 files changed

+237
-29
lines changed

.gitmodules

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[submodule "providers/flagd/test-harness"]
55
path = providers/flagd/test-harness
66
url = https://github.com/open-feature/test-harness.git
7+
branch = v0.5.19
78
[submodule "providers/flagd/spec"]
89
path = providers/flagd/spec
910
url = https://github.com/open-feature/spec.git
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,46 @@
11
package dev.openfeature.contrib.providers.flagd.e2e;
22

3+
import org.apache.logging.log4j.util.Strings;
34
import org.jetbrains.annotations.NotNull;
45
import org.testcontainers.containers.GenericContainer;
56
import org.testcontainers.containers.Network;
67
import org.testcontainers.utility.DockerImageName;
78
import org.testcontainers.utility.MountableFile;
89

9-
import java.io.IOException;
10-
import java.util.Properties;
10+
import java.io.File;
11+
import java.nio.file.Files;
12+
import java.util.List;
1113

1214
public class ContainerConfig {
1315
private static final String version;
1416
private static final Network network = Network.newNetwork();
1517

1618
static {
17-
Properties properties = new Properties();
19+
String path = "test-harness/version.txt";
20+
File file = new File(path);
1821
try {
19-
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("flagdTestbed.properties"));
20-
version = properties.getProperty("version");
21-
} catch (IOException e) {
22+
List<String> lines = Files.readAllLines(file.toPath());
23+
version = lines.get(0);
24+
} catch (Exception e) {
2225
throw new RuntimeException(e);
2326
}
2427
}
2528

29+
2630
/**
27-
*
2831
* @return a {@link org.testcontainers.containers.GenericContainer} instance of a stable sync flagd server with the port 9090 exposed
2932
*/
30-
public static GenericContainer sync() {
33+
public static GenericContainer sync() {
3134
return sync(false, false);
3235
}
3336

3437
/**
35-
*
36-
* @param unstable if an unstable version of the container, which terminates the connection regularly should be used.
38+
* @param unstable if an unstable version of the container, which terminates the connection regularly should be used.
3739
* @param addNetwork if set to true a custom network is attached for cross container access e.g. envoy --> sync:8015
3840
* @return a {@link org.testcontainers.containers.GenericContainer} instance of a sync flagd server with the port 8015 exposed
3941
*/
4042
public static GenericContainer sync(boolean unstable, boolean addNetwork) {
41-
String container = generateContainerName("flagd", unstable);
43+
String container = generateContainerName("flagd", unstable ? "unstable" : "");
4244
GenericContainer genericContainer = new GenericContainer(DockerImageName.parse(container))
4345
.withExposedPorts(8015);
4446

@@ -51,20 +53,18 @@ public static GenericContainer sync(boolean unstable, boolean addNetwork) {
5153
}
5254

5355
/**
54-
*
5556
* @return a {@link org.testcontainers.containers.GenericContainer} instance of a stable flagd server with the port 8013 exposed
5657
*/
5758
public static GenericContainer flagd() {
5859
return flagd(false);
5960
}
6061

6162
/**
62-
*
6363
* @param unstable if an unstable version of the container, which terminates the connection regularly should be used.
6464
* @return a {@link org.testcontainers.containers.GenericContainer} instance of a flagd server with the port 8013 exposed
6565
*/
6666
public static GenericContainer flagd(boolean unstable) {
67-
String container = generateContainerName("flagd", unstable);
67+
String container = generateContainerName("flagd", unstable ? "unstable" : "");
6868
return new GenericContainer(DockerImageName.parse(container))
6969
.withExposedPorts(8013);
7070
}
@@ -73,7 +73,6 @@ public static GenericContainer flagd(boolean unstable) {
7373
/**
7474
* @return a {@link org.testcontainers.containers.GenericContainer} instance of envoy container using
7575
* flagd sync service as backend expose on port 9211
76-
*
7776
*/
7877
public static GenericContainer envoy() {
7978
final String container = "envoyproxy/envoy:v1.31.0";
@@ -85,14 +84,14 @@ public static GenericContainer envoy() {
8584
.withNetworkAliases("envoy");
8685
}
8786

88-
private static @NotNull String generateContainerName(String type, boolean unstable) {
87+
public static @NotNull String generateContainerName(String type, String addition) {
8988
String container = "ghcr.io/open-feature/";
9089
container += type;
9190
container += "-testbed";
92-
if (unstable) {
93-
container += "-unstable";
91+
if (!Strings.isBlank(addition)) {
92+
container += "-" + addition;
9493
}
95-
container += ":" + version;
94+
container += ":v" + version;
9695
return container;
9796
}
9897
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package dev.openfeature.contrib.providers.flagd.e2e;
2+
3+
import org.apache.logging.log4j.core.config.Order;
4+
import org.junit.jupiter.api.Disabled;
5+
import org.junit.platform.suite.api.ConfigurationParameter;
6+
import org.junit.platform.suite.api.IncludeEngines;
7+
import org.junit.platform.suite.api.SelectClasspathResource;
8+
import org.junit.platform.suite.api.Suite;
9+
import org.testcontainers.junit.jupiter.Testcontainers;
10+
11+
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
12+
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
13+
14+
/**
15+
* Class for running the reconnection tests for the RPC provider
16+
*/
17+
@Order(value = Integer.MAX_VALUE)
18+
@Suite(failIfNoTests = false)
19+
@IncludeEngines("cucumber")
20+
//@SelectClasspathResource("features/evaluation.feature")
21+
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
22+
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.ssl.process,dev.openfeature.contrib.providers.flagd.e2e.steps")
23+
@Testcontainers
24+
public class RunFlagdInProcessSSLCucumberTest {
25+
26+
}
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dev.openfeature.contrib.providers.flagd.e2e;
2+
3+
import org.apache.logging.log4j.core.config.Order;
4+
import org.junit.platform.suite.api.ConfigurationParameter;
5+
import org.junit.platform.suite.api.IncludeEngines;
6+
import org.junit.platform.suite.api.SelectClasspathResource;
7+
import org.junit.platform.suite.api.Suite;
8+
import org.testcontainers.junit.jupiter.Testcontainers;
9+
10+
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
11+
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
12+
13+
/**
14+
* Class for running the reconnection tests for the RPC provider
15+
*/
16+
@Order(value = Integer.MAX_VALUE)
17+
@Suite
18+
@IncludeEngines("cucumber")
19+
@SelectClasspathResource("features/evaluation.feature")
20+
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
21+
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.contrib.providers.flagd.e2e.ssl.rpc,dev.openfeature.contrib.providers.flagd.e2e.steps")
22+
@Testcontainers
23+
public class RunFlagdRpcSSLCucumberTest {
24+
25+
}
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package dev.openfeature.contrib.providers.flagd.e2e.ssl.process;
2+
3+
import dev.openfeature.contrib.providers.flagd.Config;
4+
import dev.openfeature.contrib.providers.flagd.FlagdOptions;
5+
import dev.openfeature.contrib.providers.flagd.FlagdProvider;
6+
import dev.openfeature.contrib.providers.flagd.e2e.ContainerConfig;
7+
import dev.openfeature.contrib.providers.flagd.e2e.steps.StepDefinitions;
8+
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType;
9+
import dev.openfeature.sdk.FeatureProvider;
10+
import io.cucumber.java.AfterAll;
11+
import io.cucumber.java.Before;
12+
import io.cucumber.java.BeforeAll;
13+
import org.junit.jupiter.api.Order;
14+
import org.junit.jupiter.api.parallel.Isolated;
15+
import org.testcontainers.containers.GenericContainer;
16+
import org.testcontainers.utility.DockerImageName;
17+
18+
import java.io.File;
19+
20+
@Isolated()
21+
@Order(value = Integer.MAX_VALUE)
22+
public class FlagdInProcessSetup {
23+
private static final GenericContainer flagdContainer =
24+
new GenericContainer(
25+
DockerImageName.parse(
26+
ContainerConfig.generateContainerName("flagd", "ssl")
27+
)
28+
).withExposedPorts(8015);
29+
30+
@BeforeAll()
31+
public static void setups() throws InterruptedException {
32+
flagdContainer.start();
33+
}
34+
35+
@Before()
36+
public static void setupTest() throws InterruptedException {
37+
String path = "test-harness/ssl/custom-root-cert.crt";
38+
39+
File file = new File(path);
40+
String absolutePath = file.getAbsolutePath();
41+
FeatureProvider workingProvider = new FlagdProvider(FlagdOptions.builder()
42+
.resolverType(Config.Resolver.IN_PROCESS)
43+
.port(flagdContainer.getFirstMappedPort())
44+
.deadline(10000)
45+
.streamDeadlineMs(0) // this makes reconnect tests more predictable
46+
.tls(true)
47+
.certPath(absolutePath)
48+
.build());
49+
StepDefinitions.setProvider(workingProvider);
50+
51+
}
52+
53+
@AfterAll
54+
public static void tearDown() {
55+
flagdContainer.stop();
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package dev.openfeature.contrib.providers.flagd.e2e.ssl.rpc;
2+
3+
import dev.openfeature.contrib.providers.flagd.Config;
4+
import dev.openfeature.contrib.providers.flagd.FlagdOptions;
5+
import dev.openfeature.contrib.providers.flagd.FlagdProvider;
6+
import dev.openfeature.contrib.providers.flagd.e2e.ContainerConfig;
7+
import dev.openfeature.contrib.providers.flagd.e2e.steps.StepDefinitions;
8+
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.CacheType;
9+
import dev.openfeature.sdk.FeatureProvider;
10+
import io.cucumber.java.AfterAll;
11+
import io.cucumber.java.Before;
12+
import io.cucumber.java.BeforeAll;
13+
import org.junit.jupiter.api.Order;
14+
import org.junit.jupiter.api.parallel.Isolated;
15+
import org.testcontainers.containers.GenericContainer;
16+
import org.testcontainers.utility.DockerImageName;
17+
18+
import java.io.File;
19+
20+
@Isolated()
21+
@Order(value = Integer.MAX_VALUE)
22+
public class FlagdRpcSetup {
23+
private static final GenericContainer flagdContainer =
24+
new GenericContainer(
25+
DockerImageName.parse(
26+
ContainerConfig.generateContainerName("flagd", "ssl")
27+
)
28+
).withExposedPorts(8013);
29+
30+
@BeforeAll()
31+
public static void setups() throws InterruptedException {
32+
flagdContainer.start();
33+
}
34+
35+
@Before()
36+
public static void setupTest() throws InterruptedException {
37+
String path = "test-harness/ssl/custom-root-cert.crt";
38+
39+
File file = new File(path);
40+
String absolutePath = file.getAbsolutePath();
41+
FeatureProvider workingProvider = new FlagdProvider(FlagdOptions.builder()
42+
.resolverType(Config.Resolver.RPC)
43+
.port(flagdContainer.getFirstMappedPort())
44+
.deadline(10000)
45+
.streamDeadlineMs(0) // this makes reconnect tests more predictable
46+
.tls(true)
47+
.certPath(absolutePath)
48+
.build());
49+
StepDefinitions.setProvider(workingProvider);
50+
51+
}
52+
53+
@AfterAll
54+
public static void tearDown() {
55+
flagdContainer.stop();
56+
}
57+
}

0 commit comments

Comments
 (0)