diff --git a/build.gradle b/build.gradle index a0030dcd5..b53645e4b 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ apply from: 'spec.gradle' apply from: 'jacoco.gradle' ext { - splitVersion = '5.4.0' + splitVersion = '5.4.1-alpha.1' jacocoVersion = '0.8.8' } diff --git a/src/main/java/io/split/android/client/service/executor/SplitTaskFactoryImpl.java b/src/main/java/io/split/android/client/service/executor/SplitTaskFactoryImpl.java index fe770bc20..9644c2dbb 100644 --- a/src/main/java/io/split/android/client/service/executor/SplitTaskFactoryImpl.java +++ b/src/main/java/io/split/android/client/service/executor/SplitTaskFactoryImpl.java @@ -143,8 +143,7 @@ public ImpressionsRecorderTask createImpressionsRecorderTask() { @Override public SplitsSyncTask createSplitsSyncTask(boolean checkCacheExpiration) { - return SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorageContainer.getSplitsStorage(), - mSplitsStorageContainer.getRuleBasedSegmentStorage(), + return SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorageContainer.getGeneralInfoStorage(), mSplitsFilterQueryStringFromConfig, mEventsManager, mSplitsStorageContainer.getTelemetryStorage()); } diff --git a/src/main/java/io/split/android/client/service/splits/SplitsSyncHelper.java b/src/main/java/io/split/android/client/service/splits/SplitsSyncHelper.java index e13f5a85b..0836d6810 100644 --- a/src/main/java/io/split/android/client/service/splits/SplitsSyncHelper.java +++ b/src/main/java/io/split/android/client/service/splits/SplitsSyncHelper.java @@ -46,6 +46,7 @@ public class SplitsSyncHelper { private final SplitChangeProcessor mSplitChangeProcessor; private final RuleBasedSegmentChangeProcessor mRuleBasedSegmentChangeProcessor; private final RuleBasedSegmentStorageProducer mRuleBasedSegmentStorage; + private final GeneralInfoStorage mGeneralInfoStorage; private final TelemetryRuntimeProducer mTelemetryRuntimeProducer; private final BackoffCounter mBackoffCounter; private final OutdatedSplitProxyHandler mOutdatedSplitProxyHandler; @@ -113,6 +114,7 @@ public SplitsSyncHelper(@NonNull HttpFetcher splitFetcher, mRuleBasedSegmentStorage = checkNotNull(ruleBasedSegmentStorage); mTelemetryRuntimeProducer = checkNotNull(telemetryRuntimeProducer); mBackoffCounter = checkNotNull(backoffCounter); + mGeneralInfoStorage = checkNotNull(generalInfoStorage); mOutdatedSplitProxyHandler = new OutdatedSplitProxyHandler(flagsSpec, forBackgroundSync, generalInfoStorage, proxyCheckIntervalMillis); } @@ -225,8 +227,8 @@ private SinceChangeNumbers fetchUntil(SinceChangeNumbers till, boolean clearBefo SinceChangeNumbers newTill = till; while (true) { - long changeNumber = (resetChangeNumber) ? -1 : mSplitsStorage.getTill(); - long rbsChangeNumber = (resetChangeNumber) ? -1 : mRuleBasedSegmentStorage.getChangeNumber(); + long changeNumber = (resetChangeNumber) ? -1 : mGeneralInfoStorage.getFlagsChangeNumber(); + long rbsChangeNumber = (resetChangeNumber) ? -1 : mGeneralInfoStorage.getRbsChangeNumber(); resetChangeNumber = false; if ((newTill.getFlagsSince() < changeNumber) && ((newTill.getRbsSince() == null) || (newTill.getRbsSince() < rbsChangeNumber))) { return new SinceChangeNumbers(changeNumber, rbsChangeNumber); diff --git a/src/main/java/io/split/android/client/service/splits/SplitsSyncTask.java b/src/main/java/io/split/android/client/service/splits/SplitsSyncTask.java index 2cb35e578..8baeb2112 100644 --- a/src/main/java/io/split/android/client/service/splits/SplitsSyncTask.java +++ b/src/main/java/io/split/android/client/service/splits/SplitsSyncTask.java @@ -12,8 +12,7 @@ import io.split.android.client.service.executor.SplitTaskExecutionInfo; import io.split.android.client.service.executor.SplitTaskExecutionStatus; import io.split.android.client.service.synchronizer.SplitsChangeChecker; -import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer; -import io.split.android.client.storage.splits.SplitsStorage; +import io.split.android.client.storage.general.GeneralInfoStorage; import io.split.android.client.telemetry.model.OperationType; import io.split.android.client.telemetry.storage.TelemetryRuntimeProducer; @@ -21,8 +20,7 @@ public class SplitsSyncTask implements SplitTask { private final String mSplitsFilterQueryStringFromConfig; - private final SplitsStorage mSplitsStorage; - private final RuleBasedSegmentStorageProducer mRuleBasedSegmentStorage; + private final GeneralInfoStorage mGeneralInfoStorage; private final SplitsSyncHelper mSplitsSyncHelper; @Nullable private final ISplitEventsManager mEventsManager; // Should only be null on background sync @@ -31,33 +29,29 @@ public class SplitsSyncTask implements SplitTask { private final int mOnDemandFetchBackoffMaxRetries; public static SplitsSyncTask build(@NonNull SplitsSyncHelper splitsSyncHelper, - @NonNull SplitsStorage splitsStorage, - @NonNull RuleBasedSegmentStorageProducer ruleBasedSegmentStorage, + @NonNull GeneralInfoStorage generalInfoStorage, String splitsFilterQueryString, @NonNull ISplitEventsManager eventsManager, @NonNull TelemetryRuntimeProducer telemetryRuntimeProducer) { - return new SplitsSyncTask(splitsSyncHelper, splitsStorage, ruleBasedSegmentStorage, splitsFilterQueryString, telemetryRuntimeProducer, eventsManager, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); + return new SplitsSyncTask(splitsSyncHelper, generalInfoStorage, splitsFilterQueryString, telemetryRuntimeProducer, eventsManager, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); } public static SplitTask buildForBackground(@NonNull SplitsSyncHelper splitsSyncHelper, - @NonNull SplitsStorage splitsStorage, - @NonNull RuleBasedSegmentStorageProducer ruleBasedSegmentStorage, + @NonNull GeneralInfoStorage generalInfoStorage, String splitsFilterQueryString, @NonNull TelemetryRuntimeProducer telemetryRuntimeProducer) { - return new SplitsSyncTask(splitsSyncHelper, splitsStorage, ruleBasedSegmentStorage, splitsFilterQueryString, telemetryRuntimeProducer, null, 1); + return new SplitsSyncTask(splitsSyncHelper, generalInfoStorage, splitsFilterQueryString, telemetryRuntimeProducer, null, 1); } private SplitsSyncTask(@NonNull SplitsSyncHelper splitsSyncHelper, - @NonNull SplitsStorage splitsStorage, - @NonNull RuleBasedSegmentStorageProducer ruleBasedSegmentStorage, + @NonNull GeneralInfoStorage generalInfoStorage, String splitsFilterQueryString, @NonNull TelemetryRuntimeProducer telemetryRuntimeProducer, @Nullable ISplitEventsManager eventsManager, int onDemandFetchBackoffMaxRetries) { - mSplitsStorage = checkNotNull(splitsStorage); mSplitsSyncHelper = checkNotNull(splitsSyncHelper); - mRuleBasedSegmentStorage = checkNotNull(ruleBasedSegmentStorage); + mGeneralInfoStorage = checkNotNull(generalInfoStorage); mSplitsFilterQueryStringFromConfig = splitsFilterQueryString; mEventsManager = eventsManager; mChangeChecker = new SplitsChangeChecker(); @@ -68,13 +62,13 @@ private SplitsSyncTask(@NonNull SplitsSyncHelper splitsSyncHelper, @Override @NonNull public SplitTaskExecutionInfo execute() { - long storedChangeNumber = mSplitsStorage.getTill(); - long storedRbsChangeNumber = mRuleBasedSegmentStorage.getChangeNumber(); + long storedChangeNumber = mGeneralInfoStorage.getFlagsChangeNumber(); + long storedRbsChangeNumber = mGeneralInfoStorage.getRbsChangeNumber(); - boolean splitsFilterHasChanged = splitsFilterHasChanged(mSplitsStorage.getSplitsFilterQueryString()); + boolean splitsFilterHasChanged = splitsFilterHasChanged(mGeneralInfoStorage.getSplitsFilterQueryString()); if (splitsFilterHasChanged) { - mSplitsStorage.updateSplitsFilterQueryString(mSplitsFilterQueryStringFromConfig); + mGeneralInfoStorage.setSplitsFilterQueryString(mSplitsFilterQueryStringFromConfig); storedChangeNumber = -1; } @@ -95,7 +89,7 @@ public SplitTaskExecutionInfo execute() { private void notifyInternalEvent(long storedChangeNumber) { if (mEventsManager != null) { SplitInternalEvent event = SplitInternalEvent.SPLITS_FETCHED; - if (mChangeChecker.changeNumberIsNewer(storedChangeNumber, mSplitsStorage.getTill())) { + if (mChangeChecker.changeNumberIsNewer(storedChangeNumber, mGeneralInfoStorage.getFlagsChangeNumber())) { event = SplitInternalEvent.SPLITS_UPDATED; } diff --git a/src/main/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilder.java b/src/main/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilder.java index 7ef5daaf4..108050794 100644 --- a/src/main/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilder.java +++ b/src/main/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilder.java @@ -58,8 +58,7 @@ SplitTask getTask() { mFlagsSpec); return SplitsSyncTask.buildForBackground(splitsSyncHelper, - splitsStorage, - ruleBasedSegmentStorageProducer, + generalInfoStorage, splitsFilterQueryString, telemetryStorage); } catch (URISyntaxException e) { diff --git a/src/test/java/io/split/android/client/service/SplitSyncTaskTest.java b/src/test/java/io/split/android/client/service/SplitSyncTaskTest.java index 9a4eb8580..931978e0c 100644 --- a/src/test/java/io/split/android/client/service/SplitSyncTaskTest.java +++ b/src/test/java/io/split/android/client/service/SplitSyncTaskTest.java @@ -15,6 +15,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import androidx.annotation.NonNull; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -30,8 +32,7 @@ import io.split.android.client.service.http.HttpFetcherException; import io.split.android.client.service.splits.SplitsSyncHelper; import io.split.android.client.service.splits.SplitsSyncTask; -import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer; -import io.split.android.client.storage.splits.SplitsStorage; +import io.split.android.client.storage.general.GeneralInfoStorage; import io.split.android.client.telemetry.model.OperationType; import io.split.android.client.telemetry.storage.TelemetryRuntimeProducer; import io.split.android.helpers.FileHelper; @@ -40,10 +41,9 @@ public class SplitSyncTaskTest { private static final long OLD_TIMESTAMP = 1546300800L; //2019-01-01 - SplitsStorage mSplitsStorage; SplitChange mSplitChange = null; SplitsSyncHelper mSplitsSyncHelper; - RuleBasedSegmentStorageProducer mRuleBasedSegmentStorage; + private GeneralInfoStorage mGeneralInfoStorage; SplitsSyncTask mTask; String mQueryString = "qs=1"; @@ -56,10 +56,9 @@ public class SplitSyncTaskTest { public void setup() { mTelemetryRuntimeProducer = mock(TelemetryRuntimeProducer.class); - mSplitsStorage = mock(SplitsStorage.class); mSplitsSyncHelper = mock(SplitsSyncHelper.class); mEventsManager = mock(SplitEventsManager.class); - mRuleBasedSegmentStorage = mock(RuleBasedSegmentStorageProducer.class); + mGeneralInfoStorage = mock(GeneralInfoStorage.class); when(mSplitsSyncHelper.sync(notNull(), anyBoolean(), anyBoolean(), eq(ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES))).thenReturn(SplitTaskExecutionInfo.success(SplitTaskType.SPLIT_KILL)); @@ -72,12 +71,12 @@ public void correctExecution() throws HttpFetcherException { // Querystring is the same, so no clear sould be called // And updateTimestamp is 0 // Retry is off, so splitSyncHelper.sync should be called - mTask = SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorage, + mTask = SplitsSyncTask.build(mSplitsSyncHelper, mGeneralInfoStorage, mQueryString, mEventsManager, mTelemetryRuntimeProducer); - when(mSplitsStorage.getTill()).thenReturn(-1L); - when(mRuleBasedSegmentStorage.getChangeNumber()).thenReturn(-1L); - when(mSplitsStorage.getUpdateTimestamp()).thenReturn(0L); - when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); + when(mGeneralInfoStorage.getRbsChangeNumber()).thenReturn(-1L); + when(mGeneralInfoStorage.getSplitsUpdateTimestamp()).thenReturn(0L); + when(mGeneralInfoStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); mTask.execute(); @@ -93,17 +92,17 @@ public void cleanSplitsWhenQueryStringHasChanged() throws HttpFetcherException { String otherQs = "q=other"; Map params = new HashMap<>(); params.put("since", 100L); - mTask = SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorage, + mTask = SplitsSyncTask.build(mSplitsSyncHelper, mGeneralInfoStorage, otherQs, mEventsManager, mTelemetryRuntimeProducer); - when(mSplitsStorage.getTill()).thenReturn(100L); - when(mRuleBasedSegmentStorage.getChangeNumber()).thenReturn(200L); - when(mSplitsStorage.getUpdateTimestamp()).thenReturn(1111L); - when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(100L); + when(mGeneralInfoStorage.getRbsChangeNumber()).thenReturn(200L); + when(mGeneralInfoStorage.getSplitsUpdateTimestamp()).thenReturn(1111L); + when(mGeneralInfoStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); mTask.execute(); verify(mSplitsSyncHelper, times(1)).sync(argThat(argument -> argument.getFlagsSince() == -1 && argument.getRbsSince() == 200), eq(true), eq(true), eq(ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES)); - verify(mSplitsStorage, times(1)).updateSplitsFilterQueryString(otherQs); + verify(mGeneralInfoStorage, times(1)).setSplitsFilterQueryString(otherQs); } @Test @@ -111,16 +110,15 @@ public void noClearSplitsWhenQueryStringHasNotChanged() throws HttpFetcherExcept // Splits have to be cleared when query string on db is != than current one on current sdk client instance // Setting up cache not expired - mTask = SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorage, - mQueryString, mEventsManager, mTelemetryRuntimeProducer); - when(mSplitsStorage.getTill()).thenReturn(100L); - when(mSplitsStorage.getUpdateTimestamp()).thenReturn(1111L); - when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); + mTask = buildSplitsSyncTask(); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(100L); + when(mGeneralInfoStorage.getSplitsUpdateTimestamp()).thenReturn(1111L); + when(mGeneralInfoStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); mTask.execute(); verify(mSplitsSyncHelper, times(1)).sync(argThat(argument -> argument.getFlagsSince() == 100L), eq(false), eq(false), eq(ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES)); - verify(mSplitsStorage, never()).updateSplitsFilterQueryString(anyString()); + verify(mGeneralInfoStorage, never()).setSplitsFilterQueryString(anyString()); } @Test @@ -129,11 +127,10 @@ public void splitUpdatedNotified() throws HttpFetcherException { // Querystring is the same, so no clear sould be called // And updateTimestamp is 0 // Retry is off, so splitSyncHelper.sync should be called - mTask = SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorage, - mQueryString, mEventsManager, mTelemetryRuntimeProducer); - when(mSplitsStorage.getTill()).thenReturn(-1L).thenReturn(100L); - when(mSplitsStorage.getUpdateTimestamp()).thenReturn(0L); - when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); + mTask = buildSplitsSyncTask(); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L).thenReturn(100L); + when(mGeneralInfoStorage.getSplitsUpdateTimestamp()).thenReturn(0L); + when(mGeneralInfoStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); when(mSplitsSyncHelper.sync(any(), anyBoolean(), anyBoolean(), eq(ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES))).thenReturn(SplitTaskExecutionInfo.success(SplitTaskType.SPLITS_SYNC)); mTask.execute(); @@ -147,11 +144,10 @@ public void splitFetchdNotified() throws HttpFetcherException { // Querystring is the same, so no clear sould be called // And updateTimestamp is 0 // Retry is off, so splitSyncHelper.sync should be called - mTask = SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorage, - mQueryString, mEventsManager, mTelemetryRuntimeProducer); - when(mSplitsStorage.getTill()).thenReturn(100L); - when(mSplitsStorage.getUpdateTimestamp()).thenReturn(0L); - when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); + mTask = buildSplitsSyncTask(); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(100L); + when(mGeneralInfoStorage.getSplitsUpdateTimestamp()).thenReturn(0L); + when(mGeneralInfoStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); when(mSplitsSyncHelper.sync(any(), anyBoolean(), anyBoolean(), eq(ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES))).thenReturn(SplitTaskExecutionInfo.success(SplitTaskType.SPLITS_SYNC)); mTask.execute(); @@ -161,11 +157,10 @@ public void splitFetchdNotified() throws HttpFetcherException { @Test public void syncIsTrackedInTelemetry() { - mTask = SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorage, - mQueryString, mEventsManager, mTelemetryRuntimeProducer); - when(mSplitsStorage.getTill()).thenReturn(100L); - when(mSplitsStorage.getUpdateTimestamp()).thenReturn(0L); - when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); + mTask = buildSplitsSyncTask(); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(100L); + when(mGeneralInfoStorage.getSplitsUpdateTimestamp()).thenReturn(0L); + when(mGeneralInfoStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); when(mSplitsSyncHelper.sync(any(), anyBoolean(), anyBoolean(), eq(ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES))).thenReturn(SplitTaskExecutionInfo.success(SplitTaskType.SPLITS_SYNC)); mTask.execute(); @@ -175,20 +170,25 @@ public void syncIsTrackedInTelemetry() { @Test public void recordSuccessInTelemetry() { - mTask = SplitsSyncTask.build(mSplitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorage, - mQueryString, mEventsManager, mTelemetryRuntimeProducer); - when(mSplitsStorage.getTill()).thenReturn(-1L); - when(mSplitsStorage.getUpdateTimestamp()).thenReturn(0L); - when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); + mTask = buildSplitsSyncTask(); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); + when(mGeneralInfoStorage.getSplitsUpdateTimestamp()).thenReturn(0L); + when(mGeneralInfoStorage.getSplitsFilterQueryString()).thenReturn(mQueryString); mTask.execute(); verify(mTelemetryRuntimeProducer).recordSuccessfulSync(eq(OperationType.SPLITS), longThat(arg -> arg > 0)); } + @NonNull + private SplitsSyncTask buildSplitsSyncTask() { + return SplitsSyncTask.build(mSplitsSyncHelper, mGeneralInfoStorage, + mQueryString, mEventsManager, mTelemetryRuntimeProducer); + } + @After public void tearDown() { - reset(mSplitsStorage); + reset(mGeneralInfoStorage); } private void loadSplitChanges() { diff --git a/src/test/java/io/split/android/client/service/SplitsSyncHelperTest.java b/src/test/java/io/split/android/client/service/SplitsSyncHelperTest.java index b6e0793ec..5c6c7cbb3 100644 --- a/src/test/java/io/split/android/client/service/SplitsSyncHelperTest.java +++ b/src/test/java/io/split/android/client/service/SplitsSyncHelperTest.java @@ -88,7 +88,7 @@ public void setup() { mDefaultParams.clear(); mDefaultParams = getSinceParams(-1, -1); mSecondFetchParams = getSinceParams(1506703262916L, 262325L); - when(mRuleBasedSegmentStorageProducer.getChangeNumber()).thenReturn(-1L).thenReturn(262325L); + when(mGeneralInfoStorage.getRbsChangeNumber()).thenReturn(-1L).thenReturn(262325L); // Use a short proxy check interval for all tests mSplitsSyncHelper = new SplitsSyncHelper(mSplitsFetcher, mSplitsStorage, mSplitChangeProcessor, mRuleBasedSegmentChangeProcessor, mRuleBasedSegmentStorageProducer, mGeneralInfoStorage, mTelemetryRuntimeProducer, mBackoffCounter, "1.3", false, 1L); loadSplitChanges(); @@ -111,8 +111,8 @@ public void correctSyncExecution() throws HttpFetcherException { secondSplitChange.since = mTargetingRulesChange.getFeatureFlagsChange().till; when(mSplitsFetcher.execute(any(), any())) .thenReturn(TargetingRulesChange.create(secondSplitChange, RuleBasedSegmentChange.create(262325L, 262325L, Collections.emptyList()))); - when(mSplitsStorage.getTill()).thenReturn(-1L); - when(mRuleBasedSegmentStorageProducer.getChangeNumber()).thenReturn(-1L).thenReturn(262325L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); + when(mGeneralInfoStorage.getRbsChangeNumber()).thenReturn(-1L).thenReturn(262325L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -137,7 +137,7 @@ public void correctSyncExecutionNoCache() throws HttpFetcherException { secondSplitChange.since = mTargetingRulesChange.getFeatureFlagsChange().till; when(mSplitsFetcher.execute(any(), any())) .thenReturn(TargetingRulesChange.create(secondSplitChange, RuleBasedSegmentChange.create(262325L, 262325L, Collections.emptyList()))); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -152,7 +152,7 @@ public void correctSyncExecutionNoCache() throws HttpFetcherException { public void fetcherSyncException() throws HttpFetcherException { when(mSplitsFetcher.execute(mDefaultParams, null)) .thenThrow(HttpFetcherException.class); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), true, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -167,7 +167,7 @@ public void fetcherSyncException() throws HttpFetcherException { public void storageException() throws HttpFetcherException { when(mSplitsFetcher.execute(mDefaultParams, null)).thenReturn(mTargetingRulesChange); doThrow(NullPointerException.class).when(mSplitsStorage).update(any(ProcessedSplitChange.class)); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), true, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -185,7 +185,7 @@ public void shouldClearStorageAfterFetch() throws HttpFetcherException { secondSplitChange.since = mTargetingRulesChange.getFeatureFlagsChange().till; when(mSplitsFetcher.execute(any(), any())) .thenReturn(TargetingRulesChange.create(secondSplitChange, RuleBasedSegmentChange.create(262325L, 262325L, Collections.emptyList()))); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), true, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -201,7 +201,7 @@ public void shouldClearStorageAfterFetch() throws HttpFetcherException { public void errorIsRecordedInTelemetry() throws HttpFetcherException { when(mSplitsFetcher.execute(mDefaultParams, null)) .thenThrow(new HttpFetcherException("error", "error", 500)); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), true, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -217,7 +217,7 @@ public void performSplitsFetchUntilSinceEqualsTill() throws HttpFetcherException Map secondParams = getSinceParams(2L, 262325L); Map thirdParams = getSinceParams(3L, 262325L); - when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 3L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, 2L, 3L); when(mSplitsFetcher.execute(eq(firstParams), any())).thenReturn(firstSplitChange); when(mSplitsFetcher.execute(eq(secondParams), any())).thenReturn(secondSplitChange); @@ -225,7 +225,7 @@ public void performSplitsFetchUntilSinceEqualsTill() throws HttpFetcherException mSplitsSyncHelper.sync(getSinceChangeNumbers(3, -1), ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); - verify(mSplitsStorage, times(3)).getTill(); + verify(mGeneralInfoStorage, times(3)).getFlagsChangeNumber(); verify(mSplitsFetcher).execute(eq(firstParams), any()); verify(mSplitsFetcher).execute(eq(secondParams), any()); verify(mSplitsFetcher).execute(eq(thirdParams), any()); @@ -237,20 +237,20 @@ public void performSplitFetchUntilStoredChangeNumberIsGreaterThanRequested() thr TargetingRulesChange secondSplitChange = getSplitChange(2, 4); TargetingRulesChange thirdSplitChange = getSplitChange(4, 4); - when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 4L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, 2L, 4L); when(mSplitsFetcher.execute(any(), any())).thenReturn(firstSplitChange).thenReturn(secondSplitChange).thenReturn(thirdSplitChange); mSplitsSyncHelper.sync(getSinceChangeNumbers(3, -1), ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); - verify(mSplitsStorage, times(3)).getTill(); + verify(mGeneralInfoStorage, times(3)).getFlagsChangeNumber(); verify(mSplitsFetcher, times(3)).execute(any(), any()); } @Test public void syncWithClearBeforeUpdateOnlyClearsStorageOnce() throws HttpFetcherException { when(mSplitsFetcher.execute(mDefaultParams, null)).thenReturn(mTargetingRulesChange); - when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 4L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, 2L, 4L); mSplitsSyncHelper.sync(getSinceChangeNumbers(3, -1), true, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -259,7 +259,7 @@ public void syncWithClearBeforeUpdateOnlyClearsStorageOnce() throws HttpFetcherE @Test public void syncWithoutClearBeforeUpdateDoesNotClearStorage() { - when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 4L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, 2L, 4L); mSplitsSyncHelper.sync(getSinceChangeNumbers(3, -1), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -268,8 +268,8 @@ public void syncWithoutClearBeforeUpdateDoesNotClearStorage() { @Test public void cdnIsBypassedWhenNeeded() throws HttpFetcherException { - when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L); - when(mRuleBasedSegmentStorageProducer.getChangeNumber()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L); + when(mGeneralInfoStorage.getRbsChangeNumber()).thenReturn(-1L); when(mSplitsFetcher.execute(anyMap(), any())).thenReturn( getSplitChange(-1, 2), getSplitChange(2, 3), @@ -304,8 +304,8 @@ public void cdnIsBypassedWhenNeeded() throws HttpFetcherException { @Test public void cdnIsBypassedWhenNeededWithRuleBasedSegments() throws HttpFetcherException { - when(mRuleBasedSegmentStorageProducer.getChangeNumber()).thenReturn(-1L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getRbsChangeNumber()).thenReturn(-1L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); when(mSplitsFetcher.execute(anyMap(), any())).thenReturn( getRuleBasedSegmentChange(-1, 2), getRuleBasedSegmentChange(2, 3), @@ -340,7 +340,7 @@ public void cdnIsBypassedWhenNeededWithRuleBasedSegments() throws HttpFetcherExc @Test public void backoffIsAppliedWhenRetryingSplits() throws HttpFetcherException { - when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 3L, 3L, 4L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, 2L, 3L, 3L, 4L); when(mSplitsFetcher.execute(anyMap(), any())).thenReturn( getSplitChange(-1, 2), getSplitChange(2, 3), @@ -372,7 +372,7 @@ public void replaceTillWhenFilterHasChanged() throws HttpFetcherException { public void returnTaskInfoToDoNotRetryWhenHttpFetcherExceptionStatusCodeIs414() throws HttpFetcherException { when(mSplitsFetcher.execute(eq(mDefaultParams), any())) .thenThrow(new HttpFetcherException("error", "error", 414)); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -383,7 +383,7 @@ public void returnTaskInfoToDoNotRetryWhenHttpFetcherExceptionStatusCodeIs414() public void doNotRetryFlagIsNullWhenFetcherExceptionStatusCodeIsNot414() throws HttpFetcherException { when(mSplitsFetcher.execute(eq(mDefaultParams), any())) .thenThrow(new HttpFetcherException("error", "error", 500)); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -394,7 +394,7 @@ public void doNotRetryFlagIsNullWhenFetcherExceptionStatusCodeIsNot414() throws public void returnTaskInfoToDoNotRetryWhenHttpFetcherExceptionStatusCodeIs9009() throws HttpFetcherException { when(mSplitsFetcher.execute(eq(mDefaultParams), any())) .thenThrow(new HttpFetcherException("error", "error", 9009)); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -405,7 +405,7 @@ public void returnTaskInfoToDoNotRetryWhenHttpFetcherExceptionStatusCodeIs9009() public void doNotRetryFlagIsNullWhenFetcherExceptionStatusCodeIsNot9009() throws HttpFetcherException { when(mSplitsFetcher.execute(eq(mDefaultParams), any())) .thenThrow(new HttpFetcherException("error", "error", 500)); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); SplitTaskExecutionInfo result = mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); @@ -436,7 +436,7 @@ public void proxyErrorTriggersFallbackAndOmitsRbSince() throws Exception { .thenThrow(new HttpFetcherException("Proxy outdated", "Proxy outdated", HttpStatus.INTERNAL_PROXY_OUTDATED.getCode())) // Use real status code .thenReturn(TargetingRulesChange.create(SplitChange.create(-1, 2, Collections.emptyList()), RuleBasedSegmentChange.create(-1, 2, Collections.emptyList()))) .thenReturn(TargetingRulesChange.create(SplitChange.create(2, 2, Collections.emptyList()), RuleBasedSegmentChange.create(2, 2, Collections.emptyList()))); - when(mSplitsStorage.getTill()).thenReturn(-1L, -1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, -1L); // First sync triggers the proxy error and sets fallback mode try { @@ -476,7 +476,7 @@ public void fallbackPersistsUntilIntervalElapses() throws Exception { .thenReturn(TargetingRulesChange.create(SplitChange.create(-1, 2, Collections.emptyList()), RuleBasedSegmentChange.create(-1, 2, Collections.emptyList()))) .thenReturn(TargetingRulesChange.create(SplitChange.create(3, 3, Collections.emptyList()), RuleBasedSegmentChange.create(3, 3, Collections.emptyList()))); // Simulate advancing change numbers for storage - when(mSplitsStorage.getTill()).thenReturn(-1L, 2L, 3L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L, 2L, 3L); // Trigger fallback try { mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); } catch (Exception ignored) {} // Simulate time NOT elapsed @@ -490,10 +490,10 @@ public void fallbackPersistsUntilIntervalElapses() throws Exception { @Test public void generic400InFallbackDoesNotResetToNone() throws Exception { // Simulate proxy outdated error + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); when(mSplitsFetcher.execute(any(), any())) .thenThrow(new HttpFetcherException("Proxy outdated", "Proxy outdated", HttpStatus.INTERNAL_PROXY_OUTDATED.getCode())) .thenThrow(new HttpFetcherException("Bad Request", "Bad Request", 400)); - when(mSplitsStorage.getTill()).thenReturn(-1L); // Trigger fallback mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); // Next call gets a generic 400, should remain in fallback @@ -512,7 +512,7 @@ public void successfulRecoveryReturnsToNormalSpec() throws Exception { .thenThrow(new HttpFetcherException("Proxy outdated", "Proxy outdated", HttpStatus.INTERNAL_PROXY_OUTDATED.getCode())) .thenReturn(TargetingRulesChange.create(SplitChange.create(-1, 2, Collections.emptyList()), RuleBasedSegmentChange.create(-1, 2, Collections.emptyList()))) .thenReturn(TargetingRulesChange.create(SplitChange.create(2, 2, Collections.emptyList()), RuleBasedSegmentChange.create(2, 2, Collections.emptyList()))); - when(mSplitsStorage.getTill()).thenReturn(-1L); + when(mGeneralInfoStorage.getFlagsChangeNumber()).thenReturn(-1L); // Trigger fallback try { mSplitsSyncHelper.sync(getSinceChangeNumbers(-1, -1L), false, false, ServiceConstants.ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES); } catch (Exception ignored) {} // Simulate interval elapsed diff --git a/src/test/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilderTest.java b/src/test/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilderTest.java index b5f2ade6a..e2106f0b6 100644 --- a/src/test/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilderTest.java +++ b/src/test/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilderTest.java @@ -38,7 +38,7 @@ public class SplitsSyncWorkerTaskBuilderTest { private HttpFetcher mSplitsFetcher; private TelemetryStorage mTelemetryStorage; private RuleBasedSegmentStorageProducer mRuleBasedSegmentStorageProducer; - private GeneralInfoStorage mGeneralinfoStorage; + private GeneralInfoStorage mGeneralInfoStorage; @Before public void setUp() throws URISyntaxException { @@ -51,11 +51,12 @@ public void setUp() throws URISyntaxException { mSplitsSyncHelperProvider = mock(SyncHelperProvider.class); mRuleBasedSegmentStorageProducer = mock(RuleBasedSegmentStorageProducer.class); mRuleBasedSegmentChangeProcessor = mock(RuleBasedSegmentChangeProcessor.class); - mGeneralinfoStorage = mock(GeneralInfoStorage.class); + mGeneralInfoStorage = mock(GeneralInfoStorage.class); when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn("filterQueryString"); when(mStorageProvider.provideSplitsStorage()).thenReturn(mSplitsStorage); when(mStorageProvider.provideRuleBasedSegmentStorage()).thenReturn(mRuleBasedSegmentStorageProducer); + when(mStorageProvider.provideGeneralInfoStorage()).thenReturn(mGeneralInfoStorage); when(mStorageProvider.provideTelemetryStorage()).thenReturn(mTelemetryStorage); when(mFetcherProvider.provideFetcher("filterQueryString")).thenReturn(mSplitsFetcher); when(mSplitsSyncHelperProvider.provideSplitsSyncHelper(any(), any(), any(), any(), any(), any(), any(), any())).thenReturn(mock(SplitsSyncHelper.class)); @@ -70,6 +71,15 @@ public void getTaskUsesStorageProviderForSplitsStorage() { verify(mStorageProvider).provideSplitsStorage(); } + @Test + public void getTaskUsesStorageProviderForGeneralInfoStorage() { + SplitsSyncWorkerTaskBuilder builder = getSplitsSyncWorkerTaskBuilder(null); + + builder.getTask(); + + verify(mStorageProvider).provideGeneralInfoStorage(); + } + @Test public void getTaskUsesFetcherProviderForFetcher() throws URISyntaxException { SplitsSyncWorkerTaskBuilder builder = getSplitsSyncWorkerTaskBuilder(null); @@ -99,7 +109,7 @@ public void getTaskUsesSplitsSyncHelperProviderForSplitsSyncHelper() throws URIS when(mSplitsStorage.getSplitsFilterQueryString()).thenReturn("string"); when(mStorageProvider.provideRuleBasedSegmentStorage()).thenReturn(mRuleBasedSegmentStorageProducer); when(mFetcherProvider.provideFetcher("string")).thenReturn(mSplitsFetcher); - when(mStorageProvider.provideGeneralInfoStorage()).thenReturn(mGeneralinfoStorage); + when(mStorageProvider.provideGeneralInfoStorage()).thenReturn(mGeneralInfoStorage); SplitsSyncWorkerTaskBuilder builder = new SplitsSyncWorkerTaskBuilder( mStorageProvider, @@ -118,7 +128,7 @@ public void getTaskUsesSplitsSyncHelperProviderForSplitsSyncHelper() throws URIS mSplitChangeProcessor, mRuleBasedSegmentChangeProcessor, mRuleBasedSegmentStorageProducer, - mGeneralinfoStorage, + mGeneralInfoStorage, mTelemetryStorage, "1.5"); } @@ -140,12 +150,16 @@ public void getTaskUsesSplitSyncTaskStaticMethod() { SplitsSyncHelper splitsSyncHelper = mock(SplitsSyncHelper.class); when(mSplitsSyncHelperProvider.provideSplitsSyncHelper(any(), any(), any(), any(), any(), any(), any(), any())).thenReturn(splitsSyncHelper); when(mStorageProvider.provideRuleBasedSegmentStorage()).thenReturn(mRuleBasedSegmentStorageProducer); + when(mStorageProvider.provideGeneralInfoStorage()).thenReturn(mGeneralInfoStorage); SplitsSyncWorkerTaskBuilder builder = getSplitsSyncWorkerTaskBuilder("2.5"); builder.getTask(); - mockedStatic.verify(() -> SplitsSyncTask.buildForBackground(splitsSyncHelper, mSplitsStorage, mRuleBasedSegmentStorageProducer, "filterQueryString", mTelemetryStorage)); + mockedStatic.verify(() -> SplitsSyncTask.buildForBackground(splitsSyncHelper, + mGeneralInfoStorage, + "filterQueryString", + mTelemetryStorage)); } }