Skip to content

Commit

Permalink
Merge branch 'release/3.1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
mscwilson committed May 25, 2022
2 parents 50e104b + 25ccb07 commit 3a93694
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 12 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 3.1.2 (2022-05-25)
--------------------------
Set log level without trackerDiagnostic (#441)
Attach LifecycleEntity before the first Background event (#512)
Attach different entity in demo global context (#514)

Version 3.1.1 (2022-03-09)
--------------------------
Enable updating collector endpoint while Emitter is running (#508)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.1
3.1.2
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ buildscript {

subprojects {
group = 'com.snowplowanalytics'
version = '3.1.1'
version = '3.1.2'
repositories {
google()
maven {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ systemProp.org.gradle.internal.http.socketTimeout=120000
SONATYPE_STAGING_PROFILE=comsnowplowanalytics
GROUP=com.snowplowanalytics
POM_ARTIFACT_ID=snowplow-android-tracker
VERSION_NAME=3.1.1
VERSION_NAME=3.1.2

POM_NAME=snowplow-android-tracker
POM_PACKAGING=aar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@
*/
public class Demo extends Activity implements LoggerDelegate {

// Example schema for global contexts
final String SCHEMA_IDENTIFY = "iglu:com.snowplowanalytics.snowplow/identify/jsonschema/1-0-0";

private Button _startButton, _tabButton;
private EditText _uriField;
private RadioGroup _type, _remoteConfig, _collection;
Expand Down Expand Up @@ -284,9 +287,9 @@ private boolean setupWithLocalConfig() {
);
GlobalContextsConfiguration gcConfiguration = new GlobalContextsConfiguration(null);
Map<String, Object> pairs = new HashMap<>();
addToMap(Parameters.APP_VERSION, "0.3.0", pairs);
addToMap(Parameters.APP_BUILD, "3", pairs);
gcConfiguration.add("ruleSetExampleTag", new GlobalContext(Collections.singletonList(new SelfDescribingJson(TrackerConstants.SCHEMA_APPLICATION, pairs))));
addToMap("id", "snowplow", pairs);
addToMap("email", "info@snowplowanalytics.com", pairs);
gcConfiguration.add("ruleSetExampleTag", new GlobalContext(Collections.singletonList(new SelfDescribingJson(SCHEMA_IDENTIFY, pairs))));

Snowplow.createTracker(getApplicationContext(),
namespace,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;

import com.snowplowanalytics.snowplow.event.Background;
import com.snowplowanalytics.snowplow.event.DeepLinkReceived;
import com.snowplowanalytics.snowplow.event.Event;
import com.snowplowanalytics.snowplow.event.Foreground;
import com.snowplowanalytics.snowplow.event.ScreenView;
import com.snowplowanalytics.snowplow.event.SelfDescribing;
import com.snowplowanalytics.snowplow.event.Timing;
Expand Down Expand Up @@ -171,6 +174,132 @@ public void testScreenStateMachine() throws InterruptedException {
assertEquals(1, entities.split("screen2", -1).length - 1);
}

@Test
public void testLifecycleStateMachine() throws InterruptedException {
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
MockEventStore eventStore = new MockEventStore();
Emitter emitter = new Emitter(context, "http://snowplow-fake-url.com", new Emitter.EmitterBuilder()
.eventStore(eventStore)
);
Tracker tracker = new Tracker(new Tracker.TrackerBuilder(emitter, "namespace", "appId", context)
.base64(false)
.level(LogLevel.VERBOSE)
.lifecycleEvents(true)
);

// Send events
tracker.track(new Timing("category", "variable", 123));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
Payload payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
String entities = (String) payload.getMap().get("co");
assertNotNull(entities);
assertTrue(entities.contains("\"isVisible\":true"));
assertEquals(1, entities.split("isVisible", -1).length - 1);

tracker.track(new Background());
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNotNull(entities);
assertTrue(entities.contains("\"isVisible\":false"));
assertEquals(1, entities.split("isVisible", -1).length - 1);

tracker.track(new ScreenView("screen1"));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNotNull(entities);
System.out.println(entities);
assertTrue(entities.contains("\"isVisible\":false"));
assertEquals(1, entities.split("isVisible", -1).length - 1);

tracker.track(new Foreground().foregroundIndex(9));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNotNull(entities);
System.out.println(entities);
assertTrue(entities.contains("\"isVisible\":true"));
assertTrue(entities.contains("\"index\":9"));
assertEquals(1, entities.split("isVisible", -1).length - 1);

tracker.track(new ScreenView("screen1"));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNotNull(entities);
System.out.println(entities);
assertTrue(entities.contains("\"isVisible\":true"));
assertTrue(entities.contains("\"index\":9"));
assertEquals(1, entities.split("isVisible", -1).length - 1);
}

@Test
public void testDeepLinkStateMachine() throws InterruptedException {
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
MockEventStore eventStore = new MockEventStore();
Emitter emitter = new Emitter(context, "http://snowplow-fake-url.com", new Emitter.EmitterBuilder()
.eventStore(eventStore)
);
Tracker tracker = new Tracker(new Tracker.TrackerBuilder(emitter, "namespace", "appId", context)
.base64(false)
.deepLinkContext(true)
);

// Send events
tracker.track(new Timing("category", "variable", 123));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
Payload payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
String entities = (String) payload.getMap().get("co");
assertNull(entities);

tracker.track(new DeepLinkReceived("http://www.homepage.com"));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNull(entities);

tracker.track(new ScreenView("screen1"));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNotNull(entities);
assertTrue(entities.contains("www.homepage.com"));
assertEquals(1, entities.split("url", -1).length - 1);

tracker.track(new Timing("category", "variable", 123));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNull(entities);

tracker.track(new ScreenView("screen2"));
Thread.sleep(1000);
if (eventStore.lastInsertedRow == -1) fail();
payload = eventStore.db.get(eventStore.lastInsertedRow);
eventStore.removeAllEvents();
entities = (String) payload.getMap().get("co");
assertNull(entities);
}

@Test
public void testAllowsMultipleStateMachines() throws InterruptedException {
StateManager stateManager = new StateManager();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2015-2022 Snowplow Analytics Ltd. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/

package com.snowplowanalytics.snowplow.tracker;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.snowplowanalytics.snowplow.Snowplow;
import com.snowplowanalytics.snowplow.configuration.NetworkConfiguration;
import com.snowplowanalytics.snowplow.configuration.TrackerConfiguration;
import com.snowplowanalytics.snowplow.emitter.BufferOption;
import com.snowplowanalytics.snowplow.internal.emitter.Emitter;
import com.snowplowanalytics.snowplow.internal.tracker.Tracker;
import com.snowplowanalytics.snowplow.network.HttpMethod;


import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class LoggingTest {

static class MockLoggerDelegate implements LoggerDelegate {
String capturedLogs = "";

@Override
public void error(@NonNull String tag, @NonNull String msg) {
capturedLogs += tag + " " + msg + " (error)\n";
}

@Override
public void debug(@NonNull String tag, @NonNull String msg) {
capturedLogs += tag + " " + msg + " (debug)\n";
}

@Override
public void verbose(@NonNull String tag, @NonNull String msg) {
capturedLogs += tag + " " + msg + " (verbose)\n";
}
}

MockLoggerDelegate mockLoggerDelegate;
Emitter emitter;
Tracker tracker;
NetworkConfiguration networkConfig;

@Before
public void setUp() throws Exception {
mockLoggerDelegate = new MockLoggerDelegate();
emitter = new Emitter(ApplicationProvider.getApplicationContext(), "http://localhost", new Emitter.EmitterBuilder()
.option(BufferOption.Single)
);
networkConfig = new NetworkConfiguration("http://localhost", HttpMethod.POST);
}

// Tests

// The Emitter logs at error level during failed attempts to send, but it's difficult to delay JUnit long enough to reach that point
// Therefore these tests look at verbose and debug logging only

@Test
public void VerboseLogsShownWhenVerboseSet() {
tracker = new Tracker(new Tracker.TrackerBuilder(emitter, "namespace", "myAppId", ApplicationProvider.getApplicationContext())
.sessionContext(true)
.level(LogLevel.VERBOSE)
.loggerDelegate(mockLoggerDelegate)
);

assertTrue(mockLoggerDelegate.capturedLogs.contains("Session checking has been resumed. (debug)"));
assertTrue(mockLoggerDelegate.capturedLogs.contains("Tracker created successfully. (verbose)"));
}

@Test
public void VerboseLogsWithTrackerConfig() {
TrackerConfiguration trackerConfig = new TrackerConfiguration("appId")
.logLevel(LogLevel.VERBOSE)
.loggerDelegate(mockLoggerDelegate)
.sessionContext(true);

Snowplow.createTracker(ApplicationProvider.getApplicationContext(),
"appTracker",
networkConfig,
trackerConfig);

assertTrue(mockLoggerDelegate.capturedLogs.contains("Session checking has been resumed. (debug)"));
assertTrue(mockLoggerDelegate.capturedLogs.contains("Tracker created successfully. (verbose)"));
}

@Test
public void DebugLogsShownWhenDebugSet() {
tracker = new Tracker(new Tracker.TrackerBuilder(emitter, "namespace", "myAppId", ApplicationProvider.getApplicationContext())
.sessionContext(true)
.level(LogLevel.DEBUG)
.loggerDelegate(mockLoggerDelegate)
);

assertTrue(mockLoggerDelegate.capturedLogs.contains("Session checking has been resumed. (debug)"));
assertFalse(mockLoggerDelegate.capturedLogs.contains("Tracker created successfully. (verbose)"));
}

@Test
public void DebugLogsWithTrackerConfig() {
TrackerConfiguration trackerConfig = new TrackerConfiguration("appId")
.logLevel(LogLevel.DEBUG)
.loggerDelegate(mockLoggerDelegate)
.sessionContext(true);

Snowplow.createTracker(ApplicationProvider.getApplicationContext(),
"appTracker",
networkConfig,
trackerConfig);

assertTrue(mockLoggerDelegate.capturedLogs.contains("Session checking has been resumed. (debug)"));
assertFalse(mockLoggerDelegate.capturedLogs.contains("Tracker created successfully. (verbose)"));
}

@Test
public void LoggingOffByDefault() {
tracker = new Tracker(new Tracker.TrackerBuilder(emitter, "namespace", "myAppId", ApplicationProvider.getApplicationContext())
.sessionContext(true)
.loggerDelegate(mockLoggerDelegate)
);

assertFalse(mockLoggerDelegate.capturedLogs.contains("Session checking has been resumed. (debug)"));
assertFalse(mockLoggerDelegate.capturedLogs.contains("Tracker created successfully. (verbose)"));
}

@Test
public void LoggingOffByDefaultWithConfig() {
TrackerConfiguration trackerConfig = new TrackerConfiguration("appId")
.loggerDelegate(mockLoggerDelegate)
.sessionContext(true);

Snowplow.createTracker(ApplicationProvider.getApplicationContext(),
"appTracker",
networkConfig,
trackerConfig);

assertFalse(mockLoggerDelegate.capturedLogs.contains("Session checking has been resumed. (debug)"));
assertFalse(mockLoggerDelegate.capturedLogs.contains("Tracker created successfully. (verbose)"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@

public class LifecycleStateMachine implements StateMachineInterface {

/*
States: Visible, NotVisible
Events: FG (Foreground), BG (Background)
Transitions:
- Visible (BG) NotVisible
- NotVisible (FG) Visible
Entity Generation:
- Visible, NotVisible
*/

@NonNull
@Override
public List<String> subscribedEventSchemasForTransitions() {
Expand Down Expand Up @@ -52,7 +62,8 @@ public State transition(@NonNull Event event, @Nullable State currentState) {
@Nullable
@Override
public List<SelfDescribingJson> entities(@NonNull InspectableEvent event, @Nullable State state) {
if (state == null) return null;
if (state == null) return Collections.singletonList(new LifecycleEntity(true));

LifecycleState s = (LifecycleState) state;
return Collections.singletonList(new LifecycleEntity(s.isForeground).index(s.index));
}
Expand Down
Loading

0 comments on commit 3a93694

Please sign in to comment.