From 34104275a9a36a3b6b74cfd6e019a80b568d0283 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 02:14:13 +0000 Subject: [PATCH 1/9] chore(deps): update dependency providers/flagd/test-harness to v2.7.0 --- .gitmodules | 2 +- providers/flagd/test-harness | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 1903ae720..2f04ec5c1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "providers/flagd/test-harness"] path = providers/flagd/test-harness url = https://github.com/open-feature/test-harness.git - branch = v2.5.0 + branch = v2.7.0 [submodule "providers/flagd/spec"] path = providers/flagd/spec url = https://github.com/open-feature/spec.git diff --git a/providers/flagd/test-harness b/providers/flagd/test-harness index 9d35a07f4..4008f2dad 160000 --- a/providers/flagd/test-harness +++ b/providers/flagd/test-harness @@ -1 +1 @@ -Subproject commit 9d35a07f43c6b5e1810a5e83029aae62a5dbd494 +Subproject commit 4008f2dadbbe43c6ec623076d65be2908d9b28ad From f28944146c652bf014f19c2c811c8de778fcd103 Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Thu, 20 Mar 2025 13:44:59 +0100 Subject: [PATCH 2/9] chore(flagd): update testharness and add metadata tests Signed-off-by: Simon Schrottner --- .gitmodules | 2 +- .../providers/flagd/e2e/steps/FlagSteps.java | 51 +++++++++++++++++++ .../flagd/e2e/steps/ProviderSteps.java | 15 ++++++ providers/flagd/test-harness | 2 +- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2f04ec5c1..cd4407edf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "providers/flagd/test-harness"] path = providers/flagd/test-harness url = https://github.com/open-feature/test-harness.git - branch = v2.7.0 + branch = v2.7.1 [submodule "providers/flagd/spec"] path = providers/flagd/spec url = https://github.com/open-feature/spec.git diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java index cd0d65afa..4345b3b42 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java @@ -4,11 +4,17 @@ import dev.openfeature.contrib.providers.flagd.e2e.State; import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.ImmutableMetadata; import dev.openfeature.sdk.Value; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import lombok.val; import org.junit.jupiter.api.parallel.Isolated; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; @Isolated() public class FlagSteps extends AbstractSteps { @@ -84,4 +90,49 @@ public Flag(String type, String name, Object defaultValue) { this.type = type; } } + + @Then("the resolved metadata is empty") + @SuppressWarnings("unchecked") + public void the_resolved_metadata_is_empty() throws NoSuchFieldException, IllegalAccessException { + ImmutableMetadata flagMetadata = state.evaluation.getFlagMetadata(); + + Field metadataField = flagMetadata.getClass().getDeclaredField("metadata"); + metadataField.setAccessible(true); + Map metadataMap = (Map) metadataField.get(flagMetadata); + assertThat(metadataMap).isEmpty(); + } + + + @Then("the resolved metadata should contain") + @SuppressWarnings("unchecked") + public void the_resolved_metadata_should_contain(io.cucumber.datatable.DataTable dataTable) + throws IOException, ClassNotFoundException { + + ImmutableMetadata flagMetadata = state.evaluation.getFlagMetadata(); + + List> rows = dataTable.asMaps(String.class, String.class); + for (Map row : rows) { + switch (row.get("metadata_type")) { + case "String": + assertThat(flagMetadata.getString(row.get("key"))).isEqualTo( + Utils.convert(row.get("value"), row.get("metadata_type"))); + break; + case "Boolean": + assertThat(flagMetadata.getBoolean(row.get("key"))).isEqualTo( + Utils.convert(row.get("value"), row.get("metadata_type"))); + break; + case "Float": + assertThat(flagMetadata.getDouble(row.get("key"))).isEqualTo( + Utils.convert(row.get("value"), row.get("metadata_type"))); + break; + case "Integer": + assertThat(flagMetadata.getInteger(row.get("key"))).isEqualTo( + Utils.convert(row.get("value"), row.get("metadata_type"))); + break; + default: + throw new AssertionError("type not supported"); + } + } + } + } diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java index eb837afe1..dd2afec80 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java @@ -3,6 +3,7 @@ import static io.restassured.RestAssured.when; import dev.openfeature.contrib.providers.flagd.Config; +import dev.openfeature.contrib.providers.flagd.FlagdOptions; import dev.openfeature.contrib.providers.flagd.FlagdProvider; import dev.openfeature.contrib.providers.flagd.e2e.FlagdContainer; import dev.openfeature.contrib.providers.flagd.e2e.State; @@ -104,7 +105,21 @@ public void setupProvider(String providerType) throws InterruptedException { .certPath(absolutePath); flagdConfig = "ssl"; break; + case "metadata": + flagdConfig = "metadata"; + if (State.resolverType == Config.Resolver.FILE) { + FlagdOptions build = state.builder.build(); + String selector = build.getSelector(); + String replace = selector.replace("rawflags/", ""); + + state.builder + .port(UNAVAILABLE_PORT) + .offlineFlagSourcePath(new File("test-harness/flags/"+ replace).getAbsolutePath()); + } else { + state.builder.port(container.getPort(State.resolverType)); + } + break; default: this.state.providerType = ProviderType.DEFAULT; if (State.resolverType == Config.Resolver.FILE) { diff --git a/providers/flagd/test-harness b/providers/flagd/test-harness index 4008f2dad..d173ec053 160000 --- a/providers/flagd/test-harness +++ b/providers/flagd/test-harness @@ -1 +1 @@ -Subproject commit 4008f2dadbbe43c6ec623076d65be2908d9b28ad +Subproject commit d173ec0535c94155df4a0bf2ccd0a9cc9f493679 From 261ecf7deaaa18eaed0fb421634f3941844832eb Mon Sep 17 00:00:00 2001 From: "christian.lutnik" Date: Mon, 24 Mar 2025 10:17:25 +0100 Subject: [PATCH 3/9] Fix flaky test by fixing race condition Signed-off-by: christian.lutnik --- .../providers/flagd/e2e/steps/EventSteps.java | 2 +- .../providers/flagd/e2e/steps/FlagSteps.java | 21 ++++++++----------- .../flagd/e2e/steps/ProviderSteps.java | 2 +- .../flagd/resolver/rpc/RpcResolverTest.java | 2 +- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/EventSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/EventSteps.java index 96130c048..32eed5b9d 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/EventSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/EventSteps.java @@ -27,7 +27,7 @@ public EventSteps(State state) { @Given("a {} event handler") public void a_stale_event_handler(String eventType) { state.client.on(mapEventType(eventType), eventDetails -> { - log.info("event tracked for {} at {} ms ", eventType, System.currentTimeMillis() % 100_000); + log.info("{} event tracked", eventType); state.events.add(new Event(eventType, eventDetails)); }); } diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java index 4345b3b42..a596803a0 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java @@ -9,12 +9,11 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; -import lombok.val; -import org.junit.jupiter.api.parallel.Isolated; import java.io.IOException; import java.lang.reflect.Field; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.parallel.Isolated; @Isolated() public class FlagSteps extends AbstractSteps { @@ -102,7 +101,6 @@ public void the_resolved_metadata_is_empty() throws NoSuchFieldException, Illega assertThat(metadataMap).isEmpty(); } - @Then("the resolved metadata should contain") @SuppressWarnings("unchecked") public void the_resolved_metadata_should_contain(io.cucumber.datatable.DataTable dataTable) @@ -114,25 +112,24 @@ public void the_resolved_metadata_should_contain(io.cucumber.datatable.DataTable for (Map row : rows) { switch (row.get("metadata_type")) { case "String": - assertThat(flagMetadata.getString(row.get("key"))).isEqualTo( - Utils.convert(row.get("value"), row.get("metadata_type"))); + assertThat(flagMetadata.getString(row.get("key"))) + .isEqualTo(Utils.convert(row.get("value"), row.get("metadata_type"))); break; case "Boolean": - assertThat(flagMetadata.getBoolean(row.get("key"))).isEqualTo( - Utils.convert(row.get("value"), row.get("metadata_type"))); + assertThat(flagMetadata.getBoolean(row.get("key"))) + .isEqualTo(Utils.convert(row.get("value"), row.get("metadata_type"))); break; case "Float": - assertThat(flagMetadata.getDouble(row.get("key"))).isEqualTo( - Utils.convert(row.get("value"), row.get("metadata_type"))); + assertThat(flagMetadata.getDouble(row.get("key"))) + .isEqualTo(Utils.convert(row.get("value"), row.get("metadata_type"))); break; case "Integer": - assertThat(flagMetadata.getInteger(row.get("key"))).isEqualTo( - Utils.convert(row.get("value"), row.get("metadata_type"))); + assertThat(flagMetadata.getInteger(row.get("key"))) + .isEqualTo(Utils.convert(row.get("value"), row.get("metadata_type"))); break; default: throw new AssertionError("type not supported"); } } } - } diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java index dd2afec80..cc520545b 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java @@ -115,7 +115,7 @@ public void setupProvider(String providerType) throws InterruptedException { state.builder .port(UNAVAILABLE_PORT) - .offlineFlagSourcePath(new File("test-harness/flags/"+ replace).getAbsolutePath()); + .offlineFlagSourcePath(new File("test-harness/flags/" + replace).getAbsolutePath()); } else { state.builder.port(container.getPort(State.resolverType)); } diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolverTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolverTest.java index 19a61c95d..eb9a55c13 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolverTest.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolverTest.java @@ -50,11 +50,11 @@ public void init() throws Exception { when(stub.withDeadlineAfter(anyLong(), any())).thenReturn(stub); doAnswer(new Answer() { public Void answer(InvocationOnMock invocation) { - latch.countDown(); Object[] args = invocation.getArguments(); if (args[1] != null) { observer = (QueueingStreamObserver) args[1]; } + latch.countDown(); return null; } }) From e07a103b83bbcf34b6775822da60c2a707d298cf Mon Sep 17 00:00:00 2001 From: "christian.lutnik" Date: Mon, 24 Mar 2025 11:04:08 +0100 Subject: [PATCH 4/9] Fix test that were silently failing Signed-off-by: christian.lutnik --- .../flagd/FlagdProviderSyncResourcesTest.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdProviderSyncResourcesTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdProviderSyncResourcesTest.java index 6ff6e1765..6258dad37 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdProviderSyncResourcesTest.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdProviderSyncResourcesTest.java @@ -79,13 +79,14 @@ void interruptingWaitingThread_isIgnored() throws InterruptedException { @Test void callingInitialize_wakesUpWaitingThread() throws InterruptedException { final AtomicBoolean isWaiting = new AtomicBoolean(); + final AtomicBoolean successfulTest = new AtomicBoolean(); Thread waitingThread = new Thread(() -> { long start = System.currentTimeMillis(); isWaiting.set(true); flagdProviderSyncResources.waitForInitialization(10000); long end = System.currentTimeMillis(); long duration = end - start; - Assertions.assertTrue(duration < MAX_TIME_TOLERANCE); + successfulTest.set(duration < MAX_TIME_TOLERANCE * 2); }); waitingThread.start(); @@ -98,12 +99,15 @@ void callingInitialize_wakesUpWaitingThread() throws InterruptedException { flagdProviderSyncResources.initialize(); waitingThread.join(); + + Assertions.assertTrue(successfulTest.get()); } @Timeout(2) @Test void callingShutdown_wakesUpWaitingThreadWithException() throws InterruptedException { final AtomicBoolean isWaiting = new AtomicBoolean(); + final AtomicBoolean successfulTest = new AtomicBoolean(); Thread waitingThread = new Thread(() -> { long start = System.currentTimeMillis(); isWaiting.set(true); @@ -112,7 +116,7 @@ void callingShutdown_wakesUpWaitingThreadWithException() throws InterruptedExcep long end = System.currentTimeMillis(); long duration = end - start; - Assertions.assertTrue(duration < MAX_TIME_TOLERANCE); + successfulTest.set(duration < MAX_TIME_TOLERANCE * 2); }); waitingThread.start(); @@ -125,6 +129,8 @@ void callingShutdown_wakesUpWaitingThreadWithException() throws InterruptedExcep flagdProviderSyncResources.shutdown(); waitingThread.join(); + + Assertions.assertTrue(successfulTest.get()); } @Timeout(2) From cc426ea4343e312d3e379d2b20941c85a42e69ac Mon Sep 17 00:00:00 2001 From: "christian.lutnik" Date: Mon, 24 Mar 2025 12:49:20 +0100 Subject: [PATCH 5/9] experiment with circumventing singleton Signed-off-by: christian.lutnik --- .../flagd/e2e/steps/ProviderSteps.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java index cc520545b..2b38be6a4 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java @@ -17,6 +17,8 @@ import io.cucumber.java.en.When; import java.io.File; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -139,12 +141,25 @@ public void setupProvider(String providerType) throws InterruptedException { .then() .statusCode(200); - // giving flagd a little time to start - Thread.sleep(300); FeatureProvider provider = new FlagdProvider(state.builder.resolverType(State.resolverType).build()); String providerName = "Provider " + Math.random(); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + OpenFeatureAPI api; // = OpenFeatureAPI.getInstance(); + + try { + Constructor constructor = OpenFeatureAPI.class.getDeclaredConstructor(); + constructor.setAccessible(true); + api = constructor.newInstance(); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + if (wait) { api.setProviderAndWait(providerName, provider); } else { @@ -166,10 +181,7 @@ public void the_connection_is_lost_for(int seconds) { } @When("the flag was modified") - public void the_flag_was_modded() throws InterruptedException { + public void the_flag_was_modded() { when().post("http://" + container.getLaunchpadUrl() + "/change").then().statusCode(200); - - // we might be too fast in the execution - Thread.sleep(1000); } } From 25a86508f15b0f6d6bb615349c36a63c7b67690c Mon Sep 17 00:00:00 2001 From: "christian.lutnik" Date: Mon, 24 Mar 2025 14:49:25 +0100 Subject: [PATCH 6/9] do not access cache if it is disabled Signed-off-by: christian.lutnik --- .../flagd/resolver/rpc/cache/Cache.java | 12 +++++++++++ .../flagd/e2e/steps/ProviderSteps.java | 20 +++---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java index 45d27fac1..73b341606 100644 --- a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java +++ b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java @@ -37,18 +37,30 @@ public Cache(final String forType, int maxCacheSize) { } public void put(String key, ProviderEvaluation value) { + if (Boolean.FALSE.equals(enabled)) { + return; + } this.store.put(key, value); } public ProviderEvaluation get(String key) { + if (Boolean.FALSE.equals(enabled)) { + return null; + } return this.store.get(key); } public void remove(String key) { + if (Boolean.FALSE.equals(enabled)) { + return; + } this.store.remove(key); } public void clear() { + if (Boolean.FALSE.equals(enabled)) { + return; + } this.store.clear(); } } diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java index 2b38be6a4..8a4650c50 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java @@ -17,8 +17,6 @@ import io.cucumber.java.en.When; import java.io.File; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -141,24 +139,12 @@ public void setupProvider(String providerType) throws InterruptedException { .then() .statusCode(200); + Thread.sleep(300); + FeatureProvider provider = new FlagdProvider(state.builder.resolverType(State.resolverType).build()); String providerName = "Provider " + Math.random(); - OpenFeatureAPI api; // = OpenFeatureAPI.getInstance(); - - try { - Constructor constructor = OpenFeatureAPI.class.getDeclaredConstructor(); - constructor.setAccessible(true); - api = constructor.newInstance(); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } + OpenFeatureAPI api = OpenFeatureAPI.getInstance(); if (wait) { api.setProviderAndWait(providerName, provider); From 7407658259d5f834bcc13c9684c3fbd588175b25 Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 25 Mar 2025 12:00:38 +0100 Subject: [PATCH 7/9] fixup: update harness and minor tweaks Signed-off-by: Simon Schrottner --- .../providers/flagd/resolver/rpc/RpcResolver.java | 6 +++--- .../providers/flagd/resolver/rpc/cache/Cache.java | 10 +++++----- .../contrib/providers/flagd/e2e/steps/FlagSteps.java | 5 +++++ .../providers/flagd/e2e/steps/ProviderSteps.java | 2 +- .../providers/flagd/resolver/rpc/cache/CacheTest.java | 6 +++--- providers/flagd/test-harness | 2 +- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolver.java b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolver.java index 580281d4d..466c26359 100644 --- a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolver.java +++ b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/RpcResolver.java @@ -263,14 +263,14 @@ private ProviderEvaluation Boolean isEvaluationCacheable(ProviderEvaluation evaluation) { + private boolean isEvaluationCacheable(ProviderEvaluation evaluation) { String reason = evaluation.getReason(); return reason != null && reason.equals(Config.STATIC_REASON) && this.cacheAvailable(); } - private Boolean cacheAvailable() { - return this.cache.getEnabled(); + private boolean cacheAvailable() { + return this.cache.isEnabled(); } private static ImmutableMetadata metadataFromResponse(Message response) { diff --git a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java index 73b341606..06b19db57 100644 --- a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java +++ b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java @@ -16,7 +16,7 @@ public class Cache { private Map> store; @Getter - private final Boolean enabled; + private final boolean enabled; /** * Initialize the cache. @@ -37,28 +37,28 @@ public Cache(final String forType, int maxCacheSize) { } public void put(String key, ProviderEvaluation value) { - if (Boolean.FALSE.equals(enabled)) { + if (!enabled) { return; } this.store.put(key, value); } public ProviderEvaluation get(String key) { - if (Boolean.FALSE.equals(enabled)) { + if (!enabled) { return null; } return this.store.get(key); } public void remove(String key) { - if (Boolean.FALSE.equals(enabled)) { + if (!enabled) { return; } this.store.remove(key); } public void clear() { - if (Boolean.FALSE.equals(enabled)) { + if (!enabled) { return; } this.store.clear(); diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java index a596803a0..24f7b0e08 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/FlagSteps.java @@ -13,8 +13,10 @@ import java.lang.reflect.Field; import java.util.List; import java.util.Map; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.parallel.Isolated; +@Slf4j @Isolated() public class FlagSteps extends AbstractSteps { @@ -59,6 +61,9 @@ public void the_flag_was_evaluated_with_details() throws InterruptedException { @Then("the resolved details value should be \"{}\"") public void the_resolved_details_value_should_be(String value) throws Throwable { + if (state.evaluation.getErrorCode() != null) { + log.warn(state.evaluation.getErrorMessage()); + } assertThat(state.evaluation.getValue()).isEqualTo(Utils.convert(value, state.flag.type)); } diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java index 8a4650c50..38585d805 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java @@ -139,7 +139,7 @@ public void setupProvider(String providerType) throws InterruptedException { .then() .statusCode(200); - Thread.sleep(300); + Thread.sleep(20); FeatureProvider provider = new FlagdProvider(state.builder.resolverType(State.resolverType).build()); diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/CacheTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/CacheTest.java index ede1542b7..476fae408 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/CacheTest.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/CacheTest.java @@ -20,9 +20,9 @@ void cacheTypeTest() { final Cache undefined = new Cache("invalid", 10); // then - assertTrue(lru.getEnabled()); - assertFalse(disabled.getEnabled()); - assertFalse(undefined.getEnabled()); + assertTrue(lru.isEnabled()); + assertFalse(disabled.isEnabled()); + assertFalse(undefined.isEnabled()); } @Test diff --git a/providers/flagd/test-harness b/providers/flagd/test-harness index d173ec053..5f3f68931 160000 --- a/providers/flagd/test-harness +++ b/providers/flagd/test-harness @@ -1 +1 @@ -Subproject commit d173ec0535c94155df4a0bf2ccd0a9cc9f493679 +Subproject commit 5f3f6893108daed3b510952e97c5429ad1897d8e From 66c4b367a12c2000a05692930320175bd8830834 Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 25 Mar 2025 12:00:38 +0100 Subject: [PATCH 8/9] fixup: update harness and minor tweaks Signed-off-by: Simon Schrottner --- providers/flagd/schemas | 2 +- providers/flagd/spec | 2 +- .../contrib/providers/flagd/e2e/steps/ProviderSteps.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/providers/flagd/schemas b/providers/flagd/schemas index 9b0ee43ec..e840a037d 160000 --- a/providers/flagd/schemas +++ b/providers/flagd/schemas @@ -1 +1 @@ -Subproject commit 9b0ee43ecc477e277d41770034fa495ec78838fe +Subproject commit e840a037dc49801185217f45cc404fc8ff2cd0d4 diff --git a/providers/flagd/spec b/providers/flagd/spec index 130df3eb6..aad6193d7 160000 --- a/providers/flagd/spec +++ b/providers/flagd/spec @@ -1 +1 @@ -Subproject commit 130df3eb61f1b8d1a121d54f33563ce0ec27c1b6 +Subproject commit aad6193d77eca269bc5a8dc0a0b626dbf98d924b diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java index 38585d805..ae16290d5 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/e2e/steps/ProviderSteps.java @@ -139,7 +139,7 @@ public void setupProvider(String providerType) throws InterruptedException { .then() .statusCode(200); - Thread.sleep(20); + Thread.sleep(50); FeatureProvider provider = new FlagdProvider(state.builder.resolverType(State.resolverType).build()); From fc0ae713723749da3a955f3091221597d41fb3c8 Mon Sep 17 00:00:00 2001 From: "christian.lutnik" Date: Tue, 25 Mar 2025 12:52:44 +0100 Subject: [PATCH 9/9] add javadoc Signed-off-by: christian.lutnik --- .../flagd/resolver/rpc/cache/Cache.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java index 06b19db57..068ce65de 100644 --- a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java +++ b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/rpc/cache/Cache.java @@ -21,7 +21,7 @@ public class Cache { /** * Initialize the cache. * - * @param forType type of the cache. + * @param forType type of the cache. * @param maxCacheSize max amount of element to keep. */ public Cache(final String forType, int maxCacheSize) { @@ -36,6 +36,12 @@ public Cache(final String forType, int maxCacheSize) { } } + /** + * Adds a provider evaluation to the cache. + * + * @param key the key of the flag + * @param value the provider evaluation + */ public void put(String key, ProviderEvaluation value) { if (!enabled) { return; @@ -43,6 +49,11 @@ public void put(String key, ProviderEvaluation value) { this.store.put(key, value); } + /** + * Retrieves a provider evaluation from the cache, or null if the key has not been cached before. + * + * @param key the key of the flag + */ public ProviderEvaluation get(String key) { if (!enabled) { return null; @@ -50,6 +61,11 @@ public ProviderEvaluation get(String key) { return this.store.get(key); } + /** + * Removes a provider evaluation from the cache. + * + * @param key the key of the flag + */ public void remove(String key) { if (!enabled) { return; @@ -57,6 +73,9 @@ public void remove(String key) { this.store.remove(key); } + /** + * Clears the cache. + */ public void clear() { if (!enabled) { return;