11package dev .openfeature .contrib .providers .flagd .e2e .steps ;
22
3+ import static io .restassured .RestAssured .when ;
4+
35import com .fasterxml .jackson .databind .ObjectMapper ;
46import com .fasterxml .jackson .databind .ObjectReader ;
5- import dev .openfeature .contrib .providers .flagd .Config ;
67import dev .openfeature .contrib .providers .flagd .FlagdProvider ;
78import dev .openfeature .contrib .providers .flagd .e2e .FlagdContainer ;
89import dev .openfeature .contrib .providers .flagd .e2e .State ;
910import dev .openfeature .sdk .FeatureProvider ;
1011import dev .openfeature .sdk .OpenFeatureAPI ;
11- import eu .rekawek .toxiproxy .Proxy ;
12- import eu .rekawek .toxiproxy .ToxiproxyClient ;
13- import eu .rekawek .toxiproxy .model .ToxicDirection ;
1412import io .cucumber .java .After ;
1513import io .cucumber .java .AfterAll ;
1614import io .cucumber .java .Before ;
2220import java .nio .file .Files ;
2321import java .nio .file .Path ;
2422import java .nio .file .Paths ;
25- import java .util .HashMap ;
26- import java .util .Map ;
2723import java .util .Objects ;
28- import java .util .Timer ;
29- import java .util .TimerTask ;
3024import lombok .extern .slf4j .Slf4j ;
3125import org .apache .commons .lang3 .RandomStringUtils ;
3226import org .junit .jupiter .api .parallel .Isolated ;
3327import org .testcontainers .containers .BindMode ;
34- import org .testcontainers .containers .Network ;
35- import org .testcontainers .containers .ToxiproxyContainer ;
3628import org .testcontainers .shaded .org .apache .commons .io .FileUtils ;
3729
3830@ Isolated ()
3931@ Slf4j
4032public class ProviderSteps extends AbstractSteps {
4133
4234 public static final int UNAVAILABLE_PORT = 9999 ;
43- static Map <ProviderType , FlagdContainer > containers = new HashMap <>();
44- public static Network network = Network .newNetwork ();
45- public static ToxiproxyContainer toxiproxy =
46- new ToxiproxyContainer ("ghcr.io/shopify/toxiproxy:2.5.0" ).withNetwork (network );
47- public static ToxiproxyClient toxiproxyClient ;
35+ static FlagdContainer container ;
4836
4937 static Path sharedTempDir ;
5038
5139 public ProviderSteps (State state ) {
5240 super (state );
5341 }
5442
55- static String generateProxyName (Config .Resolver resolver , ProviderType providerType ) {
56- return providerType + "-" + resolver ;
57- }
58-
5943 @ BeforeAll
6044 public static void beforeAll () throws IOException {
61- toxiproxy .start ();
62- toxiproxyClient = new ToxiproxyClient (toxiproxy .getHost (), toxiproxy .getControlPort ());
63- toxiproxyClient .createProxy (
64- generateProxyName (Config .Resolver .RPC , ProviderType .DEFAULT ), "0.0.0.0:8666" , "default:8013" );
65-
66- toxiproxyClient .createProxy (
67- generateProxyName (Config .Resolver .IN_PROCESS , ProviderType .DEFAULT ), "0.0.0.0:8667" , "default:8015" );
68- toxiproxyClient .createProxy (
69- generateProxyName (Config .Resolver .RPC , ProviderType .SSL ), "0.0.0.0:8668" , "ssl:8013" );
70- toxiproxyClient .createProxy (
71- generateProxyName (Config .Resolver .IN_PROCESS , ProviderType .SSL ), "0.0.0.0:8669" , "ssl:8015" );
72-
73- containers .put (
74- ProviderType .DEFAULT , new FlagdContainer ().withNetwork (network ).withNetworkAliases ("default" ));
75- containers .put (
76- ProviderType .SSL , new FlagdContainer ("ssl" ).withNetwork (network ).withNetworkAliases ("ssl" ));
45+
7746 sharedTempDir = Files .createDirectories (
7847 Paths .get ("tmp/" + RandomStringUtils .randomAlphanumeric (8 ).toLowerCase () + "/" ));
79- containers .put (
80- ProviderType .SOCKET ,
81- new FlagdContainer ("socket" )
82- .withFileSystemBind (sharedTempDir .toAbsolutePath ().toString (), "/tmp" , BindMode .READ_WRITE ));
48+ container = new FlagdContainer ()
49+ .withFileSystemBind (sharedTempDir .toAbsolutePath ().toString (), "/tmp" , BindMode .READ_WRITE );
50+ ;
8351 }
8452
8553 @ AfterAll
8654 public static void afterAll () throws IOException {
87-
88- containers .forEach ((name , container ) -> container .stop ());
55+ container .stop ();
8956 FileUtils .deleteDirectory (sharedTempDir .toFile ());
90- toxiproxyClient .reset ();
91- toxiproxy .stop ();
9257 }
9358
9459 @ Before
9560 public void before () throws IOException {
96-
97- toxiproxyClient .getProxies ().forEach (proxy -> {
98- try {
99- proxy .toxics ().getAll ().forEach (toxic -> {
100- try {
101- toxic .remove ();
102- } catch (IOException e ) {
103- log .debug ("Failed to remove timout" , e );
104- }
105- });
106- } catch (IOException e ) {
107- log .debug ("Failed to remove timout" , e );
108- }
109- });
110-
111- containers .values ().stream ()
112- .filter (containers -> !containers .isRunning ())
113- .forEach (FlagdContainer ::start );
61+ if (!container .isRunning ()) {
62+ container .start ();
63+ }
11464 }
11565
11666 @ After
11767 public void tearDown () {
11868 OpenFeatureAPI .getInstance ().shutdown ();
11969 }
12070
121- public int getPort (Config .Resolver resolver , ProviderType providerType ) {
122- switch (resolver ) {
123- case RPC :
124- switch (providerType ) {
125- case DEFAULT :
126- return toxiproxy .getMappedPort (8666 );
127- case SSL :
128- return toxiproxy .getMappedPort (8668 );
129- }
130- case IN_PROCESS :
131- switch (providerType ) {
132- case DEFAULT :
133- return toxiproxy .getMappedPort (8667 );
134- case SSL :
135- return toxiproxy .getMappedPort (8669 );
136- }
137- default :
138- throw new IllegalArgumentException ("Unsupported resolver: " + resolver );
139- }
140- }
141-
14271 @ Given ("a {} flagd provider" )
143- public void setupProvider (String providerType ) throws IOException {
144- state .builder .deadline (500 ).keepAlive (0 ).retryGracePeriod (3 );
72+ public void setupProvider (String providerType ) throws IOException , InterruptedException {
73+ String flagdConfig = "default" ;
74+ state .builder .deadline (1000 ).keepAlive (0 ).retryGracePeriod (3 );
14575 boolean wait = true ;
14676 switch (providerType ) {
14777 case "unavailable" :
@@ -163,9 +93,10 @@ public void setupProvider(String providerType) throws IOException {
16393 String absolutePath = file .getAbsolutePath ();
16494 this .state .providerType = ProviderType .SSL ;
16595 state .builder
166- .port (getPort (State .resolverType , state . providerType ))
96+ .port (container . getPort (State .resolverType ))
16797 .tls (true )
16898 .certPath (absolutePath );
99+ flagdConfig = "ssl" ;
169100 break ;
170101 case "offline" :
171102 File flags = new File ("test-harness/flags" );
@@ -185,9 +116,15 @@ public void setupProvider(String providerType) throws IOException {
185116
186117 default :
187118 this .state .providerType = ProviderType .DEFAULT ;
188- state .builder .port (getPort (State .resolverType , state . providerType ));
119+ state .builder .port (container . getPort (State .resolverType ));
189120 break ;
190121 }
122+ when ().post ("http://" + container .launchpad () + "/start?config={config}" , flagdConfig )
123+ .then ()
124+ .statusCode (200 );
125+
126+ // giving flagd a little time to start
127+ Thread .sleep (100 );
191128 FeatureProvider provider =
192129 new FlagdProvider (state .builder .resolverType (State .resolverType ).build ());
193130
@@ -203,30 +140,15 @@ public void setupProvider(String providerType) throws IOException {
203140 @ When ("the connection is lost for {int}s" )
204141 public void the_connection_is_lost_for (int seconds ) throws InterruptedException , IOException {
205142 log .info ("Timeout and wait for {} seconds" , seconds );
206- String randomizer = RandomStringUtils .randomAlphanumeric (5 );
207- String timeoutUpName = "restart-up-" + randomizer ;
208- String timeoutDownName = "restart-down-" + randomizer ;
209- Proxy proxy = toxiproxyClient .getProxy (generateProxyName (State .resolverType , state .providerType ));
210- proxy .toxics ().timeout (timeoutDownName , ToxicDirection .DOWNSTREAM , seconds );
211- proxy .toxics ().timeout (timeoutUpName , ToxicDirection .UPSTREAM , seconds );
212-
213- TimerTask task = new TimerTask () {
214- public void run () {
215- try {
216- proxy .toxics ().get (timeoutUpName ).remove ();
217- proxy .toxics ().get (timeoutDownName ).remove ();
218- } catch (IOException e ) {
219- log .debug ("Failed to remove timeout" , e );
220- }
221- }
222- };
223- Timer restartTimer = new Timer ("Timer" + randomizer );
224143
225- restartTimer .schedule (task , seconds * 1000L );
144+ when ().post ("http://" + container .launchpad () + "/restart?seconds={seconds}" , seconds )
145+ .then ()
146+ .statusCode (200 );
226147 }
227148
228- static FlagdContainer getContainer (ProviderType providerType ) {
229- log .info ("getting container for {}" , providerType );
230- return containers .getOrDefault (providerType , containers .get (ProviderType .DEFAULT ));
149+ @ When ("the flag was modified" )
150+ public void the_flag_was_modded () {
151+
152+ when ().post ("http://" + container .launchpad () + "/change" ).then ().statusCode (200 );
231153 }
232154}
0 commit comments