-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathOpenFeatureAPITest.java
More file actions
155 lines (124 loc) · 6.49 KB
/
OpenFeatureAPITest.java
File metadata and controls
155 lines (124 loc) · 6.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package dev.openfeature.sdk;
import static dev.openfeature.sdk.ProviderEvent.PROVIDER_CONFIGURATION_CHANGED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import dev.openfeature.sdk.testutils.testProvider.TestProvider;
import java.util.HashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
class OpenFeatureAPITest {
private static final String DOMAIN_NAME = "my domain";
private OpenFeatureAPI api;
@BeforeEach
void setupTest() {
api = new OpenFeatureAPI();
}
@Test
void namedProviderTest() {
var provider = TestProvider.builder().initsToReady();
api.setProviderAndWait("namedProviderTest", provider);
assertThat(provider.getMetadata().getName())
.isEqualTo(api.getProviderMetadata("namedProviderTest").getName());
}
@Specification(
number = "1.1.3",
text =
"The API MUST provide a function to bind a given provider to one or more clients using a domain. If the domain already has a bound provider, it is overwritten with the new mapping.")
@Test
void namedProviderOverwrittenTest() {
String domain = "namedProviderOverwrittenTest";
var provider1 = TestProvider.builder().withName("provider1").initsToReady();
var provider2 = TestProvider.builder().withName("provider2").initsToReady();
api.setProviderAndWait(domain, provider1);
api.setProviderAndWait(domain, provider2);
assertThat(api.getProvider(domain).getMetadata().getName())
.isEqualTo(provider2.getMetadata().getName());
}
@Test
void providerToMultipleNames() throws Exception {
var inMemAsEventingProvider = TestProvider.builder().initsToReady();
var noOpAsNonEventingProvider = TestProvider.builder().initsToReady();
// register same provider for multiple names & as default provider
api.setProviderAndWait(inMemAsEventingProvider);
api.setProviderAndWait("clientA", inMemAsEventingProvider);
api.setProviderAndWait("clientB", inMemAsEventingProvider);
api.setProviderAndWait("clientC", noOpAsNonEventingProvider);
api.setProviderAndWait("clientD", noOpAsNonEventingProvider);
assertEquals(inMemAsEventingProvider, api.getProvider());
assertEquals(inMemAsEventingProvider, api.getProvider("clientA"));
assertEquals(inMemAsEventingProvider, api.getProvider("clientB"));
assertEquals(noOpAsNonEventingProvider, api.getProvider("clientC"));
assertEquals(noOpAsNonEventingProvider, api.getProvider("clientD"));
}
@Test
void settingDefaultProviderToNullErrors() {
assertThatCode(() -> api.setProvider(null)).isInstanceOf(IllegalArgumentException.class);
}
@Test
void settingDomainProviderToNullErrors() {
assertThatCode(() -> api.setProvider(DOMAIN_NAME, null)).isInstanceOf(IllegalArgumentException.class);
}
@Test
void settingTransactionalContextPropagatorToNullErrors() {
assertThatCode(() -> api.setTransactionContextPropagator(null)).isInstanceOf(IllegalArgumentException.class);
}
@Test
void setEvaluationContextShouldAllowChaining() {
OpenFeatureClient client = new OpenFeatureClient(api, "name", "version");
EvaluationContext ctx = new ImmutableContext("targeting key", new HashMap<>());
OpenFeatureClient result = client.setEvaluationContext(ctx);
assertEquals(client, result);
}
@Test
void getStateReturnsTheStateOfTheAppropriateProvider() throws Exception {
String domain = "namedProviderOverwrittenTest";
var provider1 = TestProvider.builder().initsToReady();
var provider2 = TestProvider.builder().initsToReady();
api.setProviderAndWait(domain, provider1);
api.setProviderAndWait(domain, provider2);
provider2.initialize(null);
assertThat(api.getClient(domain).getProviderState()).isEqualTo(ProviderState.READY);
}
@Test
void featureProviderTrackIsCalled() throws Exception {
FeatureProvider featureProvider = mock(FeatureProvider.class);
api.setProviderAndWait(featureProvider);
api.getClient().track("track-event", new ImmutableContext(), new MutableTrackingEventDetails(22.2f));
verify(featureProvider).initialize(any());
verify(featureProvider, times(2)).getMetadata();
verify(featureProvider).track(any(), any(), any());
}
@Test
@DisplayName(
"Domainless provider initialized after domain provider - OnConfigurationChanged handlers are invoked for both providers after emitting PROVIDER_CONFIGURATION_CHANGED")
void onConfigurationChangedAreCalledForDomainlessAndDomainProviders() throws InterruptedException {
EventProvider domainlessFeatureProvider = spy(EventProvider.class);
EventProvider featureProvider = spy(EventProvider.class);
Client domainlessClient = api.getClient();
Client client = api.getClient("domain");
CountDownLatch domainlessLatch = new CountDownLatch(1);
CountDownLatch latch = new CountDownLatch(1);
domainlessClient.onProviderConfigurationChanged(eventDetails -> domainlessLatch.countDown());
client.onProviderConfigurationChanged(eventDetails -> latch.countDown());
api.setProviderAndWait("domain", featureProvider);
api.setProviderAndWait(domainlessFeatureProvider);
featureProvider.emit(PROVIDER_CONFIGURATION_CHANGED, mock(ProviderEventDetails.class));
domainlessFeatureProvider.emit(PROVIDER_CONFIGURATION_CHANGED, mock(ProviderEventDetails.class));
boolean domainlessCompleted = domainlessLatch.await(5, TimeUnit.SECONDS);
assertTrue(
domainlessCompleted,
"onProviderConfigurationChanged was not be invoked for a client with default domain");
boolean completed = latch.await(5, TimeUnit.SECONDS);
assertTrue(completed, "onProviderConfigurationChanged was not be invoked for a client with domain 'domain'");
}
}