Skip to content

Commit

Permalink
Flag sets (#547)
Browse files Browse the repository at this point in the history
  • Loading branch information
gthea authored Oct 30, 2023
1 parent 49b49df commit a32b1ac
Show file tree
Hide file tree
Showing 104 changed files with 4,182 additions and 616 deletions.
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ apply plugin: 'signing'
apply plugin: 'kotlin-android'

ext {
splitVersion = '3.3.1-alpha-1'
splitVersion = '3.4.0-alpha-1'
}

android {
Expand Down Expand Up @@ -225,6 +225,7 @@ afterEvaluate {
release(MavenPublication) {
from components.release

artifactId = 'android-client'
groupId = 'io.split.client'
version = splitVersion
artifact sourcesJar
Expand All @@ -241,6 +242,7 @@ afterEvaluate {
development(MavenPublication) {
from components.release

artifactId = 'android-client'
groupId = 'io.split.client'
version = splitVersion
artifact sourcesJar
Expand Down
1 change: 1 addition & 0 deletions src/androidTest/assets/split_changes_flag_set-0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"splits":[{"trafficTypeName":"client","name":"workm","trafficAllocation":100,"trafficAllocationSeed":147392224,"seed":524417105,"status":"ACTIVE","killed":false,"defaultTreatment":"on","changeNumber":1602798638344,"algo":2,"configurations":{},"sets":["set_3"],"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"},{"conditionType":"ROLLOUT","matcherGroup":{"combiner":"AND","matchers":[{"keySelector":{"trafficType":"client","attribute":null},"matcherType":"ALL_KEYS","negate":false,"userDefinedSegmentMatcherData":null,"whitelistMatcherData":null,"unaryNumericMatcherData":null,"betweenMatcherData":null,"booleanMatcherData":null,"dependencyMatcherData":null,"stringMatcherData":null}]},"partitions":[{"treatment":"on","size":100},{"treatment":"off","size":0},{"treatment":"free","size":0},{"treatment":"conta","size":0}],"label":"default rule"}]}],"since":1602797638344,"till":1602798638344}
1 change: 1 addition & 0 deletions src/androidTest/assets/split_changes_flag_set-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"splits":[{"trafficTypeName":"client","name":"workm","trafficAllocation":100,"trafficAllocationSeed":147392224,"seed":524417105,"status":"ACTIVE","killed":false,"defaultTreatment":"on","changeNumber":1602797638344,"algo":2,"configurations":{},"sets":["set_1"],"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"},{"conditionType":"ROLLOUT","matcherGroup":{"combiner":"AND","matchers":[{"keySelector":{"trafficType":"client","attribute":null},"matcherType":"ALL_KEYS","negate":false,"userDefinedSegmentMatcherData":null,"whitelistMatcherData":null,"unaryNumericMatcherData":null,"betweenMatcherData":null,"booleanMatcherData":null,"dependencyMatcherData":null,"stringMatcherData":null}]},"partitions":[{"treatment":"on","size":100},{"treatment":"off","size":0},{"treatment":"free","size":0},{"treatment":"conta","size":0}],"label":"default rule"}]}],"since":1602796638344,"till":1602797638344}
1 change: 1 addition & 0 deletions src/androidTest/assets/split_changes_flag_set-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"splits":[{"trafficTypeName":"client","name":"workm","trafficAllocation":100,"trafficAllocationSeed":147392224,"seed":524417105,"status":"ACTIVE","killed":false,"defaultTreatment":"on","changeNumber":1602796638344,"algo":2,"configurations":{},"sets":["set_1","set_2"],"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"},{"conditionType":"ROLLOUT","matcherGroup":{"combiner":"AND","matchers":[{"keySelector":{"trafficType":"client","attribute":null},"matcherType":"ALL_KEYS","negate":false,"userDefinedSegmentMatcherData":null,"whitelistMatcherData":null,"unaryNumericMatcherData":null,"betweenMatcherData":null,"booleanMatcherData":null,"dependencyMatcherData":null,"stringMatcherData":null}]},"partitions":[{"treatment":"on","size":100},{"treatment":"off","size":0},{"treatment":"free","size":0},{"treatment":"conta","size":0}],"label":"default rule"}]},{"trafficTypeName":"client","name":"workm_set_3","trafficAllocation":100,"trafficAllocationSeed":147392224,"seed":524417105,"status":"ACTIVE","killed":false,"defaultTreatment":"on","changeNumber":1602796638344,"algo":2,"configurations":{},"sets":["set_3"],"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"},{"conditionType":"ROLLOUT","matcherGroup":{"combiner":"AND","matchers":[{"keySelector":{"trafficType":"client","attribute":null},"matcherType":"ALL_KEYS","negate":false,"userDefinedSegmentMatcherData":null,"whitelistMatcherData":null,"unaryNumericMatcherData":null,"betweenMatcherData":null,"booleanMatcherData":null,"dependencyMatcherData":null,"stringMatcherData":null}]},"partitions":[{"treatment":"on","size":100},{"treatment":"off","size":0},{"treatment":"free","size":0},{"treatment":"conta","size":0}],"label":"default rule"}]}],"since":-1,"till":1602796638344}
20 changes: 20 additions & 0 deletions src/androidTest/java/fake/SplitClientStub.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ public Map<String, SplitResult> getTreatmentsWithConfig(List<String> featureFlag
return null;
}

@Override
public Map<String, String> getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
return null;
}

@Override
public Map<String, String> getTreatmentsByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
return null;
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map<String, Object> attributes) {
return null;
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(@NonNull List<String> flagSets, @Nullable Map<String, Object> attributes) {
return null;
}

@Override
public void destroy() {

Expand Down
5 changes: 0 additions & 5 deletions src/androidTest/java/fake/SynchronizerSpyImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ public void loadAndSynchronizeSplits() {
mSynchronizer.loadAndSynchronizeSplits();
}

@Override
public void loadSplitsFromCache() {
mSynchronizer.loadSplitsFromCache();
}

@Override
public void loadMySegmentsFromCache() {
mSynchronizer.loadMySegmentsFromCache();
Expand Down
30 changes: 18 additions & 12 deletions src/androidTest/java/helper/IntegrationHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;

import androidx.annotation.Nullable;
import androidx.core.util.Pair;

import com.google.common.base.Strings;
Expand All @@ -16,6 +17,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;

import fake.HttpClientMock;
import fake.HttpResponseMock;
Expand Down Expand Up @@ -257,30 +259,36 @@ public static String splitChangeV2CompressionType0() {
"eyJ0cmFmZmljVHlwZU5hbWUiOiJ1c2VyIiwiaWQiOiJkNDMxY2RkMC1iMGJlLTExZWEtOGE4MC0xNjYwYWRhOWNlMzkiLCJuYW1lIjoibWF1cm9famF2YSIsInRyYWZmaWNBbGxvY2F0aW9uIjoxMDAsInRyYWZmaWNBbGxvY2F0aW9uU2VlZCI6LTkyMzkxNDkxLCJzZWVkIjotMTc2OTM3NzYwNCwic3RhdHVzIjoiQUNUSVZFIiwia2lsbGVkIjpmYWxzZSwiZGVmYXVsdFRyZWF0bWVudCI6Im9mZiIsImNoYW5nZU51bWJlciI6MTY4NDMyOTg1NDM4NSwiYWxnbyI6MiwiY29uZmlndXJhdGlvbnMiOnt9LCJjb25kaXRpb25zIjpbeyJjb25kaXRpb25UeXBlIjoiV0hJVEVMSVNUIiwibWF0Y2hlckdyb3VwIjp7ImNvbWJpbmVyIjoiQU5EIiwibWF0Y2hlcnMiOlt7Im1hdGNoZXJUeXBlIjoiV0hJVEVMSVNUIiwibmVnYXRlIjpmYWxzZSwid2hpdGVsaXN0TWF0Y2hlckRhdGEiOnsid2hpdGVsaXN0IjpbImFkbWluIiwibWF1cm8iLCJuaWNvIl19fV19LCJwYXJ0aXRpb25zIjpbeyJ0cmVhdG1lbnQiOiJvZmYiLCJzaXplIjoxMDB9XSwibGFiZWwiOiJ3aGl0ZWxpc3RlZCJ9LHsiY29uZGl0aW9uVHlwZSI6IlJPTExPVVQiLCJtYXRjaGVyR3JvdXAiOnsiY29tYmluZXIiOiJBTkQiLCJtYXRjaGVycyI6W3sia2V5U2VsZWN0b3IiOnsidHJhZmZpY1R5cGUiOiJ1c2VyIn0sIm1hdGNoZXJUeXBlIjoiSU5fU0VHTUVOVCIsIm5lZ2F0ZSI6ZmFsc2UsInVzZXJEZWZpbmVkU2VnbWVudE1hdGNoZXJEYXRhIjp7InNlZ21lbnROYW1lIjoibWF1ci0yIn19XX0sInBhcnRpdGlvbnMiOlt7InRyZWF0bWVudCI6Im9uIiwic2l6ZSI6MH0seyJ0cmVhdG1lbnQiOiJvZmYiLCJzaXplIjoxMDB9LHsidHJlYXRtZW50IjoiVjQiLCJzaXplIjowfSx7InRyZWF0bWVudCI6InY1Iiwic2l6ZSI6MH1dLCJsYWJlbCI6ImluIHNlZ21lbnQgbWF1ci0yIn0seyJjb25kaXRpb25UeXBlIjoiUk9MTE9VVCIsIm1hdGNoZXJHcm91cCI6eyJjb21iaW5lciI6IkFORCIsIm1hdGNoZXJzIjpbeyJrZXlTZWxlY3RvciI6eyJ0cmFmZmljVHlwZSI6InVzZXIifSwibWF0Y2hlclR5cGUiOiJBTExfS0VZUyIsIm5lZ2F0ZSI6ZmFsc2V9XX0sInBhcnRpdGlvbnMiOlt7InRyZWF0bWVudCI6Im9uIiwic2l6ZSI6MH0seyJ0cmVhdG1lbnQiOiJvZmYiLCJzaXplIjoxMDB9LHsidHJlYXRtZW50IjoiVjQiLCJzaXplIjowfSx7InRyZWF0bWVudCI6InY1Iiwic2l6ZSI6MH1dLCJsYWJlbCI6ImRlZmF1bHQgcnVsZSJ9XX0=");
}

private static String splitChangeV2(String changeNumber, String previousChangeNumber, String compressionType, String compressedPayload) {
public static String splitChangeV2(String changeNumber, String previousChangeNumber, String compressionType, String compressedPayload) {
return "id: vQQ61wzBRO:0:0\n" +
"event: message\n" +
"data: {\"id\":\"m2T85LA4fQ:0:0\",\"clientId\":\"pri:NzIyNjY1MzI4\",\"timestamp\":"+System.currentTimeMillis()+",\"encoding\":\"json\",\"channel\":\"NzM2MDI5Mzc0_MTgyNTg1MTgwNg==_splits\",\"data\":\"{\\\"type\\\":\\\"SPLIT_UPDATE\\\",\\\"changeNumber\\\":"+changeNumber+",\\\"pcn\\\":"+previousChangeNumber+",\\\"c\\\":"+compressionType+",\\\"d\\\":\\\""+compressedPayload+"\\\"}\"}\n";
}

public static String splitKill(String changeNumber, String splitName) {
return "id:cf74eb42-f687-48e4-ad18-af2125110aac\n" +
"event:message\n" +
"data:{\"id\":\"-OT-rGuSwz:0:0\",\"clientId\":\"NDEzMTY5Mzg0MA==:NDIxNjU0NTUyNw==\",\"timestamp\":"+System.currentTimeMillis()+",\"encoding\":\"json\",\"channel\":\"NzM2MDI5Mzc0_MTgyNTg1MTgwNg==_splits\",\"data\":\"{\\\"type\\\":\\\"SPLIT_KILL\\\",\\\"changeNumber\\\":" + changeNumber + ",\\\"defaultTreatment\\\":\\\"off\\\",\\\"splitName\\\":\\\"" + splitName + "\\\"}\"}\n";
}

/**
* Builds a dispatcher with the given responses.
*
* @param responses The responses to be returned by the dispatcher. The keys are url paths.
* @return The dispatcher to be used in {@link HttpClientMock}
*/
public static HttpResponseMockDispatcher buildDispatcher(Map<String, ResponseClosure> responses) {
return buildDispatcher(responses, Collections.emptyMap());
return buildDispatcher(responses, null);
}

/**
* Builds a dispatcher with the given responses.
*
* @param responses The responses to be returned by the dispatcher. The keys are url paths.
* @param streamingResponses The streaming responses to be returned by the dispatcher. The keys are url paths.
* @param streamingQueue The streaming responses to be returned by the dispatcher.
* @return The dispatcher to be used in {@link HttpClientMock}
*/
public static HttpResponseMockDispatcher buildDispatcher(Map<String, ResponseClosure> responses, Map<String, StreamingResponseClosure> streamingResponses) {
public static HttpResponseMockDispatcher buildDispatcher(Map<String, ResponseClosure> responses, @Nullable BlockingQueue<String> streamingQueue) {
return new HttpResponseMockDispatcher() {
@Override
public HttpResponseMock getResponse(URI uri, HttpMethod method, String body) {
Expand All @@ -300,17 +308,11 @@ public HttpResponseMock getResponse(URI uri, HttpMethod method, String body) {
@Override
public HttpStreamResponseMock getStreamResponse(URI uri) {
try {
String path = uri.getPath().replace("/api/", "");
if (streamingResponses.containsKey(path)) {
return streamingResponses.get(path).onResponse(uri);
} else {
return new HttpStreamResponseMock(200, null);
}
return new HttpStreamResponseMock(200, streamingQueue);
} catch (IOException e) {
e.printStackTrace();
return null;
}

return null;
}
};
}
Expand All @@ -322,6 +324,10 @@ public interface ResponseClosure {
HttpResponseMock onResponse(URI uri,
HttpMethod httpMethod,
String body);

static String getSinceFromUri(URI uri) {
return uri.getQuery().split("&")[0].split("=")[1];
}
}

/**
Expand Down
Loading

0 comments on commit a32b1ac

Please sign in to comment.