Skip to content
This repository has been archived by the owner on Apr 5, 2023. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
ujjawalgarg committed Aug 29, 2019
2 parents 98e55da + 7139c21 commit 5a03ebf
Show file tree
Hide file tree
Showing 25 changed files with 277 additions and 100 deletions.
20 changes: 13 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
language: android
# you MUST mention trusty https://docs.travis-ci.com/user/languages/android/
dist: trusty
env:
global:
# These parameters should match the parameters for build tools and sdk versions in the gradle file
- ANDROID_BUILD_TOOLS=28.0.3 # should match gradle
- ADB_INSTALL_TIMEOUT=5 # minutes
- ANDROID_API=28 # api is same as gradle file
matrix:
- EMULATOR_API=22
- EMULATOR_API=21
- EMULATOR_API=22
android:
components:
- tools
- platform-tools
- tools
- platform-tools-$ANDROID_BUILD_TOOLS
- build-tools-$ANDROID_BUILD_TOOLS
- android-$ANDROID_API
- android-$EMULATOR_API
Expand All @@ -35,13 +36,13 @@ cache:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
before_install:
- yes | sdkmanager "platforms;android-28"
#- yes | sdkmanager "platforms;android-$ANDROID_API"
before_script:
- echo $TRAVIS_BRANCH
- echo $TRAVIS_TAG
- echo no | android create avd --force -n test -t android-$EMULATOR_API --abi armeabi-v7a
- emulator -avd test -no-audio -no-window &
- android-wait-for-emulator
- scripts/android-wait-for-emulator.sh
- adb shell input keyevent 82 &
addons:
srcclr: true
Expand All @@ -53,11 +54,13 @@ script:
# Integration tests need to run first to reset the PR build status to pending
stages:
- 'Integration tests'
- 'Benchmarking tests'
- 'Test'

jobs:
include:
- stage: 'Integration tests'
- &integrationtest
stage: 'Integration tests'
env:
- SDK=android
- BUILD_NUMBER=$TRAVIS_BUILD_NUMBER
Expand All @@ -68,5 +71,8 @@ jobs:
before_script:
- mkdir $HOME/travisci-tools && pushd $HOME/travisci-tools && git init && git pull https://$CI_USER_TOKEN@github.com/optimizely/travisci-tools.git && popd
script:
- "$HOME/travisci-tools/fsc-trigger/trigger_fullstack-sdk-compat.sh"
- $HOME/travisci-tools/trigger-script-with-status-update.sh
after_success: travis_terminate 0
- <<: *integrationtest
stage: 'Benchmarking tests'
env: SDK=android FULLSTACK_TEST_REPO=Benchmarking
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Optimizely Android X SDK Changelog

## 3.2.0
August 21st 2019

This minor release updates the SDK to use the Optimizely Java SDK 3.2.1 which includes the following:

### New Features:
* The default datafile manager now supports the Java SDK [#ProjectConfigManager](https://github.com/optimizely/java-sdk/blob/master/core-api/src/main/java/com/optimizely/ab/config/ProjectConfigManager.java)
* The default datafile manager with polling enabled will pickup new ProjectConfigs without needing to re-initialize.
* You can register for Datafile change notifications.

### Bug Fixes:
* Potential bug fix for ANRs where a service is started but there is a bad network connection. [#PR295](https://github.com/optimizely/android-sdk/pull/295)

### Deprecated
* DatafileHandler interface has been deprecated. In the future we will start using the ProjectConfigManager from the Java SDK mentioned above.


## 3.1.1
July 23rd, 2019

### Bug Fixes:
* SourceClear flagged jackson-databind 2.9.8 fixed in 2.9.9.1

## 3.1.0
May 13th, 2019

Expand Down
16 changes: 16 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This is a comment.
# Each line is a file pattern followed by one or more owners.

# These owners will be the default owners for everything in the repo.
# Unless a later match takes precedence, @global-owner1 and @global-owner2
# will be requested for review when someone opens a pull request.
* @optimizely/fullstack-devs

# Order is important; the last matching pattern takes the most precedence.
# When someone opens a pull request that only modifies JS files, only @js-owner
# and not the global owner(s) will be requested for a review.
#*.js @js-owner

# You can also use email addresses if you prefer. They'll be used to look up
# users just like we do for commit author emails.
#docs/* docs@example.com
2 changes: 1 addition & 1 deletion android-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ dependencies {
androidTestImplementation "com.google.dexmaker:dexmaker-mockito:$dexmaker_ver"
androidTestImplementation "com.noveogroup.android:android-logger:$android_logger_ver"
androidTestImplementation "com.google.code.gson:gson:$gson_ver"
androidTestImplementation "com.fasterxml.jackson.core:jackson-databind:2.9.8"
androidTestImplementation "com.fasterxml.jackson.core:jackson-databind:$jacksonversion"
}

//uploadArchives {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ public OptimizelyClientTest(int datafileVersion,String datafile){
eventHandler = spy(DefaultEventHandler.getInstance(InstrumentationRegistry.getTargetContext()));
optimizely = Optimizely.builder(datafile, eventHandler).build();
if(datafileVersion==3) {
when(bucketer.bucket(optimizely.getProjectConfig().getExperiments().get(0), GENERIC_USER_ID)).thenReturn(optimizely.getProjectConfig().getExperiments().get(0).getVariations().get(0));
when(bucketer.bucket(optimizely.getProjectConfig().getExperiments().get(0), GENERIC_USER_ID, optimizely.getProjectConfig())).thenReturn(optimizely.getProjectConfig().getExperiments().get(0).getVariations().get(0));
} else {
when(bucketer.bucket(optimizely.getProjectConfig().getExperimentKeyMapping().get(FEATURE_MULTI_VARIATE_EXPERIMENT_KEY), GENERIC_USER_ID)).thenReturn(optimizely.getProjectConfig().getExperimentKeyMapping().get(FEATURE_MULTI_VARIATE_EXPERIMENT_KEY).getVariations().get(1));
when(bucketer.bucket(optimizely.getProjectConfig().getExperimentKeyMapping().get(FEATURE_MULTI_VARIATE_EXPERIMENT_KEY), GENERIC_USER_ID, optimizely.getProjectConfig())).thenReturn(optimizely.getProjectConfig().getExperimentKeyMapping().get(FEATURE_MULTI_VARIATE_EXPERIMENT_KEY).getVariations().get(1));
}
spyOnConfig();
} catch (Exception configException) {
Expand Down Expand Up @@ -356,7 +356,7 @@ public void testGoodActivationBucketingId() {
Experiment experiment = optimizelyClient.getProjectConfig().getExperimentKeyMapping().get(FEATURE_ANDROID_EXPERIMENT_KEY);
attributes.put(BUCKETING_ATTRIBUTE, bucketingId);
Variation v = optimizelyClient.activate(FEATURE_ANDROID_EXPERIMENT_KEY, GENERIC_USER_ID, attributes);
verify(bucketer).bucket( experiment, bucketingId);
verify(bucketer).bucket(experiment, bucketingId, optimizely.getProjectConfig());
}

@Test
Expand Down Expand Up @@ -881,7 +881,7 @@ public void testGoodGetVariationBucketingId() {
Map<String, String> attributes = new HashMap<>();
attributes.put(BUCKETING_ATTRIBUTE, bucketingId);
Variation v = optimizelyClient.getVariation("android_experiment_key", "userId", attributes);
verify(bucketer).bucket(experiment, bucketingId);
verify(bucketer).bucket(experiment, bucketingId, optimizely.getProjectConfig());
}

@Test
Expand Down Expand Up @@ -1027,9 +1027,9 @@ public void testGoodGetProjectConfigForced() {
logger);
ProjectConfig config = optimizelyClient.getProjectConfig();
assertNotNull(config);
assertTrue(config.setForcedVariation(FEATURE_ANDROID_EXPERIMENT_KEY, GENERIC_USER_ID, "var_1"));
assertEquals(config.getForcedVariation(FEATURE_ANDROID_EXPERIMENT_KEY, GENERIC_USER_ID), config.getExperimentKeyMapping().get(FEATURE_ANDROID_EXPERIMENT_KEY).getVariations().get(0));
assertTrue(config.setForcedVariation(FEATURE_ANDROID_EXPERIMENT_KEY, GENERIC_USER_ID, null));
assertTrue(optimizelyClient.setForcedVariation(FEATURE_ANDROID_EXPERIMENT_KEY, GENERIC_USER_ID, "var_1"));
assertEquals(optimizelyClient.getForcedVariation(FEATURE_ANDROID_EXPERIMENT_KEY, GENERIC_USER_ID), config.getExperimentKeyMapping().get(FEATURE_ANDROID_EXPERIMENT_KEY).getVariations().get(0));
assertTrue(optimizelyClient.setForcedVariation(FEATURE_ANDROID_EXPERIMENT_KEY, GENERIC_USER_ID, null));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.optimizely.ab.OptimizelyRuntimeException;
import com.optimizely.ab.android.datafile_handler.DefaultDatafileHandler;
import com.optimizely.ab.android.event_handler.DefaultEventHandler;
import com.optimizely.ab.android.shared.DatafileConfig;
import com.optimizely.ab.android.user_profile.DefaultUserProfileService;
import com.optimizely.ab.config.Experiment;
import com.optimizely.ab.config.ProjectConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import com.optimizely.ab.android.shared.ServiceScheduler;
import com.optimizely.ab.android.user_profile.DefaultUserProfileService;
import com.optimizely.ab.bucketing.UserProfileService;
import com.optimizely.ab.config.DatafileProjectConfig;
import com.optimizely.ab.config.ProjectConfig;
import com.optimizely.ab.config.Variation;
import com.optimizely.ab.event.EventHandler;

Expand Down Expand Up @@ -74,6 +76,7 @@ public class OptimizelyManagerTest {
private ListeningExecutorService executor;
private Logger logger;
private OptimizelyManager optimizelyManager;
private DefaultDatafileHandler defaultDatafileHandler;

private String minDatafile = "{\n" +
"experiments: [ ],\n" +
Expand All @@ -88,19 +91,24 @@ public class OptimizelyManagerTest {
"}";

@Before
public void setup() {
public void setup() throws Exception {
logger = mock(Logger.class);
executor = MoreExecutors.newDirectExecutorService();
DatafileHandler datafileHandler = mock(DefaultDatafileHandler.class);
defaultDatafileHandler = mock(DefaultDatafileHandler.class);
EventHandler eventHandler = mock(DefaultEventHandler.class);
optimizelyManager = new OptimizelyManager(testProjectId, null, null, logger, 3600L, datafileHandler, null, 3600L,
optimizelyManager = new OptimizelyManager(testProjectId, null, null, logger, 3600L, defaultDatafileHandler, null, 3600L,
eventHandler, null);
String datafile = optimizelyManager.getDatafile(InstrumentationRegistry.getTargetContext(), R.raw.datafile);
ProjectConfig config = new DatafileProjectConfig.Builder().withDatafile(datafile).build();

when(defaultDatafileHandler.getConfig()).thenReturn(config);
}

@Test
public void initializeIntUseForcedVariation() {
optimizelyManager.initialize(InstrumentationRegistry.getTargetContext(), R.raw.datafile);


assertTrue(optimizelyManager.getOptimizely().setForcedVariation("android_experiment_key", "1", "var_1"));
Variation variation = optimizelyManager.getOptimizely().getForcedVariation("android_experiment_key", "1");
assertEquals(variation.getKey(), "var_1");
Expand All @@ -116,7 +124,7 @@ public void initializeInt() {

assertEquals(optimizelyManager.getDatafileUrl(), "https://cdn.optimizely.com/json/7595190003.json" );

verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(InstrumentationRegistry.getTargetContext()), eq(new DatafileConfig(testProjectId, null)), eq(3600L));
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(InstrumentationRegistry.getTargetContext()), eq(new DatafileConfig(testProjectId, null)), eq(3600L), any(DatafileLoadedListener.class));
assertNotNull(optimizelyManager.getOptimizely());
assertNotNull(optimizelyManager.getDatafileHandler());

Expand Down Expand Up @@ -169,6 +177,7 @@ public void initializeSyncWithEmptyDatafile() {
Context appContext = mock(Context.class);
when(context.getApplicationContext()).thenReturn(appContext);
when(appContext.getPackageName()).thenReturn("com.optly");
when(defaultDatafileHandler.getConfig()).thenReturn(null);
optimizelyManager.initialize(InstrumentationRegistry.getTargetContext(), R.raw.emptydatafile);
assertFalse(optimizelyManager.getOptimizely().isValid());
}
Expand Down Expand Up @@ -227,7 +236,7 @@ public void onStart(OptimizelyClient optimizely) {
};
optimizelyManager.initialize(InstrumentationRegistry.getContext(), R.raw.datafile, listener);

verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(any(Context.class), eq(new DatafileConfig(testProjectId, testSdkKey)), eq(3600L));
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(any(Context.class), eq(new DatafileConfig(testProjectId, testSdkKey)), eq(3600L), any(DatafileLoadedListener.class));


assertEquals(optimizelyManager.isDatafileCached(InstrumentationRegistry.getTargetContext()), false);
Expand Down Expand Up @@ -261,6 +270,7 @@ public void initializeWithEmptyDatafile() {
Context appContext = mock(Context.class);
when(context.getApplicationContext()).thenReturn(appContext);
when(appContext.getPackageName()).thenReturn("com.optly");
when(defaultDatafileHandler.getConfig()).thenReturn(null);

String emptyString = "";

Expand All @@ -274,6 +284,7 @@ public void initializeWithMalformedDatafile() {
Context appContext = mock(Context.class);
when(context.getApplicationContext()).thenReturn(appContext);
when(appContext.getPackageName()).thenReturn("com.optly");
when(defaultDatafileHandler.getConfig()).thenReturn(null);

String emptyString = "malformed data";

Expand Down Expand Up @@ -347,7 +358,7 @@ public void injectOptimizely() {

verify(logger).info("Sending Optimizely instance to listener");
verify(startListener).onStart(any(OptimizelyClient.class));
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(context), eq(new DatafileConfig(testProjectId, null)), eq(3600L));
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(context), eq(new DatafileConfig(testProjectId, null)), eq(3600L), any(DatafileLoadedListener.class));

}

Expand All @@ -366,7 +377,7 @@ public void injectOptimizelyWithDatafileLisener() {
fail("Timed out");
}

verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(context), eq(new DatafileConfig(testProjectId, null)), eq(3600L));
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(context), eq(new DatafileConfig(testProjectId, null)), eq(3600L), any(DatafileLoadedListener.class));
verify(logger).info("Sending Optimizely instance to listener");
verify(startListener).onStart(any(OptimizelyClient.class));
}
Expand Down Expand Up @@ -435,6 +446,7 @@ public void injectOptimizelyHandlesInvalidDatafile() {
ArgumentCaptor<DefaultUserProfileService.StartCallback> callbackArgumentCaptor =
ArgumentCaptor.forClass(DefaultUserProfileService.StartCallback.class);

when(defaultDatafileHandler.getConfig()).thenReturn(null);
optimizelyManager.setOptimizelyStartListener(null);
optimizelyManager.injectOptimizely(context, userProfileService, "{}");
try {
Expand Down
Loading

0 comments on commit 5a03ebf

Please sign in to comment.