Skip to content

Commit 0326095

Browse files
authored
fix: blocking in-process init, e2e tests (open-feature#436)
Signed-off-by: Todd Baert <[email protected]>
1 parent a34ad58 commit 0326095

File tree

19 files changed

+343
-220
lines changed

19 files changed

+343
-220
lines changed

.github/workflows/ci.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@ jobs:
1414
services:
1515
# flagd-testbed for flagd-provider e2e tests
1616
flagd:
17-
image: ghcr.io/open-feature/flagd-testbed:latest
17+
image: ghcr.io/open-feature/flagd-testbed:v0.4.0
1818
ports:
1919
- 8013:8013
20+
# sync-testbed for flagd-provider e2e tests
21+
sync:
22+
image: ghcr.io/open-feature/sync-testbed:v0.4.0
23+
ports:
24+
- 9090:9090
2025

2126
steps:
2227
- name: Checkout Repository

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
[submodule "providers/flagd/test-harness"]
55
path = providers/flagd/test-harness
66
url = https://github.com/open-feature/test-harness.git
7+
[submodule "providers/flagd/spec"]
8+
path = providers/flagd/spec
9+
url = https://github.com/open-feature/spec.git

providers/flagd/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ A feature flag daemon with a Unix philosophy.
1717

1818
## Usage
1919

20-
### Remote resolver
20+
### Remote resolver (RPC)
2121

2222
This is the default mode of operation of the provider.
2323
In this mode, `FlagdProvider` communicates with [flagd](https://github.com/open-feature/flagd) via the gRPC protocol.
@@ -41,7 +41,7 @@ Consider following example to create a `FlagdProvider` with in-process evaluatio
4141
```java
4242
FlagdProvider flagdProvider = new FlagdProvider(
4343
FlagdOptions.builder()
44-
.resolverType(Config.ResolverType.IN_PROCESS)
44+
.resolverType(Config.Evaluator.IN_PROCESS)
4545
.build());
4646
```
4747

providers/flagd/pom.xml

+21-4
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@
248248
<goal>exec</goal>
249249
</goals>
250250
<configuration>
251-
<!-- run: git submodule update \-\-init \-\-recursive -->
251+
<!-- run: git submodule update \-\-init test-harness -->
252252
<executable>git</executable>
253253
<arguments>
254254
<argument>submodule</argument>
@@ -259,7 +259,24 @@
259259
</configuration>
260260
</execution>
261261
<execution>
262-
<id>copy-gherkin-tests</id>
262+
<id>update-spec-submodule</id>
263+
<phase>validate</phase>
264+
<goals>
265+
<goal>exec</goal>
266+
</goals>
267+
<configuration>
268+
<!-- run: git submodule update \-\-init spec -->
269+
<executable>git</executable>
270+
<arguments>
271+
<argument>submodule</argument>
272+
<argument>update</argument>
273+
<argument>--init</argument>
274+
<argument>spec</argument>
275+
</arguments>
276+
</configuration>
277+
</execution>
278+
<execution>
279+
<id>copy-gherkin-evaluation.feature</id>
263280
<phase>validate</phase>
264281
<goals>
265282
<goal>exec</goal>
@@ -269,11 +286,11 @@
269286
<!-- run: cp test-harness/features/evaluation.feature src/test/resources/features/ -->
270287
<executable>cp</executable>
271288
<arguments>
272-
<argument>test-harness/features/evaluation.feature</argument>
289+
<argument>spec/specification/assets/gherkin/evaluation.feature</argument>
273290
<argument>src/test/resources/features/</argument>
274291
</arguments>
275292
</configuration>
276-
</execution>
293+
</execution>
277294
</executions>
278295
</plugin>
279296
</plugins>

providers/flagd/spec

Submodule spec added at e2eb2b4

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/Config.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Helper class to hold configuration default values.
55
*/
66
public final class Config {
7-
static final ResolverType DEFAULT_RESOLVER_TYPE = ResolverType.FLAGD;
7+
static final Evaluator DEFAULT_RESOLVER_TYPE = Evaluator.RPC;
88
static final String DEFAULT_PORT = "8013";
99
static final String DEFAULT_TLS = "false";
1010
static final String DEFAULT_HOST = "localhost";
@@ -52,16 +52,18 @@ static int fallBackToEnvOrDefault(String key, int defaultValue) {
5252
}
5353

5454
/**
55-
* flagd resolving type.
55+
* flagd evaluator type.
5656
*/
57-
public enum ResolverType {
57+
public enum Evaluator {
5858
/**
5959
* This is the default resolver type, which connects to flagd instance with flag evaluation gRPC contract.
60+
* Evaluations are performed remotely.
6061
*/
61-
FLAGD,
62+
RPC,
6263
/**
6364
* This is the in-process resolving type, where flags are fetched with flag sync gRPC contract and stored
6465
* locally for in-process evaluation.
66+
* Evaluations are preformed in-process.
6567
*/
6668
IN_PROCESS
6769
}

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdOptions.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import static dev.openfeature.contrib.providers.flagd.Config.TLS_ENV_VAR_NAME;
2626
import static dev.openfeature.contrib.providers.flagd.Config.fallBackToEnvOrDefault;
2727

28-
2928
/**
3029
* FlagdOptions is a builder to build flagd provider options.
3130
* */
@@ -38,7 +37,7 @@ public class FlagdOptions {
3837
* flagd resolving type.
3938
* */
4039
@Builder.Default
41-
private Config.ResolverType resolverType = DEFAULT_RESOLVER_TYPE;
40+
private Config.Evaluator resolverType = DEFAULT_RESOLVER_TYPE;
4241

4342
/**
4443
* flagd connection host.

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdProvider.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public FlagdProvider(final FlagdOptions options) {
4848
case IN_PROCESS:
4949
this.flagResolver = new InProcessResolver(options, this::setState);
5050
break;
51-
case FLAGD:
51+
case RPC:
5252
this.flagResolver =
5353
new GrpcResolver(options, CacheFactory.getCache(options), this::getState, this::setState);
5454
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package dev.openfeature.contrib.providers.flagd.resolver.common;
2+
3+
import java.util.concurrent.atomic.AtomicBoolean;
4+
5+
/**
6+
* Utils for flagd resolvers.
7+
*/
8+
public class Util {
9+
/**
10+
* A helper to block the caller for given conditions.
11+
*
12+
* @param deadline number of milliseconds to block
13+
* @param check {@link AtomicBoolean} to check for status true
14+
*/
15+
public static void busyWaitAndCheck(final Long deadline, final AtomicBoolean check) throws InterruptedException {
16+
long start = System.currentTimeMillis();
17+
18+
do {
19+
if (deadline <= System.currentTimeMillis() - start) {
20+
throw new RuntimeException(
21+
String.format("Deadline exceeded. Condition did not complete within the %d deadline", deadline));
22+
}
23+
24+
Thread.sleep(50L);
25+
} while (!check.get());
26+
}
27+
}

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/grpc/GrpcConnector.java

+2-19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import dev.openfeature.contrib.providers.flagd.FlagdOptions;
44
import dev.openfeature.contrib.providers.flagd.resolver.grpc.cache.Cache;
55
import dev.openfeature.contrib.providers.flagd.resolver.common.ChannelBuilder;
6+
import dev.openfeature.contrib.providers.flagd.resolver.common.Util;
67
import dev.openfeature.flagd.grpc.Schema;
78
import dev.openfeature.flagd.grpc.ServiceGrpc;
89
import dev.openfeature.sdk.ProviderState;
@@ -73,7 +74,7 @@ public void initialize() throws Exception {
7374
eventObserverThread.start();
7475

7576
// block till ready
76-
busyWaitAndCheck(this.deadline, this.connected);
77+
Util.busyWaitAndCheck(this.deadline, this.connected);
7778
}
7879

7980
/**
@@ -160,22 +161,4 @@ private void grpcStateConsumer(final ProviderState state) {
160161
// chain to initiator
161162
this.stateConsumer.accept(state);
162163
}
163-
164-
/**
165-
* A helper to block the caller for given conditions.
166-
*
167-
* @param deadline number of milliseconds to block
168-
* @param check {@link AtomicBoolean} to check for status true
169-
*/
170-
private static void busyWaitAndCheck(final Long deadline, final AtomicBoolean check) throws InterruptedException {
171-
long start = System.currentTimeMillis();
172-
173-
do {
174-
if (deadline <= System.currentTimeMillis() - start) {
175-
throw new RuntimeException(String.format("Initialization not complete after %d ms", deadline));
176-
}
177-
178-
Thread.sleep(50L);
179-
} while (!check.get());
180-
}
181164
}

0 commit comments

Comments
 (0)