88import static org .mockito .Mockito .verify ;
99
1010import dev .openfeature .sdk .internal .TriConsumer ;
11- import java .util .function .Consumer ;
11+ import dev .openfeature .sdk .testutils .TestStackedEmitCallsProvider ;
12+ import io .cucumber .java .AfterAll ;
1213import lombok .SneakyThrows ;
1314import org .junit .jupiter .api .BeforeEach ;
1415import org .junit .jupiter .api .DisplayName ;
@@ -26,6 +27,11 @@ void setup() {
2627 eventProvider .initialize (null );
2728 }
2829
30+ @ AfterAll
31+ public static void resetDefaultProvider () {
32+ OpenFeatureAPI .getInstance ().setProviderAndWait (new NoOpProvider ());
33+ }
34+
2935 @ Test
3036 @ DisplayName ("should run attached onEmit with emitters" )
3137 void emitsEventsWhenAttached () {
@@ -85,105 +91,10 @@ void doesNotThrowWhenOnEmitSame() {
8591 @ Timeout (value = 2 , threadMode = Timeout .ThreadMode .SEPARATE_THREAD )
8692 @ DisplayName ("should not deadlock on emit called during emit" )
8793 void doesNotDeadlockOnEmitStackedCalls () {
88- StackedEmitCallsProvider provider = new StackedEmitCallsProvider ();
94+ TestStackedEmitCallsProvider provider = new TestStackedEmitCallsProvider ();
8995 OpenFeatureAPI .getInstance ().setProviderAndWait (provider );
9096 }
9197
92- static class StackedEmitCallsProvider extends EventProvider {
93- private final NestedBlockingEmitter nestedBlockingEmitter = new NestedBlockingEmitter (this ::onProviderEvent );
94-
95- @ Override
96- public Metadata getMetadata () {
97- return () -> getClass ().getSimpleName ();
98- }
99-
100- @ Override
101- public void initialize (EvaluationContext evaluationContext ) throws Exception {
102- synchronized (nestedBlockingEmitter ) {
103- nestedBlockingEmitter .init ();
104- while (!nestedBlockingEmitter .isReady ()) {
105- try {
106- nestedBlockingEmitter .wait ();
107- } catch (InterruptedException e ) {
108- }
109- }
110- }
111- }
112-
113- private void onProviderEvent (ProviderEvent providerEvent ) {
114- synchronized (nestedBlockingEmitter ) {
115- if (providerEvent == ProviderEvent .PROVIDER_READY ) {
116- nestedBlockingEmitter .setReady ();
117- /*
118- * This line deadlocked in the original implementation without the emitterExecutor see
119- * https://github.com/open-feature/java-sdk/issues/1299
120- */
121- emitProviderReady (ProviderEventDetails .builder ().build ());
122- }
123- }
124- }
125-
126- @ Override
127- public ProviderEvaluation <Boolean > getBooleanEvaluation (
128- String key , Boolean defaultValue , EvaluationContext ctx ) {
129- throw new UnsupportedOperationException ("Unimplemented method 'getBooleanEvaluation'" );
130- }
131-
132- @ Override
133- public ProviderEvaluation <String > getStringEvaluation (String key , String defaultValue , EvaluationContext ctx ) {
134- throw new UnsupportedOperationException ("Unimplemented method 'getStringEvaluation'" );
135- }
136-
137- @ Override
138- public ProviderEvaluation <Integer > getIntegerEvaluation (
139- String key , Integer defaultValue , EvaluationContext ctx ) {
140- throw new UnsupportedOperationException ("Unimplemented method 'getIntegerEvaluation'" );
141- }
142-
143- @ Override
144- public ProviderEvaluation <Double > getDoubleEvaluation (String key , Double defaultValue , EvaluationContext ctx ) {
145- throw new UnsupportedOperationException ("Unimplemented method 'getDoubleEvaluation'" );
146- }
147-
148- @ Override
149- public ProviderEvaluation <Value > getObjectEvaluation (String key , Value defaultValue , EvaluationContext ctx ) {
150- throw new UnsupportedOperationException ("Unimplemented method 'getObjectEvaluation'" );
151- }
152- }
153-
154- static class NestedBlockingEmitter {
155-
156- private final Consumer <ProviderEvent > emitProviderEvent ;
157- private volatile boolean isReady ;
158-
159- public NestedBlockingEmitter (Consumer <ProviderEvent > emitProviderEvent ) {
160- this .emitProviderEvent = emitProviderEvent ;
161- }
162-
163- public void init () {
164- // run init outside monitored thread
165- new Thread (() -> {
166- try {
167- Thread .sleep (500 );
168- } catch (InterruptedException e ) {
169- throw new RuntimeException (e );
170- }
171-
172- emitProviderEvent .accept (ProviderEvent .PROVIDER_READY );
173- })
174- .start ();
175- }
176-
177- public boolean isReady () {
178- return isReady ;
179- }
180-
181- public synchronized void setReady () {
182- isReady = true ;
183- this .notifyAll ();
184- }
185- }
186-
18798 static class TestEventProvider extends EventProvider {
18899
189100 private static final String NAME = "TestEventProvider" ;
0 commit comments