Skip to content

Commit

Permalink
Release 3.2.0 (#484)
Browse files Browse the repository at this point in the history
  • Loading branch information
gthea authored Apr 25, 2023
2 parents 093b55f + 1a4db4a commit 7fb0c57
Show file tree
Hide file tree
Showing 112 changed files with 3,927 additions and 525 deletions.
59 changes: 59 additions & 0 deletions .github/workflows/instrumented.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Instrumented tests

on:
pull_request:
branches:
- '*'

jobs:
test:
runs-on: macos-12

strategy:
fail-fast: false
matrix:
api-level: [ 29 ]
shard: [ 0, 1, 2, 3 ]

steps:
- name: checkout
uses: actions/checkout@v3

- name: Gradle cache
uses: gradle/gradle-build-action@v2

- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 11
cache: 'gradle'

- name: AVD cache
uses: actions/cache@v3
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ matrix.api-level }}

- name: create AVD and generate snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/[email protected]
with:
api-level: ${{ matrix.api-level }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: echo "Generated AVD snapshot for caching."

- name: Assemble debug AndroidTest
run: ./gradlew assembleDebugAndroidTest

- name: Run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
profile: Galaxy Nexus
script: ./gradlew connectedCheck --continue -Pandroid.testInstrumentationRunnerArguments.numShards=4 -Pandroid.testInstrumentationRunnerArguments.shardIndex=${{ matrix.shard }}
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
3.2.0 (Apr 25, 2023)
- Added the ability to encrypt the local cache of rollout plans via encryptionEnabled config.

3.1.0 (Mar 1, 2023)
- Changed default connection timeout to 10 seconds.
- Updated Lifecycle library to 2.5.1.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Split SDK for Android
[![Build Status](https://travis-ci.com/splitio/android-client.svg?branch=master)](https://travis-ci.com/splitio/android-client)
![Build Status](https://github.com/splitio/android-client/actions/workflows/sonar.yml/badge.svg?branch=master)

## Overview
This SDK is designed to work with Split, the platform for controlled rollouts, which serves features to your users via a Split feature flag to manage your complete customer experience.
Expand Down
24 changes: 18 additions & 6 deletions 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.1.0'
splitVersion = '3.2.0'
}

android {
Expand All @@ -37,14 +37,20 @@ android {
versionName splitVersion
multiDexEnabled true

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'split-proguard-rules.pro'

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'

javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}

testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
}

configurations {
Expand Down Expand Up @@ -107,7 +113,10 @@ dependencies {
def kotlinVer = '1.5.31'
def mockWebServerVersion = '3.12.13'

def androidTestVersion = '1.4.0'
def testRulesVersion = '1.4.0'
def jUnitExtVersion = '1.1.3'
def testRunnerVersion = '1.5.1'
def orchestratorVersion = '1.4.2'

implementation fileTree(include: ['*.jar'], dir: 'libs')

Expand All @@ -132,15 +141,18 @@ dependencies {
// Test
testImplementation "junit:junit:$jUnitVersion"
testImplementation "org.mockito:mockito-core:$mockitoVersion"
testImplementation "org.mockito:mockito-inline:$mockitoVersion"
testImplementation "org.hamcrest:hamcrest-all:$hamcrestVersion"
testImplementation "org.apache.commons:commons-lang3:$apacheCommonsVersion"
testImplementation "com.squareup.okhttp3:mockwebserver:$mockWebServerVersion"
testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVer"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlinVer"

androidTestImplementation "androidx.test:core:$androidTestVersion"
androidTestImplementation "androidx.test:runner:$androidTestVersion"
androidTestImplementation "androidx.test:rules:$androidTestVersion"
androidTestImplementation "androidx.test:rules:$testRulesVersion"
androidTestImplementation "androidx.test.ext:junit:$jUnitExtVersion"
androidTestImplementation "androidx.test:runner:$testRunnerVersion"
androidTestUtil "androidx.test:orchestrator:$orchestratorVersion"

androidTestImplementation "com.squareup.okhttp3:mockwebserver:$mockWebServerVersion"
androidTestImplementation "androidx.room:room-testing:$roomVersion"
androidTestImplementation "androidx.work:work-testing:$workVersion"
Expand Down
146 changes: 146 additions & 0 deletions src/androidTest/java/helper/DataSample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package helper

const val MOCK_DATA_IMPRESSION = """
{
"featureName": "onboarding",
"keyName": "9oIdSh7h+ACsSTBhZBMzgRHmljmcuZ6OioFinkdf4EtuElENWIYloE",
"bucketingKey": null,
"treatment": "on",
"label": "default rule",
"time":" 546546546549,
"changeNumber": 546546546549,
"previousTime": 498357419865
}
"""

const val MOCK_DATA_EVENT: String = """
{
"key": "CD16FqbutYKb5Mgd4TwAcXFOZsKrVm9QJM5LL1lwHoIn4SmOdOMqH",
"eventTypeId": "id33",
"trafficTypeName": "user",
"value": 123.0,
"timestamp": 5465465469,
"properties": ["prop1": 1, "prop2": "dos"],
"sizeInBytes": 0
}
"""

const val MOCK_DATA_SPLIT: String = """
{
"trafficTypeName":"account",
"name":"FACUNDO_TEST",
"trafficAllocation":59,
"trafficAllocationSeed":-2108186082,
"seed":-1947050785,
"status":"ACTIVE",
"killed":false,
"defaultTreatment":"off",
"changeNumber":1506703262916,
"algo":2,
"conditions":[
{
"conditionType":"WHITELIST",
"matcherGroup":{
"combiner":"AND",
"matchers":[
{
"keySelector":null,
"matcherType":"WHITELIST",
"negate":false,
"userDefinedSegmentMatcherData":null,
"whitelistMatcherData":{
"whitelist":[
"nico_test",
"othertest"
]
},
"unaryNumericMatcherData":null,
"betweenMatcherData":null,
"booleanMatcherData":null,
"dependencyMatcherData":null,
"stringMatcherData":null
}
]
},
"partitions":[
{
"treatment":"on",
"size":100
}
],
"label":"whitelisted"
},
{
"conditionType":"WHITELIST",
"matcherGroup":{
"combiner":"AND",
"matchers":[
{
"keySelector":null,
"matcherType":"WHITELIST",
"negate":false,
"userDefinedSegmentMatcherData":null,
"whitelistMatcherData":{
"whitelist":[
"bla"
]
},
"unaryNumericMatcherData":null,
"betweenMatcherData":null,
"booleanMatcherData":null,
"dependencyMatcherData":null,
"stringMatcherData":null
}
]
},
"partitions":[
{
"treatment":"off",
"size":100
}
],
"label":"whitelisted"
},
{
"conditionType":"ROLLOUT",
"matcherGroup":{
"combiner":"AND",
"matchers":[
{
"keySelector":{
"trafficType":"account",
"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":0
},
{
"treatment":"off",
"size":100
},
{
"treatment":"visa",
"size":0
}
],
"label":"in segment all"
}
]
}
"""

const val MOCK_DATA_LONG_TEXT = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed dolor arcu, ultrices eget diam ut, tincidunt rhoncus felis. Suspendisse vel libero nec risus tincidunt ultricies. Aenean a vulputate nulla, a viverra enim. Phasellus volutpat magna quam, non ultrices lorem facilisis id. Morbi ultrices est augue. Integer interdum nisi at erat molestie auctor. Donec in diam vel sapien tincidunt luctus."""
9 changes: 8 additions & 1 deletion src/androidTest/java/helper/TestableSplitConfigBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class TestableSplitConfigBuilder {
private int mMtkPerPush = 30000;
private int mMtkRefreshRate = 1800;
private UserConsent mUserConsent = UserConsent.GRANTED;
private boolean mEncryptionEnabled;

public TestableSplitConfigBuilder() {
mServiceEndpoints = ServiceEndpoints.builder().build();
Expand Down Expand Up @@ -230,6 +231,11 @@ public TestableSplitConfigBuilder userConsent(UserConsent value) {
return this;
}

public TestableSplitConfigBuilder encryptionEnabled(boolean enabled) {
this.mEncryptionEnabled = enabled;
return this;
}

public SplitClientConfig build() {
Constructor constructor = SplitClientConfig.class.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Expand Down Expand Up @@ -278,7 +284,8 @@ public SplitClientConfig build() {
mLogLevel,
mMtkPerPush,
mMtkRefreshRate,
mUserConsent);
mUserConsent,
mEncryptionEnabled);
return config;
} catch (Exception e) {
Logger.e("Error creating Testable Split client builder: "
Expand Down
78 changes: 78 additions & 0 deletions src/androidTest/java/tests/database/ExclusiveTransactionTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package tests.database

import androidx.test.platform.app.InstrumentationRegistry
import io.split.android.client.storage.db.SplitEntity
import io.split.android.client.storage.db.SplitRoomDatabase
import io.split.android.client.storage.db.attributes.AttributesEntity
import org.junit.Before
import org.junit.Test
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.test.fail

class ExclusiveTransactionTest {

private lateinit var db: SplitRoomDatabase

@Before
fun setUp() {
db = SplitRoomDatabase.getDatabase(
InstrumentationRegistry.getInstrumentation().context,
"test_db"
)
}

@Test
fun transactionPreventsReads() {
val writeFinished = AtomicBoolean(false)
val readFinished = AtomicBoolean(false)

// Insert multiple values in multiple DAOs inside a transaction
val updateThread = Thread() {
db.runInTransaction {
for (i in 0..400) {
db.splitDao().insert(
SplitEntity().apply {
name = "split${i}"
body = "body${i}"
updatedAt = System.currentTimeMillis()
}
)

db.attributesDao().update(
AttributesEntity().apply {
userKey = "key${i}"
attributes = "value${i}"
}
)
}
writeFinished.set(true)
}
}

// Read values from multiple DAOs
val readThread = Thread() {
db.splitDao().all
db.attributesDao().all
readFinished.set(true)
}

// Monitor the operations
val monitorThread = Thread() {
while (true) {
if (readFinished.get() && !writeFinished.get()) {
fail("Values were read before update was done")
} else if (writeFinished.get() && readFinished.get()) {
break
}
}
}

monitorThread.start()
readThread.start()
updateThread.start()

monitorThread.join(2000)
readThread.join(2000)
updateThread.join(2000)
}
}
Loading

0 comments on commit 7fb0c57

Please sign in to comment.