diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 3149c89dd..742bf1af4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -21,7 +21,7 @@ jobs: - name: Check out the code uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - - name: Set up JDK 11 + - name: Set up JDK ${{ matrix.build.java }} uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 with: java-version: ${{ matrix.build.java }} diff --git a/pom.xml b/pom.xml index 516a241f0..67b031257 100644 --- a/pom.xml +++ b/pom.xml @@ -193,6 +193,13 @@ test + + com.vmlens + api + 1.2.13 + test + + @@ -239,7 +246,6 @@ pom import - @@ -331,7 +337,6 @@ - @@ -343,6 +348,22 @@ + + com.vmlens + vmlens-maven-plugin + 1.2.13 + + + test + + test + + + true + + + + maven-dependency-plugin 3.8.1 diff --git a/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java b/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java new file mode 100644 index 000000000..136c35965 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java @@ -0,0 +1,77 @@ +package dev.openfeature.sdk.vmlens; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.vmlens.api.AllInterleavings; +import com.vmlens.api.Runner; +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.OpenFeatureAPITestUtil; +import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.providers.memory.Flag; +import dev.openfeature.sdk.providers.memory.InMemoryProvider; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class VmLensTest { + final OpenFeatureAPI api = OpenFeatureAPITestUtil.createAPI(); + + @BeforeEach + void setUp() { + var flags = new HashMap>(); + flags.put("a", Flag.builder().variant("a", "def").defaultVariant("a").build()); + flags.put("b", Flag.builder().variant("a", "as").defaultVariant("a").build()); + api.setProviderAndWait(new InMemoryProvider(flags)); + } + + @AfterEach + void tearDown() { + api.clearHooks(); + api.shutdown(); + } + + @Test + void concurrentClientCreations() { + try (AllInterleavings allInterleavings = new AllInterleavings("Concurrent creations of the Client")) { + while (allInterleavings.hasNext()) { + Runner.runParallel(api::getClient, api::getClient); + } + } + // keep the linter happy + assertTrue(true); + } + + @Test + void concurrentFlagEvaluations() { + var client = api.getClient(); + try (AllInterleavings allInterleavings = new AllInterleavings("Concurrent evaluations")) { + while (allInterleavings.hasNext()) { + Runner.runParallel( + () -> assertEquals("def", client.getStringValue("a", "a")), + () -> assertEquals("as", client.getStringValue("b", "b"))); + } + } + } + + @Test + void concurrentContextSetting() { + var client = api.getClient(); + var contextA = new ImmutableContext(Map.of("a", new Value("b"))); + var contextB = new ImmutableContext(Map.of("c", new Value("d"))); + try (AllInterleavings allInterleavings = + new AllInterleavings("Concurrently setting the context and evaluating a flag")) { + while (allInterleavings.hasNext()) { + Runner.runParallel( + () -> assertEquals("def", client.getStringValue("a", "a")), + () -> client.setEvaluationContext(contextA), + () -> client.setEvaluationContext(contextB)); + assertThat(client.getEvaluationContext()).isIn(contextA, contextB); + } + } + } +}