diff --git a/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FDv2DataSourceTest.java b/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FDv2DataSourceTest.java index 75156e95..33ecfc61 100644 --- a/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FDv2DataSourceTest.java +++ b/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FDv2DataSourceTest.java @@ -517,13 +517,10 @@ public void emptyInitializerListSkipsToSynchronizers() throws Exception { @Test public void fallbackAndRecoveryTasksWellBehaved() throws Exception { - // First sync: changeset then INTERRUPTED; second sync: changeset; recovery brings back first - MockQueuedSynchronizer firstSync = new MockQueuedSynchronizer( - FDv2SourceResult.changeSet(makeChangeSet(false), false), - interrupted()); - MockQueuedSynchronizer secondSync = new MockQueuedSynchronizer( - FDv2SourceResult.changeSet(makeChangeSet(false), false)); - + // First sync: changeset then INTERRUPTED; second sync: changeset; recovery brings back first. + // Each factory call builds a new synchronizer, as a real factory does. Recovery closes the + // active one and builds the primary again, and a closed mock answers SHUTDOWN at once, so + // handing the same instance back would spin the orchestrator between two closed mocks. AtomicInteger firstCallCount = new AtomicInteger(0); AtomicInteger secondCallCount = new AtomicInteger(0); MockComponents.MockDataSourceUpdateSink sink = new MockComponents.MockDataSourceUpdateSink(); @@ -531,8 +528,17 @@ public void fallbackAndRecoveryTasksWellBehaved() throws Exception { FDv2DataSource dataSource = buildDataSource(sink, Collections.emptyList(), Arrays.asList( - () -> { firstCallCount.incrementAndGet(); return firstSync; }, - () -> { secondCallCount.incrementAndGet(); return secondSync; }), + () -> { + firstCallCount.incrementAndGet(); + return new MockQueuedSynchronizer( + FDv2SourceResult.changeSet(makeChangeSet(false), false), + interrupted()); + }, + () -> { + secondCallCount.incrementAndGet(); + return new MockQueuedSynchronizer( + FDv2SourceResult.changeSet(makeChangeSet(false), false)); + }), 1, 2); AwaitableCallback startCallback = startDataSource(dataSource); @@ -541,6 +547,7 @@ public void fallbackAndRecoveryTasksWellBehaved() throws Exception { // Wait for fallback + recovery: ~1s fallback + ~2s recovery. // Use generous timeouts for Android where thread scheduling can delay timer delivery. sink.awaitApplyCount(3, AWAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); + assertTrue(sink.getApplyCount() >= 3); List statuses = sink.awaitStatuses(3, AWAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(statuses.size() >= 3); @@ -2030,16 +2037,15 @@ public void orchestrationLogging_fallback_logsInfo() throws Exception { @Test public void orchestrationLogging_recovery_logsInfo() throws Exception { MockComponents.MockDataSourceUpdateSink sink = new MockComponents.MockDataSourceUpdateSink(); - MockQueuedSynchronizer firstSync = new MockQueuedSynchronizer( - FDv2SourceResult.changeSet(makeChangeSet(false), false), - interrupted()); - MockQueuedSynchronizer secondSync = new MockQueuedSynchronizer( - FDv2SourceResult.changeSet(makeChangeSet(false), false)); + // A new synchronizer per build, for the reason fallbackAndRecoveryTasksWellBehaved gives. FDv2DataSource dataSource = buildDataSource(sink, Collections.emptyList(), Arrays.asList( - () -> firstSync, - () -> secondSync), + () -> new MockQueuedSynchronizer( + FDv2SourceResult.changeSet(makeChangeSet(false), false), + interrupted()), + () -> new MockQueuedSynchronizer( + FDv2SourceResult.changeSet(makeChangeSet(false), false))), 1, 2); AwaitableCallback startCallback = startDataSource(dataSource); try { diff --git a/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FlagTest.java b/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FlagTest.java index 36360754..63d7bb57 100644 --- a/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FlagTest.java +++ b/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/FlagTest.java @@ -156,7 +156,7 @@ public void variationIsSerialized() { public void variationIsDeserialized() { final String jsonStr = "{\"version\": 99, \"variation\": 2}"; final Flag r = gson.fromJson(jsonStr, Flag.class); - assertEquals(new Integer(2), r.getVariation()); + assertEquals(Integer.valueOf(2), r.getVariation()); } @Test @@ -243,12 +243,12 @@ public void debugEventsUntilDateIsSerialized() { public void debugEventsUntilDateIsDeserialized() { final String jsonStr = "{\"version\": 99, \"debugEventsUntilDate\": 12345}"; final Flag r = gson.fromJson(jsonStr, Flag.class); - assertEquals(new Long(12345L), r.getDebugEventsUntilDate()); + assertEquals(Long.valueOf(12345L), r.getDebugEventsUntilDate()); // Test long sized number final String jsonStrl = "{\"version\": 99, \"debugEventsUntilDate\": 2500000000}"; final Flag rl = gson.fromJson(jsonStrl, Flag.class); - assertEquals(new Long(2500000000L), rl.getDebugEventsUntilDate()); + assertEquals(Long.valueOf(2500000000L), rl.getDebugEventsUntilDate()); } @Test