Skip to content

Commit ae3125e

Browse files
authored
chore: Project housekeeping (#90)
* chore: Project housekeeping * spotless * wip * wip init cleanup * fix test * all tests pass * spotless * fix welp * remove shared prefs unused method * info instead of warn
1 parent 6836214 commit ae3125e

File tree

8 files changed

+157
-194
lines changed

8 files changed

+157
-194
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ test: test-data
4848
# $(INFO)Uninstalling old version of test app(END)
4949
adb uninstall cloud.eppo.android.test
5050
# $(INFO)Running tests(END)
51-
./gradlew runEppoTests
51+
./gradlew connectedCheck
5252

5353
check-maven-credentials-and-publish:
5454
# $(INFO)Checking required gradle configuration(END)

eppo/build.gradle

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,6 @@ publishing {
158158
}
159159
}
160160

161-
task runEppoTests(type: GradleBuild) {
162-
tasks = [
163-
':eppo:testDebugUnitTest',
164-
':eppo:connectedDebugAndroidTest'
165-
]
166-
}
167-
168161
// Custom task to ensure we can conditionally publish either a release or snapshot artifact
169162
// based on a command line switch. See github workflow files for more details on usage.
170163
task checkVersion {

eppo/src/androidTest/java/cloud/eppo/android/EppoClientTest.java

Lines changed: 54 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import android.content.res.AssetManager;
2222
import android.util.Log;
23+
import androidx.annotation.Nullable;
2324
import androidx.test.core.app.ApplicationProvider;
2425
import cloud.eppo.android.helpers.AssignmentTestCase;
2526
import cloud.eppo.android.helpers.AssignmentTestCaseDeserializer;
@@ -37,7 +38,6 @@
3738
import java.io.File;
3839
import java.io.IOException;
3940
import java.io.InputStream;
40-
import java.lang.reflect.Field;
4141
import java.text.ParseException;
4242
import java.text.SimpleDateFormat;
4343
import java.util.Date;
@@ -62,44 +62,50 @@ public class EppoClientTest {
6262
"https://us-central1-eppo-qa.cloudfunctions.net/serveGitHubRacTestFile";
6363
private static final String INVALID_HOST = "https://thisisabaddomainforthistest.com";
6464
private final ObjectMapper mapper = new ObjectMapper().registerModule(module());
65-
6665
private AssignmentLogger mockAssignmentLogger;
6766

6867
private void initClient(
6968
String host,
7069
boolean throwOnCallbackError,
7170
boolean shouldDeleteCacheFiles,
7271
boolean isGracefulMode,
72+
boolean obfuscateConfig,
73+
@Nullable EppoHttpClient httpClientOverride,
74+
@Nullable ConfigurationStore configurationStoreOverride,
7375
String apiKey) {
7476
if (shouldDeleteCacheFiles) {
7577
clearCacheFile(apiKey);
7678
}
7779
mockAssignmentLogger = mock(AssignmentLogger.class);
7880
CountDownLatch lock = new CountDownLatch(1);
7981

82+
InitializationCallback callback =
83+
new InitializationCallback() {
84+
@Override
85+
public void onCompleted() {
86+
Log.i(TAG, "Test client onCompleted callback");
87+
lock.countDown();
88+
}
89+
90+
@Override
91+
public void onError(String errorMessage) {
92+
Log.w(TAG, "Test client onError callback");
93+
if (throwOnCallbackError) {
94+
throw new RuntimeException("Unable to initialize: " + errorMessage);
95+
}
96+
lock.countDown();
97+
}
98+
};
8099
new EppoClient.Builder()
81100
.application(ApplicationProvider.getApplicationContext())
82101
.apiKey(apiKey)
83102
.isGracefulMode(isGracefulMode)
84103
.host(host)
85104
.assignmentLogger(mockAssignmentLogger)
86-
.callback(
87-
new InitializationCallback() {
88-
@Override
89-
public void onCompleted() {
90-
Log.w(TAG, "Test client onCompleted callback");
91-
lock.countDown();
92-
}
93-
94-
@Override
95-
public void onError(String errorMessage) {
96-
Log.w(TAG, "Test client onError callback");
97-
if (throwOnCallbackError) {
98-
throw new RuntimeException("Unable to initialize: " + errorMessage);
99-
}
100-
lock.countDown();
101-
}
102-
})
105+
.obfuscateConfig(obfuscateConfig)
106+
.httpClient(httpClientOverride)
107+
.configStore(configurationStoreOverride)
108+
.callback(callback)
103109
.buildAndInit();
104110

105111
// Wait for initialization to succeed or fail, up to 10 seconds, before continuing
@@ -120,10 +126,6 @@ public void cleanUp() {
120126
for (String apiKey : apiKeys) {
121127
clearCacheFile(apiKey);
122128
}
123-
// Reset any development overrides
124-
setIsConfigObfuscatedField(true);
125-
setHttpClientOverrideField(null);
126-
setConfigurationStoreOverrideField(null);
127129
}
128130

129131
private void clearCacheFile(String apiKey) {
@@ -135,20 +137,19 @@ private void clearCacheFile(String apiKey) {
135137

136138
@Test
137139
public void testUnobfuscatedAssignments() {
138-
setIsConfigObfuscatedField(false);
139-
initClient(TEST_HOST, true, true, false, DUMMY_API_KEY);
140+
initClient(TEST_HOST, true, true, false, false, null, null, DUMMY_API_KEY);
140141
runTestCases();
141142
}
142143

143144
@Test
144145
public void testAssignments() {
145-
initClient(TEST_HOST, true, true, false, DUMMY_API_KEY);
146+
initClient(TEST_HOST, true, true, false, true, null, null, DUMMY_API_KEY);
146147
runTestCases();
147148
}
148149

149150
@Test
150151
public void testErrorGracefulModeOn() throws JSONException {
151-
initClient(TEST_HOST, false, true, true, DUMMY_API_KEY);
152+
initClient(TEST_HOST, false, true, true, true, null, null, DUMMY_API_KEY);
152153

153154
EppoClient realClient = EppoClient.getInstance();
154155
EppoClient spyClient = spy(realClient);
@@ -200,7 +201,7 @@ public void testErrorGracefulModeOn() throws JSONException {
200201

201202
@Test
202203
public void testErrorGracefulModeOff() {
203-
initClient(TEST_HOST, false, true, false, DUMMY_API_KEY);
204+
initClient(TEST_HOST, false, true, false, true, null, null, DUMMY_API_KEY);
204205

205206
EppoClient realClient = EppoClient.getInstance();
206207
EppoClient spyClient = spy(realClient);
@@ -277,15 +278,30 @@ private void runTestCases() {
277278
@Test
278279
public void testCachedAssignments() {
279280
// First initialize successfully
280-
initClient(TEST_HOST, true, true, false, DUMMY_API_KEY); // ensure cache is populated
281+
initClient(
282+
TEST_HOST,
283+
true,
284+
true,
285+
false,
286+
false,
287+
null,
288+
null,
289+
DUMMY_API_KEY); // ensure cache is populated
281290

282291
// wait for a bit since cache file is written asynchronously
283292
waitForPopulatedCache();
284293

285294
// Then reinitialize with a bad host so we know it's using the cached UFC built from the first
286295
// initialization
287296
initClient(
288-
INVALID_HOST, false, false, false, DUMMY_API_KEY); // invalid host to force to use cache
297+
INVALID_HOST,
298+
false,
299+
false,
300+
false,
301+
false,
302+
null,
303+
null,
304+
DUMMY_API_KEY); // invalid host to force to use cache
289305

290306
runTestCases();
291307
}
@@ -414,8 +430,7 @@ public void testInvalidConfigJSON() {
414430
.when(mockHttpClient)
415431
.get(anyString(), any(RequestCallback.class));
416432

417-
setHttpClientOverrideField(mockHttpClient);
418-
initClient(TEST_HOST, true, true, false, DUMMY_API_KEY);
433+
initClient(TEST_HOST, true, true, false, false, mockHttpClient, null, DUMMY_API_KEY);
419434

420435
String result =
421436
EppoClient.getInstance()
@@ -431,7 +446,7 @@ public void testCachedBadResponseRequiresFetch() {
431446
ApplicationProvider.getApplicationContext(), safeCacheKey(DUMMY_API_KEY));
432447
cacheFile.setContents("{ invalid }");
433448

434-
initClient(TEST_HOST, true, false, false, DUMMY_API_KEY);
449+
initClient(TEST_HOST, true, false, false, true, null, null, DUMMY_API_KEY);
435450

436451
double assignment = EppoClient.getInstance().getDoubleAssignment("numeric_flag", "alice", 0.0);
437452
assertEquals(3.1415926, assignment, 0.0000001);
@@ -445,14 +460,14 @@ public void testEmptyFlagsResponseRequiresFetch() {
445460
ApplicationProvider.getApplicationContext(), safeCacheKey(DUMMY_API_KEY));
446461
cacheFile.setContents("{\"flags\": {}}");
447462

448-
initClient(TEST_HOST, true, false, false, DUMMY_API_KEY);
463+
initClient(TEST_HOST, true, false, false, true, null, null, DUMMY_API_KEY);
449464
double assignment = EppoClient.getInstance().getDoubleAssignment("numeric_flag", "alice", 0.0);
450465
assertEquals(3.1415926, assignment, 0.0000001);
451466
}
452467

453468
@Test
454469
public void testDifferentCacheFilesPerKey() {
455-
initClient(TEST_HOST, true, true, false, DUMMY_API_KEY);
470+
initClient(TEST_HOST, true, true, false, true, null, null, DUMMY_API_KEY);
456471
// API Key 1 will fetch and then populate its cache with the usual test data
457472
double apiKey1Assignment =
458473
EppoClient.getInstance().getDoubleAssignment("numeric_flag", "alice", 0.0);
@@ -495,15 +510,15 @@ public void testDifferentCacheFilesPerKey() {
495510
+ " }\n"
496511
+ "}");
497512

498-
initClient(TEST_HOST, true, false, false, DUMMY_OTHER_API_KEY);
513+
initClient(TEST_HOST, true, false, false, true, null, null, DUMMY_OTHER_API_KEY);
499514

500515
// Ensure API key 2 uses its cache
501516
double apiKey2Assignment =
502517
EppoClient.getInstance().getDoubleAssignment("numeric_flag", "alice", 0.0);
503518
assertEquals(1.2345, apiKey2Assignment, 0.0000001);
504519

505520
// Reinitialize API key 1 to be sure it used its cache
506-
initClient(TEST_HOST, true, false, false, DUMMY_API_KEY);
521+
initClient(TEST_HOST, true, false, false, true, null, null, DUMMY_API_KEY);
507522
// API Key 1 will fetch and then populate its cache with the usual test data
508523
apiKey1Assignment = EppoClient.getInstance().getDoubleAssignment("numeric_flag", "alice", 0.0);
509524
assertEquals(3.1415926, apiKey1Assignment, 0.0000001);
@@ -531,8 +546,7 @@ protected FlagConfigResponse readCacheFile() {
531546
}
532547
};
533548

534-
setConfigurationStoreOverrideField(slowStore);
535-
initClient(TEST_HOST, true, false, false, DUMMY_API_KEY);
549+
initClient(TEST_HOST, true, false, false, true, null, slowStore, DUMMY_API_KEY);
536550

537551
// Give time for async slow cache read to finish
538552
try {
@@ -574,7 +588,7 @@ private void waitForPopulatedCache() {
574588
@Test
575589
public void testAssignmentEventCorrectlyCreated() {
576590
Date testStart = new Date();
577-
initClient(TEST_HOST, true, false, false, DUMMY_API_KEY);
591+
initClient(TEST_HOST, true, false, false, true, null, null, DUMMY_API_KEY);
578592
SubjectAttributes subjectAttributes = new SubjectAttributes();
579593
subjectAttributes.put("age", EppoValue.valueOf(30));
580594
subjectAttributes.put("employer", EppoValue.valueOf("Eppo"));
@@ -619,33 +633,6 @@ public void testAssignmentEventCorrectlyCreated() {
619633
assertEquals(expectedMeta, capturedAssignment.getMetaData());
620634
}
621635

622-
private void setHttpClientOverrideField(EppoHttpClient httpClient) {
623-
setOverrideField("httpClientOverride", httpClient);
624-
}
625-
626-
private void setConfigurationStoreOverrideField(ConfigurationStore configurationStore) {
627-
setOverrideField("configurationStoreOverride", configurationStore);
628-
}
629-
630-
/**
631-
* @noinspection SameParameterValue
632-
*/
633-
private void setIsConfigObfuscatedField(boolean isConfigObfuscated) {
634-
setOverrideField("isConfigObfuscated", isConfigObfuscated);
635-
}
636-
637-
private <T> void setOverrideField(String fieldName, T override) {
638-
try {
639-
// Use reflection to set the httpClientOverride field
640-
Field httpClientOverrideField = EppoClient.class.getDeclaredField(fieldName);
641-
httpClientOverrideField.setAccessible(true);
642-
httpClientOverrideField.set(null, override);
643-
httpClientOverrideField.setAccessible(false);
644-
} catch (NoSuchFieldException | IllegalAccessException e) {
645-
throw new RuntimeException(e);
646-
}
647-
}
648-
649636
private static SimpleModule module() {
650637
SimpleModule module = new SimpleModule();
651638
module.addDeserializer(AssignmentTestCase.class, new AssignmentTestCaseDeserializer());

eppo/src/main/java/cloud/eppo/android/ConfigurationRequestor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static cloud.eppo.android.util.Utils.logTag;
44

55
import android.util.Log;
6+
import androidx.annotation.Nullable;
67
import cloud.eppo.ufc.dto.FlagConfig;
78
import com.fasterxml.jackson.core.JsonProcessingException;
89
import java.util.concurrent.atomic.AtomicBoolean;
@@ -19,7 +20,7 @@ public ConfigurationRequestor(ConfigurationStore configurationStore, EppoHttpCli
1920
this.client = client;
2021
}
2122

22-
public void load(InitializationCallback callback) {
23+
public void load(@Nullable InitializationCallback callback) {
2324
// We have two at-bats to load the configuration: loading from cache and fetching
2425
// The below variables help them keep track of each other's progress
2526
AtomicBoolean cacheLoadInProgress = new AtomicBoolean(true);

0 commit comments

Comments
 (0)