Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/instrumented.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ on:
pull_request:
branches:
- 'development'
- 'master'
- '*_baseline'

jobs:
test:
Expand Down
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
5.1.0 (Jan 17, 2025)
- Added support for the new impressions tracking toggle available on feature flags, both respecting the setting and including the new field being returned on SplitView type objects. Read more in our docs.

5.0.1 (Nov 22, 2024)
- Optimized persistence of impressions deduplication cache.

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 = '5.0.1'
splitVersion = '5.1.0'
}

android {
Expand Down
124 changes: 124 additions & 0 deletions src/androidTest/assets/split_changes_imp_toggle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{
"splits": [
{
"trafficTypeName": "user",
"name": "tracked",
"trafficAllocation": 100,
"trafficAllocationSeed": -285565213,
"seed": -1992295819,
"status": "ACTIVE",
"killed": false,
"defaultTreatment": "off",
"changeNumber": 1506703262916,
"algo": 2,
"impressionsDisabled": false,
"conditions": [
{
"conditionType": "ROLLOUT",
"matcherGroup": {
"combiner": "AND",
"matchers": [
{
"keySelector": {
"trafficType": "client",
"attribute": null
},
"matcherType": "IN_SEGMENT",
"negate": false,
"userDefinedSegmentMatcherData": {
"segmentName": "new_segment"
},
"whitelistMatcherData": null,
"unaryNumericMatcherData": null,
"betweenMatcherData": null,
"booleanMatcherData": null,
"dependencyMatcherData": null,
"stringMatcherData": null
}
]
},
"partitions": [
{
"treatment": "on",
"size": 0
},
{
"treatment": "off",
"size": 0
},
{
"treatment": "free",
"size": 100
},
{
"treatment": "conta",
"size": 0
}
],
"label": "in segment new_segment"
}
]
},
{
"trafficTypeName": "user",
"name": "not_tracked",
"trafficAllocation": 100,
"trafficAllocationSeed": -285565213,
"seed": -1992295819,
"status": "ACTIVE",
"killed": false,
"defaultTreatment": "off",
"changeNumber": 1506703262916,
"algo": 2,
"impressionsDisabled": true,
"conditions": [
{
"conditionType": "ROLLOUT",
"matcherGroup": {
"combiner": "AND",
"matchers": [
{
"keySelector": {
"trafficType": "client",
"attribute": null
},
"matcherType": "IN_SEGMENT",
"negate": false,
"userDefinedSegmentMatcherData": {
"segmentName": "new_segment"
},
"whitelistMatcherData": null,
"unaryNumericMatcherData": null,
"betweenMatcherData": null,
"booleanMatcherData": null,
"dependencyMatcherData": null,
"stringMatcherData": null
}
]
},
"partitions": [
{
"treatment": "on",
"size": 0
},
{
"treatment": "off",
"size": 0
},
{
"treatment": "free",
"size": 100
},
{
"treatment": "conta",
"size": 0
}
],
"label": "in segment new_segment"
}
]
}
],
"since": 1506703262916,
"till": 1506703262916
}
9 changes: 7 additions & 2 deletions src/androidTest/java/fake/HttpClientMock.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@
import io.split.android.client.network.HttpStreamRequest;
import io.split.android.client.network.HttpStreamResponse;

import static java.lang.Thread.sleep;

/**
* Prefer using {@link okhttp3.mockwebserver.MockWebServer} to mock / intercept responses.
* <p>
* That will ensure the SDK uses the default HTTP client.
*/
@Deprecated
public class HttpClientMock implements HttpClient {
HttpResponseMockDispatcher mResponseDispatcher;

public HttpClientMock(HttpResponseMockDispatcher responseDispatcher) throws IOException {
mResponseDispatcher = responseDispatcher;
}
Expand Down
4 changes: 2 additions & 2 deletions src/androidTest/java/fake/SyncManagerStub.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fake;

import io.split.android.client.dtos.Event;
import io.split.android.client.impressions.Impression;
import io.split.android.client.impressions.DecoratedImpression;
import io.split.android.client.service.synchronizer.SyncManager;
import io.split.android.client.shared.UserConsent;

Expand Down Expand Up @@ -42,6 +42,6 @@ public void pushEvent(Event event) {
}

@Override
public void pushImpression(Impression impression) {
public void pushImpression(DecoratedImpression impression) {
}
}
13 changes: 7 additions & 6 deletions src/androidTest/java/fake/SynchronizerSpyImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

import io.split.android.client.api.Key;
import io.split.android.client.dtos.Event;
import io.split.android.client.impressions.Impression;
import io.split.android.client.impressions.DecoratedImpression;
import io.split.android.client.service.synchronizer.Synchronizer;
import io.split.android.client.service.synchronizer.SynchronizerSpy;
import io.split.android.client.service.synchronizer.attributes.AttributesSynchronizer;
Expand Down Expand Up @@ -87,7 +88,7 @@ public void pushEvent(Event event) {
}

@Override
public void pushImpression(Impression impression) {
public void pushImpression(DecoratedImpression impression) {
mSynchronizer.pushImpression(impression);
}

Expand Down Expand Up @@ -122,12 +123,12 @@ public void unregisterAttributesSynchronizer(String userKey) {
}

@Override
public void registerMySegmentsSynchronizer(String userKey, MySegmentsSynchronizer mySegmentsSynchronizer) {
((MySegmentsSynchronizerRegistry) mSynchronizer).registerMySegmentsSynchronizer(userKey, mySegmentsSynchronizer);
public void registerMySegmentsSynchronizer(Key key, MySegmentsSynchronizer mySegmentsSynchronizer) {
((MySegmentsSynchronizerRegistry) mSynchronizer).registerMySegmentsSynchronizer(key, mySegmentsSynchronizer);
}

@Override
public void unregisterMySegmentsSynchronizer(String userKey) {
((MySegmentsSynchronizerRegistry) mSynchronizer).unregisterMySegmentsSynchronizer(userKey);
public void unregisterMySegmentsSynchronizer(Key key) {
((MySegmentsSynchronizerRegistry) mSynchronizer).unregisterMySegmentsSynchronizer(key);
}
}
5 changes: 4 additions & 1 deletion src/androidTest/java/helper/DatabaseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ public static boolean removeDatabaseFile(String name) {
}

public static SplitRoomDatabase getTestDatabase(Context context) {
return Room.inMemoryDatabaseBuilder(context, SplitRoomDatabase.class)
SplitRoomDatabase database = Room.inMemoryDatabaseBuilder(context, SplitRoomDatabase.class)
.fallbackToDestructiveMigration()
.allowMainThreadQueries()
.build();

database.clearAllTables();
return database;
}
}
65 changes: 38 additions & 27 deletions src/androidTest/java/helper/IntegrationHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import fake.HttpClientMock;
import fake.HttpResponseMock;
Expand Down Expand Up @@ -390,40 +391,45 @@ public static <T> Set<T> asSet(T... elements) {
return result;
}

/**
* A simple interface to allow us to define the response for a given path
*/
public interface ResponseClosure {
HttpResponseMock onResponse(URI uri,
HttpMethod httpMethod,
String body);
public static long getTimestampDaysAgo(int days) {
return System.currentTimeMillis() - TimeUnit.DAYS.toMillis(days);
}

static String getSinceFromUri(URI uri) {
try {
return parse(uri.getQuery()).get("since");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}

public static String getSinceFromUri(URI uri) {
try {
return parse(uri.getQuery()).get("since");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}

static Map<String, String> parse(String query) throws UnsupportedEncodingException {
Map<String, String> queryPairs = new HashMap<>();
String[] pairs = query.split("&");
static Map<String, String> parse(String query) throws UnsupportedEncodingException {
Map<String, String> queryPairs = new HashMap<>();
String[] pairs = query.split("&");

for (String pair : pairs) {
int idx = pair.indexOf("=");
try {
String key = URLDecoder.decode(pair.substring(0, idx), "UTF-8");
String value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8");
for (String pair : pairs) {
int idx = pair.indexOf("=");
try {
String key = URLDecoder.decode(pair.substring(0, idx), "UTF-8");
String value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8");

queryPairs.put(key, value);
} catch (Exception e) {
e.printStackTrace();
}
queryPairs.put(key, value);
} catch (Exception e) {
e.printStackTrace();
}

return queryPairs;
}

return queryPairs;
}

/**
* A simple interface to allow us to define the response for a given path
*/
public interface ResponseClosure {
HttpResponseMock onResponse(URI uri,
HttpMethod httpMethod,
String body);
}

/**
Expand All @@ -435,5 +441,10 @@ public interface StreamingResponseClosure {

public static class ServicePath {
public static final String MEMBERSHIPS = "memberships";
public static final String SPLIT_CHANGES = "splitChanges";
public static final String EVENTS = "events";
public static final String UNIQUE_KEYS = "keys/cs";
public static final String COUNT = "testImpressions/count";
public static final String IMPRESSIONS = "testImpressions/bulk";
}
}
10 changes: 9 additions & 1 deletion src/androidTest/java/helper/TestableSplitConfigBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.lang.reflect.Constructor;

import io.split.android.client.RolloutCacheConfiguration;
import io.split.android.client.ServiceEndpoints;
import io.split.android.client.SplitClientConfig;
import io.split.android.client.SyncConfig;
Expand Down Expand Up @@ -64,6 +65,7 @@ public class TestableSplitConfigBuilder {
private String mPrefix = "";
private CertificatePinningConfiguration mCertificatePinningConfiguration;
private long mImpressionsDedupeTimeInterval = ServiceConstants.DEFAULT_IMPRESSIONS_DEDUPE_TIME_INTERVAL;
private RolloutCacheConfiguration mRolloutCacheConfiguration = RolloutCacheConfiguration.builder().build();

public TestableSplitConfigBuilder() {
mServiceEndpoints = ServiceEndpoints.builder().build();
Expand Down Expand Up @@ -274,6 +276,11 @@ public TestableSplitConfigBuilder impressionsDedupeTimeInterval(long impressions
return this;
}

public TestableSplitConfigBuilder rolloutCacheConfiguration(RolloutCacheConfiguration rolloutCacheConfiguration) {
this.mRolloutCacheConfiguration = rolloutCacheConfiguration;
return this;
}

public SplitClientConfig build() {
Constructor constructor = SplitClientConfig.class.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Expand Down Expand Up @@ -329,7 +336,8 @@ public SplitClientConfig build() {
mPrefix,
mObserverCacheExpirationPeriod,
mCertificatePinningConfiguration,
mImpressionsDedupeTimeInterval);
mImpressionsDedupeTimeInterval,
mRolloutCacheConfiguration);

Logger.instance().setLevel(mLogLevel);
return config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static helper.IntegrationHelper.ResponseClosure.getSinceFromUri;

import static helper.IntegrationHelper.getSinceFromUri;

import android.content.Context;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ public void usingNullPrefixResultsInIgnoredPrefix() {

private static String[] getDbList(Context context) {
// remove -journal dbs since we're not interested in them
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return Arrays.stream(context.databaseList()).filter(db -> !db.endsWith("-journal")).toArray(String[]::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static helper.IntegrationHelper.ResponseClosure.getSinceFromUri;
import static helper.IntegrationHelper.getSinceFromUri;

import android.content.Context;

Expand Down
Loading
Loading