Skip to content

Commit

Permalink
Store segments change number (#687)
Browse files Browse the repository at this point in the history
  • Loading branch information
gthea authored Aug 7, 2024
1 parent c7a80d7 commit 5468055
Show file tree
Hide file tree
Showing 48 changed files with 457 additions and 317 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ name: Internal deploy
on:
push:
branches:
- development
- 'development'
- '*_baseline'

jobs:
build-app:
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ apply plugin: 'kotlin-android'
apply from: 'spec.gradle'

ext {
splitVersion = '4.3.0-alpha.1'
splitVersion = '4.3.0-alpha.2'
}

android {
Expand Down
6 changes: 3 additions & 3 deletions src/androidTest/java/helper/IntegrationHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,21 +159,21 @@ public static String dummyMySegments() {
}

public static String dummyMyLargeSegments() {
return "{\"myLargeSegments\":[\"large-segment1\", \"large-segment2\", \"large-segment3\"], \"changeNumber\": 9999999999999}";
return "{\"myLargeSegments\":[\"large-segment1\", \"large-segment2\", \"large-segment3\"], \"till\": 9999999999999}";
}

public static String emptyMySegments() {
return "{\"mySegments\":[]}";
}

public static String emptyMyLargeSegments() {
return "{\"mySegments\":[], \"changeNumber\": 9999999999999}";
return "{\"mySegments\":[], \"till\": 9999999999999}";
}

public static String randomizedMyLargeSegments() {
int randIntOne = (int) (Math.random() * 100);
int randIntTwo = (int) (Math.random() * 100);
return "{\"myLargeSegments\":[\"large-segment1\", \"large-random\", \"large-segment"+randIntOne+"\", \"large-segment"+randIntTwo+"\"], \"changeNumber\": 9999999999999}";
return "{\"myLargeSegments\":[\"large-segment1\", \"large-random\", \"large-segment"+randIntOne+"\", \"large-segment"+randIntTwo+"\"], \"till\": 9999999999999}";
}

public static String dummyApiKey() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import io.split.android.client.events.SplitEvent;
import io.split.android.client.events.SplitEventTask;
import io.split.android.client.service.impressions.ImpressionsMode;
import io.split.android.client.shared.UserConsent;
import io.split.android.client.storage.db.EventEntity;
import io.split.android.client.storage.db.ImpressionEntity;
import io.split.android.client.storage.db.ImpressionsCountEntity;
Expand Down Expand Up @@ -236,7 +235,7 @@ private static void verifySegments(SplitRoomDatabase testDatabase) {
fail("Segment user key not encrypted, it was " + segmentEntity.getUserKey());
}

boolean bodyCondition = segmentEntity.getSegmentList().trim().endsWith("=");
boolean bodyCondition = !segmentEntity.getSegmentList().trim().endsWith("}");
if (!bodyCondition) {
fail("Segment list not encrypted, it was " + segmentEntity.getSegmentList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.split.android.client.events.SplitEvent;
import io.split.android.client.storage.db.MyLargeSegmentEntity;
import io.split.android.client.storage.db.SplitRoomDatabase;
import io.split.android.client.storage.mysegments.SegmentChangeDTO;
import io.split.android.client.utils.Json;
import io.split.android.client.utils.logger.Logger;
import tests.integration.shared.TestingData;
Expand Down Expand Up @@ -88,8 +89,8 @@ public void unboundedLargeSegmentsUpdateTriggersSdkUpdate() throws IOException,
assertEquals(3, mEndpointHits.get(MY_LARGE_SEGMENTS).get());
assertEquals(2, mEndpointHits.get(SPLIT_CHANGES).get());
assertEquals(2, mEndpointHits.get(MY_SEGMENTS).get());
assertEquals("large-segment1,large-segment2,large-segment3", initialSegmentList);
assertEquals(4, testSetup.database.myLargeSegmentDao().getByUserKey(IntegrationHelper.dummyUserKey().matchingKey()).getSegmentList().split(",").length);
assertEquals("{\"segments\":[\"large-segment1\",\"large-segment2\",\"large-segment3\"],\"till\":9999999999999}", initialSegmentList);
assertEquals(4, Json.fromJson(testSetup.database.myLargeSegmentDao().getByUserKey(IntegrationHelper.dummyUserKey().matchingKey()).getSegmentList(), SegmentChangeDTO.class).getMySegments().size());
}

@Test
Expand All @@ -114,8 +115,8 @@ public void segmentRemovalTriggersSdkUpdateAndRemovesSegmentFromStorage() throws
assertTrue(splitsAwait);
assertTrue(myLargeSegmentsAwait);
assertTrue(updateAwait);
assertEquals("large-segment1,large-segment2,large-segment3", initialLargeSegmentsSize);
assertEquals("large-segment3", db.myLargeSegmentDao().getByUserKey(IntegrationHelper.dummyUserKey().matchingKey()).getSegmentList());
assertEquals("{\"segments\":[\"large-segment1\",\"large-segment2\",\"large-segment3\"],\"till\":9999999999999}", initialLargeSegmentsSize);
assertEquals("{\"segments\":[\"large-segment3\"],\"till\":1702507130121}", db.myLargeSegmentDao().getByUserKey(IntegrationHelper.dummyUserKey().matchingKey()).getSegmentList());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.Ignore;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;
Expand All @@ -21,6 +20,8 @@
import io.split.android.client.events.SplitEvent;
import io.split.android.client.exceptions.SplitInstantiationException;
import io.split.android.client.storage.db.SplitRoomDatabase;
import io.split.android.client.storage.mysegments.SegmentChangeDTO;
import io.split.android.client.utils.Json;
import tests.integration.shared.TestingHelper;

public class LargeSegmentsTest extends LargeSegmentTestHelper {
Expand Down Expand Up @@ -83,7 +84,6 @@ public void sdkUpdateIsEmittedForLargeSegmentsWhenLargeSegmentsChange() throws I
boolean readyAwait = readyLatch.await(5, TimeUnit.SECONDS);
boolean await = updateLatch.await(5, TimeUnit.SECONDS);


assertTrue(readyAwait);
assertTrue(await);
}
Expand Down Expand Up @@ -189,13 +189,14 @@ public void successfulSyncOfLargeSegmentsContainsSegmentsInDatabase() {
SplitFactory factory = getFactory(true, true, null, null, testDatabase);
getReadyClient(IntegrationHelper.dummyUserKey().matchingKey(), factory);

String[] largeSegments = testDatabase.myLargeSegmentDao()
SegmentChangeDTO largeSegments = Json.fromJson(testDatabase.myLargeSegmentDao()
.getByUserKey(IntegrationHelper.dummyUserKey().matchingKey())
.getSegmentList().split(",");
assertEquals(3, largeSegments.length);
assertEquals("large-segment1", largeSegments[0]);
assertEquals("large-segment2", largeSegments[1]);
assertEquals("large-segment3", largeSegments[2]);
.getSegmentList(), SegmentChangeDTO.class);
assertEquals(3, largeSegments.getMySegments().size());
assertEquals("large-segment1", largeSegments.getMySegments().get(0));
assertEquals("large-segment2", largeSegments.getMySegments().get(1));
assertEquals("large-segment3", largeSegments.getMySegments().get(2));
assertEquals(9999999999999L, largeSegments.getTill().longValue());
}

@Test
Expand All @@ -213,14 +214,16 @@ public void syncOfLargeSegmentsForMultiClient() throws InterruptedException {

latch.await(10, TimeUnit.SECONDS);

String segmentList1 = testDatabase.myLargeSegmentDao().getByUserKey("CUSTOMER_ID").getSegmentList();
String segmentList2 = testDatabase.myLargeSegmentDao().getByUserKey("key2").getSegmentList();
SegmentChangeDTO segmentList1 = Json.fromJson(testDatabase.myLargeSegmentDao().getByUserKey("CUSTOMER_ID").getSegmentList(), SegmentChangeDTO.class);
SegmentChangeDTO segmentList2 = Json.fromJson(testDatabase.myLargeSegmentDao().getByUserKey("key2").getSegmentList(), SegmentChangeDTO.class);

assertEquals(2, mEndpointHits.get("myLargeSegments").get());
assertEquals(4, segmentList1.split(",").length);
assertEquals(4, segmentList2.split(",").length);
assertEquals(4, segmentList1.getMySegments().size());
assertEquals(4, segmentList2.getMySegments().size());
assertNotEquals(segmentList1,
segmentList2);
assertEquals(9999999999999L, segmentList1.getTill().longValue());
assertEquals(9999999999999L, segmentList2.getTill().longValue());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
import io.split.android.client.storage.db.MySegmentDao;
import io.split.android.client.storage.db.MySegmentEntity;
import io.split.android.client.storage.db.SplitRoomDatabase;
import io.split.android.client.storage.mysegments.SegmentChangeDTO;
import io.split.android.client.telemetry.storage.InMemoryTelemetryStorage;
import io.split.android.client.utils.Json;
import io.split.android.client.utils.logger.Logger;
import tests.integration.shared.TestingData;
import tests.integration.shared.TestingHelper;
Expand Down Expand Up @@ -157,21 +159,19 @@ mApiKey, new Key(userKey),
pushMessage(TestingData.ESCAPED_KEY_LIST_NOTIFICATION_GZIP);
l1.await(5, TimeUnit.SECONDS);

MySegmentEntity e = mySegmentsDao.getByUserKey(userKey);
MySegmentEntity e1 = mySegmentsDao.getByUserKey(userKey2);

l1 = new CountDownLatch(1);
updateTask.setLatch(l1);
pushMessage(TestingData.SEGMENT_REMOVAL_NOTIFICATION);
l1.await(5, TimeUnit.SECONDS);

MySegmentEntity mySegmentEntity = getByKey(userKey, mDb);
MySegmentEntity mySegmentEntity2 = getByKey(userKey2, mDb);
Assert.assertTrue(mySegmentEntity.getSegmentList().contains("new_segment_added"));
Assert.assertFalse(mySegmentEntity.getSegmentList().contains("segment1"));
SegmentChangeDTO mySegmentEntity = Json.fromJson(getByKey(userKey, mDb).getSegmentList(), SegmentChangeDTO.class);
SegmentChangeDTO mySegmentEntity2 = Json.fromJson(getByKey(userKey2, mDb).getSegmentList(), SegmentChangeDTO.class);
Assert.assertTrue(mySegmentEntity.getMySegments().contains("new_segment_added"));
Assert.assertFalse(mySegmentEntity.getMySegments().contains("segment1"));

Assert.assertEquals(1, mySegmentEntity2.getMySegments().size());
Assert.assertEquals("new_segment_added", mySegmentEntity2.getMySegments().get(0));
Assert.assertEquals(4, mTelemetryStorage.popUpdatesFromSSE().getMySegments());
Assert.assertEquals("new_segment_added", mySegmentEntity2.getSegmentList());
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ public void mySegmentsUpdate() throws IOException, InterruptedException {
thirdUpdateLatch.await(5, TimeUnit.SECONDS);
MySegmentEntity mySegmentEntityEmptyPayload = mSplitRoomDatabase.mySegmentDao().getByUserKey(mUserKey.matchingKey());

Assert.assertEquals("segment1,segment2,segment3", mySegmentEntity.getSegmentList());
Assert.assertEquals("segment1", mySegmentEntityPayload.getSegmentList());
Assert.assertEquals("", mySegmentEntityEmptyPayload.getSegmentList());
Assert.assertEquals("{\"segments\":[\"segment1\",\"segment2\",\"segment3\"],\"till\":-1}", mySegmentEntity.getSegmentList());
Assert.assertEquals("{\"segments\":[\"segment1\"],\"till\":1584647532812}", mySegmentEntityPayload.getSegmentList());
Assert.assertEquals("{\"segments\":[],\"till\":1584647532812}", mySegmentEntityEmptyPayload.getSegmentList());
}

@Test
Expand Down Expand Up @@ -187,13 +187,13 @@ public void onPostExecutionView(SplitClient client) {
MySegmentEntity client1SegmentEntityEmptyPayload = mSplitRoomDatabase.mySegmentDao().getByUserKey(mUserKey.matchingKey());
MySegmentEntity client2SegmentEntityEmptyPayload = mSplitRoomDatabase.mySegmentDao().getByUserKey("key2");

Assert.assertEquals("segment1,segment2,segment3", client1SegmentEntity.getSegmentList());
Assert.assertEquals("segment1", client1SegmentEntityPayload.getSegmentList());
Assert.assertEquals("", client1SegmentEntityEmptyPayload.getSegmentList());
Assert.assertEquals("{\"segments\":[\"segment1\",\"segment2\",\"segment3\"],\"till\":-1}", client1SegmentEntity.getSegmentList());
Assert.assertEquals("{\"segments\":[\"segment1\"],\"till\":1584647532812}", client1SegmentEntityPayload.getSegmentList());
Assert.assertEquals("{\"segments\":[],\"till\":1584647532812}", client1SegmentEntityEmptyPayload.getSegmentList());

Assert.assertEquals("", client2SegmentEntity.getSegmentList());
Assert.assertEquals("", client2SegmentEntityPayload.getSegmentList());
Assert.assertEquals("", client2SegmentEntityEmptyPayload.getSegmentList());
Assert.assertEquals("{\"segments\":[],\"till\":-1}", client2SegmentEntity.getSegmentList());
Assert.assertEquals("{\"segments\":[],\"till\":-1}", client2SegmentEntityPayload.getSegmentList());
Assert.assertEquals("{\"segments\":[],\"till\":-1}", client2SegmentEntityEmptyPayload.getSegmentList());
}

private void testMySegmentsUpdate() throws InterruptedException {
Expand Down
40 changes: 27 additions & 13 deletions src/androidTest/java/tests/storage/MySegmentsStorageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ public void setUp() {

MySegmentEntity entity = new MySegmentEntity();
entity.setUserKey(mUserKey);
entity.setSegmentList("s1,s2,s3");
entity.setSegmentList("{\"segments\": [\"s1\",\"s2\",\"s3\"],\"till\":-1}");
entity.setUpdatedAt(System.currentTimeMillis() / 1000);
mRoomDb.mySegmentDao().update(entity);

entity = new MySegmentEntity();
entity.setUserKey("userkey-2");
entity.setSegmentList("s10,s20");
entity.setSegmentList("{\"segments\": [\"s10\",\"s20\"],\"till\":-1}");
entity.setUpdatedAt(System.currentTimeMillis() / 1000);
mRoomDb.mySegmentDao().update(entity);

Expand Down Expand Up @@ -82,30 +82,34 @@ public void getMySegments() {
@Test
public void updateSegments() {
mMySegmentsStorage.loadLocal();
mMySegmentsStorage.set(Arrays.asList("a1", "a2", "a3", "a4"));
mMySegmentsStorage.set(Arrays.asList("a1", "a2", "a3", "a4"), 2222222);
MySegmentsStorage mySegmentsStorage = mMySegmentsStorageContainer.getStorageForKey(mUserKey);
mySegmentsStorage.loadLocal();

Set<String> snapshot = new HashSet<>(mMySegmentsStorage.getAll());
long till = mMySegmentsStorage.getTill();
Set<String> newSnapshot = new HashSet<>(mySegmentsStorage.getAll());
long newTill = mySegmentsStorage.getTill();

assertEquals(4, snapshot.size());
assertTrue(snapshot.contains("a1"));
assertTrue(snapshot.contains("a2"));
assertTrue(snapshot.contains("a3"));
assertTrue(snapshot.contains("a4"));
assertEquals(2222222, till);

assertEquals(4, newSnapshot.size());
assertTrue(newSnapshot.contains("a1"));
assertTrue(newSnapshot.contains("a2"));
assertTrue(newSnapshot.contains("a3"));
assertTrue(newSnapshot.contains("a4"));
assertEquals(2222222, newTill);
}

@Test
public void updateEmptyMySegment() {
mMySegmentsStorage.loadLocal();
mMySegmentsStorage.set(new ArrayList<>());
mMySegmentsStorage.set(new ArrayList<>(), 11124442);

MySegmentsStorage mySegmentsStorage = mMySegmentsStorageContainer.getStorageForKey(mUserKey);
mySegmentsStorage.loadLocal();
Expand All @@ -115,12 +119,13 @@ public void updateEmptyMySegment() {

assertEquals(0, snapshot.size());
assertEquals(0, newSnapshot.size());
assertEquals(11124442, mySegmentsStorage.getTill());
}

@Test
public void addNullMySegmentsList() {

mPersistentMySegmentsStorage.set(mUserKey, null);
mPersistentMySegmentsStorage.set(mUserKey, null, -1); // till will be ignored
mMySegmentsStorage.loadLocal();
MySegmentsStorage mySegmentsStorage = mMySegmentsStorageContainer.getStorageForKey(mUserKey);
mySegmentsStorage.loadLocal();
Expand All @@ -130,6 +135,7 @@ public void addNullMySegmentsList() {

assertEquals(3, snapshot.size());
assertEquals(3, newSnapshot.size());
assertEquals(-1, mySegmentsStorage.getTill());
}

@Test
Expand All @@ -144,6 +150,7 @@ public void clear() {
Set<String> snapshot = new HashSet<>(mMySegmentsStorage.getAll());

assertEquals(0, snapshot.size());
assertEquals(-1, mySegmentsStorage.getTill());
}

@Test
Expand All @@ -153,7 +160,7 @@ public void originalValuesCanBeRetrievedWhenStorageIsEncrypted() {
mMySegmentsStorageContainer = new MySegmentsStorageContainerImpl(mPersistentMySegmentsStorage);
mMySegmentsStorage = mMySegmentsStorageContainer.getStorageForKey(mUserKey);

mMySegmentsStorage.set(Arrays.asList("a1", "a2", "a3", "a4"));
mMySegmentsStorage.set(Arrays.asList("a1", "a2", "a3", "a4"), 999820);
MySegmentsStorage mySegmentsStorage = mMySegmentsStorageContainer.getStorageForKey(mUserKey);
mySegmentsStorage.loadLocal();

Expand All @@ -163,14 +170,15 @@ public void originalValuesCanBeRetrievedWhenStorageIsEncrypted() {
assertTrue(all.contains("a3"));
assertTrue(all.contains("a4"));
assertEquals(4, all.size());
assertEquals(999820, mySegmentsStorage.getTill());
}

@Test
public void updateToStorageConcurrency() throws InterruptedException {
mMySegmentsStorage.loadLocal();
CountDownLatch latch = new CountDownLatch(2);

new Thread(new Runnable() {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int j = 1000; j < 1200; j += 10) {
Expand All @@ -183,13 +191,13 @@ public void run() {
Thread.sleep(80);
} catch (InterruptedException e) {
}
mMySegmentsStorage.set(segments);
mMySegmentsStorage.set(segments, 112421 + j);
}
latch.countDown();
}
}).start();
});

new Thread(new Runnable() {
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {

Expand All @@ -201,16 +209,22 @@ public void run() {
}
try {
Thread.sleep(80);
mMySegmentsStorage.set(segments);
mMySegmentsStorage.set(segments, 112421 + j);
Thread.sleep(80);
} catch (InterruptedException e) {
}
}
latch.countDown();
}
}).start();
});

thread1.start();
thread2.start();
thread1.join();
thread2.join();

latch.await(40, TimeUnit.SECONDS);
Set<String> l = mMySegmentsStorage.getAll();
assertEquals(10, mMySegmentsStorage.getAll().size());
assertEquals(112421 + 190, mMySegmentsStorage.getTill());
}
}
Loading

0 comments on commit 5468055

Please sign in to comment.