Skip to content

Commit a1a064b

Browse files
authored
Migrate feature-flagging groovy tests to java (#11716)
Migrate feature-flagging groovy tests to java Address flaky test Merge branch 'master' into sarahchen6/migrate-feature-flagging-tests-to-java Merge branch 'master' into sarahchen6/migrate-feature-flagging-tests-to-java Merge branch 'master' into sarahchen6/migrate-feature-flagging-tests-to-java Clean up pt1 Clean up pt2 Clean up pt3 Clean up pt4 Wait for flush in both cases of testFailuresAreRetried Add VisibleForTesting annotation Merge branch 'master' into sarahchen6/migrate-feature-flagging-tests-to-java Merge branch 'master' into sarahchen6/migrate-feature-flagging-tests-to-java Update to use test-utils polling Co-authored-by: sarah.chen <sarah.chen@datadoghq.com>
1 parent 35096e2 commit a1a064b

11 files changed

Lines changed: 810 additions & 709 deletions

File tree

products/feature-flagging/feature-flagging-agent/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ dependencies {
1616
api(project(":products:feature-flagging:feature-flagging-lib"))
1717
api(project(":internal-api"))
1818

19+
testImplementation(libs.bundles.junit5)
20+
testImplementation(libs.bundles.mockito)
1921
testImplementation(project(":utils:test-utils"))
2022
testRuntimeOnly(project(":dd-trace-core"))
2123
}

products/feature-flagging/feature-flagging-agent/src/test/groovy/com/datadog/featureflag/FeatureFlaggingSystemTest.groovy

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.datadog.featureflag;
2+
3+
import static datadog.trace.api.config.RemoteConfigConfig.REMOTE_CONFIGURATION_ENABLED;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.ArgumentMatchers.eq;
7+
import static org.mockito.Mockito.mock;
8+
import static org.mockito.Mockito.verify;
9+
import static org.mockito.Mockito.when;
10+
11+
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
12+
import datadog.communication.ddagent.SharedCommunicationObjects;
13+
import datadog.remoteconfig.Capabilities;
14+
import datadog.remoteconfig.ConfigurationDeserializer;
15+
import datadog.remoteconfig.ConfigurationPoller;
16+
import datadog.remoteconfig.Product;
17+
import datadog.trace.api.Config;
18+
import datadog.trace.junit.utils.config.WithConfig;
19+
import okhttp3.HttpUrl;
20+
import okhttp3.OkHttpClient;
21+
import org.junit.jupiter.api.Test;
22+
23+
class FeatureFlaggingSystemTest {
24+
25+
@Test
26+
void testFeatureFlagSystemInitialization() {
27+
ConfigurationPoller poller = mock(ConfigurationPoller.class);
28+
DDAgentFeaturesDiscovery discovery = mock(DDAgentFeaturesDiscovery.class);
29+
SharedCommunicationObjects sharedCommunicationObjects = mock(SharedCommunicationObjects.class);
30+
when(discovery.supportsEvpProxy()).thenReturn(true);
31+
when(discovery.getEvpProxyEndpoint()).thenReturn("/evp_proxy/");
32+
when(sharedCommunicationObjects.configurationPoller(any(Config.class))).thenReturn(poller);
33+
when(sharedCommunicationObjects.featuresDiscovery(any(Config.class))).thenReturn(discovery);
34+
sharedCommunicationObjects.agentUrl = HttpUrl.get("http://localhost");
35+
sharedCommunicationObjects.agentHttpClient = new OkHttpClient.Builder().build();
36+
37+
FeatureFlaggingSystem.start(sharedCommunicationObjects);
38+
39+
verify(poller).addCapabilities(Capabilities.CAPABILITY_FFE_FLAG_CONFIGURATION_RULES);
40+
verify(poller).addListener(eq(Product.FFE_FLAGS), any(ConfigurationDeserializer.class), any());
41+
verify(poller).start();
42+
43+
FeatureFlaggingSystem.stop();
44+
45+
verify(poller).removeCapabilities(Capabilities.CAPABILITY_FFE_FLAG_CONFIGURATION_RULES);
46+
verify(poller).removeListeners(Product.FFE_FLAGS);
47+
verify(poller).stop();
48+
}
49+
50+
@Test
51+
@WithConfig(key = REMOTE_CONFIGURATION_ENABLED, value = "false")
52+
void testThatRemoteConfigIsRequired() {
53+
SharedCommunicationObjects sharedCommunicationObjects = mock(SharedCommunicationObjects.class);
54+
55+
try {
56+
assertThrows(
57+
IllegalStateException.class,
58+
() -> FeatureFlaggingSystem.start(sharedCommunicationObjects));
59+
} finally {
60+
FeatureFlaggingSystem.stop();
61+
}
62+
}
63+
}

products/feature-flagging/feature-flagging-bootstrap/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,7 @@ extra["excludedClassesCoverage"] = listOf(
3030
)
3131

3232
dependencies {
33+
testImplementation(libs.bundles.junit5)
34+
testImplementation(libs.bundles.mockito)
3335
testImplementation(project(":utils:test-utils"))
3436
}

products/feature-flagging/feature-flagging-bootstrap/src/test/groovy/datadog/trace/api/featureflag/FeatureFlaggingGatewayTest.groovy

Lines changed: 0 additions & 76 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package datadog.trace.api.featureflag;
2+
3+
import static org.mockito.Mockito.mock;
4+
import static org.mockito.Mockito.verify;
5+
import static org.mockito.Mockito.verifyNoMoreInteractions;
6+
7+
import datadog.trace.api.featureflag.exposure.ExposureEvent;
8+
import datadog.trace.api.featureflag.ufc.v1.ServerConfiguration;
9+
import org.junit.jupiter.api.AfterEach;
10+
import org.junit.jupiter.api.BeforeEach;
11+
import org.junit.jupiter.api.Test;
12+
13+
class FeatureFlaggingGatewayTest {
14+
15+
private FeatureFlaggingGateway.ConfigListener configListener;
16+
private FeatureFlaggingGateway.ExposureListener exposureListener;
17+
private ServerConfiguration firstConfiguration;
18+
private ServerConfiguration secondConfiguration;
19+
private ExposureEvent firstExposure;
20+
private ExposureEvent secondExposure;
21+
22+
@BeforeEach
23+
void setUp() {
24+
configListener = mock(FeatureFlaggingGateway.ConfigListener.class);
25+
exposureListener = mock(FeatureFlaggingGateway.ExposureListener.class);
26+
firstConfiguration = mock(ServerConfiguration.class);
27+
secondConfiguration = mock(ServerConfiguration.class);
28+
firstExposure = mock(ExposureEvent.class);
29+
secondExposure = mock(ExposureEvent.class);
30+
}
31+
32+
@AfterEach
33+
void tearDown() {
34+
FeatureFlaggingGateway.removeConfigListener(configListener);
35+
FeatureFlaggingGateway.removeExposureListener(exposureListener);
36+
}
37+
38+
@Test
39+
void testAttachingAConfigListener() {
40+
clearCurrentServerConfiguration();
41+
42+
FeatureFlaggingGateway.addConfigListener(configListener);
43+
FeatureFlaggingGateway.dispatch(firstConfiguration);
44+
45+
verify(configListener).accept(firstConfiguration);
46+
verifyNoMoreInteractions(configListener);
47+
48+
FeatureFlaggingGateway.dispatch(secondConfiguration);
49+
50+
verify(configListener).accept(secondConfiguration);
51+
verifyNoMoreInteractions(configListener);
52+
}
53+
54+
@Test
55+
void testAttachingAListenerAfterConfigured() {
56+
FeatureFlaggingGateway.dispatch(firstConfiguration);
57+
FeatureFlaggingGateway.addConfigListener(configListener);
58+
59+
verify(configListener).accept(firstConfiguration);
60+
verifyNoMoreInteractions(configListener);
61+
}
62+
63+
@Test
64+
void testAttachingAnExposureListener() {
65+
FeatureFlaggingGateway.addExposureListener(exposureListener);
66+
FeatureFlaggingGateway.dispatch(firstExposure);
67+
68+
verify(exposureListener).accept(firstExposure);
69+
verifyNoMoreInteractions(exposureListener);
70+
71+
FeatureFlaggingGateway.dispatch(secondExposure);
72+
73+
verify(exposureListener).accept(secondExposure);
74+
verifyNoMoreInteractions(exposureListener);
75+
}
76+
77+
private static void clearCurrentServerConfiguration() {
78+
FeatureFlaggingGateway.dispatch((ServerConfiguration) null);
79+
}
80+
}

products/feature-flagging/feature-flagging-lib/src/main/java/com/datadog/featureflag/ExposureWriterImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import datadog.trace.api.featureflag.exposure.ExposureEvent;
1717
import datadog.trace.api.featureflag.exposure.ExposuresRequest;
1818
import datadog.trace.api.intake.Intake;
19+
import datadog.trace.api.internal.VisibleForTesting;
1920
import java.util.ArrayList;
2021
import java.util.HashMap;
2122
import java.util.List;
@@ -84,6 +85,16 @@ public void accept(final ExposureEvent event) {
8485
queue.offer(event);
8586
}
8687

88+
@VisibleForTesting
89+
boolean isSerializerThreadAlive() {
90+
return serializerThread.isAlive();
91+
}
92+
93+
@VisibleForTesting
94+
int queueSize() {
95+
return queue.size();
96+
}
97+
8798
private static class ExposureSerializingHandler implements Runnable {
8899
private final MessagePassingBlockingQueue<ExposureEvent> queue;
89100
private final long ticksRequiredToFlush;

0 commit comments

Comments
 (0)