This repository has been archived by the owner on May 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #132 from launchdarkly/eb/ch45321/polling-tests
add polling mode tests and end-to-end streaming test
- Loading branch information
Showing
6 changed files
with
348 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
src/test/java/com/launchdarkly/client/FeatureRequestorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package com.launchdarkly.client; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
import static com.launchdarkly.client.TestHttpUtil.baseConfig; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotNull; | ||
import static org.junit.Assert.assertNull; | ||
|
||
import okhttp3.mockwebserver.MockResponse; | ||
import okhttp3.mockwebserver.MockWebServer; | ||
import okhttp3.mockwebserver.RecordedRequest; | ||
|
||
public class FeatureRequestorTest { | ||
private static final String sdkKey = "sdk-key"; | ||
private static final String flag1Key = "flag1"; | ||
private static final String flag1Json = "{\"key\":\"" + flag1Key + "\"}"; | ||
private static final String flagsJson = "{\"" + flag1Key + "\":" + flag1Json + "}"; | ||
private static final String segment1Key = "segment1"; | ||
private static final String segment1Json = "{\"key\":\"" + segment1Key + "\"}"; | ||
private static final String segmentsJson = "{\"" + segment1Key + "\":" + segment1Json + "}"; | ||
private static final String allDataJson = "{\"flags\":" + flagsJson + ",\"segments\":" + segmentsJson + "}"; | ||
|
||
@Test | ||
public void requestAllData() throws Exception { | ||
MockResponse resp = new MockResponse(); | ||
resp.setHeader("Content-Type", "application/json"); | ||
resp.setBody(allDataJson); | ||
|
||
try (MockWebServer server = TestHttpUtil.makeStartedServer(resp)) { | ||
FeatureRequestor r = new FeatureRequestor(sdkKey, basePollingConfig(server).build()); | ||
|
||
FeatureRequestor.AllData data = r.getAllData(); | ||
|
||
RecordedRequest req = server.takeRequest(); | ||
assertEquals("/sdk/latest-all", req.getPath()); | ||
verifyHeaders(req); | ||
|
||
assertNotNull(data); | ||
assertNotNull(data.flags); | ||
assertNotNull(data.segments); | ||
assertEquals(1, data.flags.size()); | ||
assertEquals(1, data.flags.size()); | ||
verifyFlag(data.flags.get(flag1Key), flag1Key); | ||
verifySegment(data.segments.get(segment1Key), segment1Key); | ||
} | ||
} | ||
|
||
@Test | ||
public void requestFlag() throws Exception { | ||
MockResponse resp = new MockResponse(); | ||
resp.setHeader("Content-Type", "application/json"); | ||
resp.setBody(flag1Json); | ||
|
||
try (MockWebServer server = TestHttpUtil.makeStartedServer(resp)) { | ||
FeatureRequestor r = new FeatureRequestor(sdkKey, basePollingConfig(server).build()); | ||
|
||
FeatureFlag flag = r.getFlag(flag1Key); | ||
|
||
RecordedRequest req = server.takeRequest(); | ||
assertEquals("/sdk/latest-flags/" + flag1Key, req.getPath()); | ||
verifyHeaders(req); | ||
|
||
verifyFlag(flag, flag1Key); | ||
} | ||
} | ||
|
||
@Test | ||
public void requestSegment() throws Exception { | ||
MockResponse resp = new MockResponse(); | ||
resp.setHeader("Content-Type", "application/json"); | ||
resp.setBody(segment1Json); | ||
|
||
try (MockWebServer server = TestHttpUtil.makeStartedServer(resp)) { | ||
FeatureRequestor r = new FeatureRequestor(sdkKey, basePollingConfig(server).build()); | ||
|
||
Segment segment = r.getSegment(segment1Key); | ||
|
||
RecordedRequest req = server.takeRequest(); | ||
assertEquals("/sdk/latest-segments/" + segment1Key, req.getPath()); | ||
verifyHeaders(req); | ||
|
||
verifySegment(segment, segment1Key); | ||
} | ||
} | ||
|
||
@Test | ||
public void requestFlagNotFound() throws Exception { | ||
MockResponse notFoundResp = new MockResponse().setResponseCode(404); | ||
|
||
try (MockWebServer server = TestHttpUtil.makeStartedServer(notFoundResp)) { | ||
FeatureRequestor r = new FeatureRequestor(sdkKey, basePollingConfig(server).build()); | ||
|
||
try { | ||
r.getFlag(flag1Key); | ||
Assert.fail("expected exception"); | ||
} catch (HttpErrorException e) { | ||
assertEquals(404, e.getStatus()); | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
public void requestSegmentNotFound() throws Exception { | ||
MockResponse notFoundResp = new MockResponse().setResponseCode(404); | ||
|
||
try (MockWebServer server = TestHttpUtil.makeStartedServer(notFoundResp)) { | ||
FeatureRequestor r = new FeatureRequestor(sdkKey, basePollingConfig(server).build()); | ||
|
||
try { | ||
r.getSegment(segment1Key); | ||
Assert.fail("expected exception"); | ||
} catch (HttpErrorException e) { | ||
assertEquals(404, e.getStatus()); | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
public void requestsAreCached() throws Exception { | ||
MockResponse cacheableResp = new MockResponse(); | ||
cacheableResp.setHeader("Content-Type", "application/json"); | ||
cacheableResp.setHeader("ETag", "aaa"); | ||
cacheableResp.setHeader("Cache-Control", "max-age=1000"); | ||
cacheableResp.setBody(flag1Json); | ||
|
||
try (MockWebServer server = TestHttpUtil.makeStartedServer(cacheableResp)) { | ||
FeatureRequestor r = new FeatureRequestor(sdkKey, basePollingConfig(server).build()); | ||
|
||
FeatureFlag flag1a = r.getFlag(flag1Key); | ||
|
||
RecordedRequest req1 = server.takeRequest(); | ||
assertEquals("/sdk/latest-flags/" + flag1Key, req1.getPath()); | ||
verifyHeaders(req1); | ||
|
||
verifyFlag(flag1a, flag1Key); | ||
|
||
FeatureFlag flag1b = r.getFlag(flag1Key); | ||
verifyFlag(flag1b, flag1Key); | ||
assertNull(server.takeRequest(0, TimeUnit.SECONDS)); // there was no second request, due to the cache hit | ||
} | ||
} | ||
|
||
private LDConfig.Builder basePollingConfig(MockWebServer server) { | ||
return baseConfig(server) | ||
.stream(false); | ||
} | ||
|
||
private void verifyHeaders(RecordedRequest req) { | ||
assertEquals(sdkKey, req.getHeader("Authorization")); | ||
assertEquals("JavaClient/" + LDClient.CLIENT_VERSION, req.getHeader("User-Agent")); | ||
} | ||
|
||
private void verifyFlag(FeatureFlag flag, String key) { | ||
assertNotNull(flag); | ||
assertEquals(key, flag.getKey()); | ||
} | ||
|
||
private void verifySegment(Segment segment, String key) { | ||
assertNotNull(segment); | ||
assertEquals(key, segment.getKey()); | ||
} | ||
} |
116 changes: 116 additions & 0 deletions
116
src/test/java/com/launchdarkly/client/LDClientEndToEndTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package com.launchdarkly.client; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonPrimitive; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
import static com.launchdarkly.client.TestHttpUtil.baseConfig; | ||
import static com.launchdarkly.client.TestHttpUtil.makeStartedServer; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertNotNull; | ||
import static org.junit.Assert.assertNull; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import okhttp3.mockwebserver.MockResponse; | ||
import okhttp3.mockwebserver.MockWebServer; | ||
import okhttp3.mockwebserver.RecordedRequest; | ||
import okhttp3.mockwebserver.SocketPolicy; | ||
|
||
public class LDClientEndToEndTest { | ||
private static final Gson gson = new Gson(); | ||
private static final String sdkKey = "sdk-key"; | ||
private static final String flagKey = "flag1"; | ||
private static final FeatureFlag flag = new FeatureFlagBuilder(flagKey) | ||
.offVariation(0).variations(new JsonPrimitive(true)) | ||
.build(); | ||
private static final LDUser user = new LDUser("user-key"); | ||
|
||
@Test | ||
public void clientStartsInPollingMode() throws Exception { | ||
MockResponse resp = new MockResponse() | ||
.setHeader("Content-Type", "application/json") | ||
.setBody(makeAllDataJson()); | ||
|
||
try (MockWebServer server = makeStartedServer(resp)) { | ||
LDConfig config = baseConfig(server) | ||
.stream(false) | ||
.sendEvents(false) | ||
.build(); | ||
|
||
try (LDClient client = new LDClient(sdkKey, config)) { | ||
assertTrue(client.initialized()); | ||
assertTrue(client.boolVariation(flagKey, user, false)); | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
public void clientFailsInPollingModeWith401Error() throws Exception { | ||
MockResponse resp = new MockResponse().setResponseCode(401); | ||
|
||
try (MockWebServer server = makeStartedServer(resp)) { | ||
LDConfig config = baseConfig(server) | ||
.stream(false) | ||
.sendEvents(false) | ||
.build(); | ||
|
||
try (LDClient client = new LDClient(sdkKey, config)) { | ||
assertFalse(client.initialized()); | ||
assertFalse(client.boolVariation(flagKey, user, false)); | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
public void clientStartsInStreamingMode() throws Exception { | ||
String eventData = "event: put\n" + | ||
"data: {\"data\":" + makeAllDataJson() + "}\n\n"; | ||
|
||
MockResponse resp = new MockResponse() | ||
.setHeader("Content-Type", "text/event-stream") | ||
.setChunkedBody(eventData, 1000) | ||
.setSocketPolicy(SocketPolicy.KEEP_OPEN); | ||
|
||
try (MockWebServer server = makeStartedServer(resp)) { | ||
LDConfig config = baseConfig(server) | ||
.sendEvents(false) | ||
.build(); | ||
|
||
try (LDClient client = new LDClient(sdkKey, config)) { | ||
assertTrue(client.initialized()); | ||
assertTrue(client.boolVariation(flagKey, user, false)); | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
public void clientFailsInStreamingModeWith401Error() throws Exception { | ||
MockResponse resp = new MockResponse().setResponseCode(401); | ||
|
||
try (MockWebServer server = makeStartedServer(resp)) { | ||
LDConfig config = baseConfig(server) | ||
.sendEvents(false) | ||
.build(); | ||
|
||
try (LDClient client = new LDClient(sdkKey, config)) { | ||
assertFalse(client.initialized()); | ||
assertFalse(client.boolVariation(flagKey, user, false)); | ||
} | ||
} | ||
} | ||
|
||
public String makeAllDataJson() { | ||
JsonObject flagsData = new JsonObject(); | ||
flagsData.add(flagKey, gson.toJsonTree(flag)); | ||
JsonObject allData = new JsonObject(); | ||
allData.add("flags", flagsData); | ||
allData.add("segments", new JsonObject()); | ||
return gson.toJson(allData); | ||
} | ||
} |
Oops, something went wrong.