Skip to content

Commit

Permalink
Log an error when recreating tracker after being removed (close #548)
Browse files Browse the repository at this point in the history
PR #552
  • Loading branch information
matus-tomlein committed Oct 31, 2022
1 parent f16c612 commit 2ed0c5e
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 57 deletions.
Expand Up @@ -15,20 +15,34 @@

import static com.snowplowanalytics.snowplow.network.HttpMethod.POST;

import android.test.AndroidTestCase;
import androidx.annotation.NonNull;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;

import com.snowplowanalytics.snowplow.configuration.Configuration;
import com.snowplowanalytics.snowplow.configuration.NetworkConfiguration;
import com.snowplowanalytics.snowplow.configuration.TrackerConfiguration;
import com.snowplowanalytics.snowplow.controller.TrackerController;
import com.snowplowanalytics.snowplow.event.Structured;
import com.snowplowanalytics.snowplow.internal.emitter.EmitterConfigurationUpdate;
import com.snowplowanalytics.snowplow.internal.tracker.ServiceProvider;

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

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

import android.content.Context;

import java.util.ArrayList;
import java.util.List;

public class ServiceProviderTest extends AndroidTestCase {
@RunWith(AndroidJUnit4.class)
public class ServiceProviderTest {

@Test
public void testUpdatingConfigurationRetainsPausedEmitter() throws InterruptedException {
NetworkConfiguration networkConfig = new NetworkConfiguration("com.acme", POST);
TrackerConfiguration trackerConfig = new TrackerConfiguration("appId");
Expand All @@ -43,25 +57,62 @@ public void testUpdatingConfigurationRetainsPausedEmitter() throws InterruptedEx
ServiceProvider provider = new ServiceProvider(getContext(), "ns", networkConfig, configurations);

// pause emitter
provider.getEmitterController().pause();
provider.getOrMakeEmitterController().pause();

// refresh configuration
List<Configuration> configurationUpdates = new ArrayList<Configuration>();
configurationUpdates.add(new EmitterConfigurationUpdate());
provider.reset(configurationUpdates);

// track event and check that emitter is paused
provider.getTrackerController().track(new Structured("cat", "act"));
provider.getOrMakeTrackerController().track(new Structured("cat", "act"));
Thread.sleep(1000);
assertFalse(provider.getEmitter().getEmitterStatus());
assertFalse(provider.getOrMakeEmitter().getEmitterStatus());
assertEquals(0, networkConnection.sendingCount());

// resume emitting
provider.getEmitterController().resume();
provider.getOrMakeEmitterController().resume();
for (int i = 0; i < 10 && networkConnection.sendingCount() < 1; i++) {
Thread.sleep(600);
}
assertEquals(1, networkConnection.sendingCount());
provider.getEmitter().flush();
provider.getOrMakeEmitter().flush();
}

@Test
public void testLogsErrorWhenAccessingShutDownTracker() {
NetworkConfiguration networkConfig = new NetworkConfiguration("com.acme", POST);
MockNetworkConnection networkConnection = new MockNetworkConnection(POST, 200);
networkConfig.networkConnection = networkConnection;
ServiceProvider provider = new ServiceProvider(getContext(), "ns", networkConfig, new ArrayList<>());

// listen for the error log
TrackerController tracker = provider.getOrMakeTrackerController();
final boolean[] loggedError = {false};
tracker.setLoggerDelegate(new LoggerDelegate() {
@Override
public void error(@NonNull String tag, @NonNull String msg) {
if (msg.contains("Recreating tracker instance")) {
loggedError[0] = true;
}
}

@Override
public void debug(@NonNull String tag, @NonNull String msg) {
}

@Override
public void verbose(@NonNull String tag, @NonNull String msg) {
}
});

// shutting down and accessing the tracker should log the error
provider.shutdown();
tracker.getNamespace();
assertTrue(loggedError[0]);
}

private Context getContext() {
return InstrumentationRegistry.getInstrumentation().getTargetContext();
}
}
Expand Up @@ -28,7 +28,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;

/**
* Entry point to instance a new Snowplow tracker.
Expand Down Expand Up @@ -193,7 +192,7 @@ public static TrackerController createTracker(@NonNull Context context, @NonNull
serviceProvider = new ServiceProvider(context, namespace, network, Arrays.asList(configurations));
registerInstance(serviceProvider);
}
return serviceProvider.getTrackerController();
return serviceProvider.getOrMakeTrackerController();
}

/**
Expand All @@ -205,7 +204,7 @@ public static TrackerController createTracker(@NonNull Context context, @NonNull
@Nullable
public static TrackerController getDefaultTracker() {
ServiceProvider serviceProvider = defaultServiceProvider;
return serviceProvider == null ? null : serviceProvider.getTrackerController();
return serviceProvider == null ? null : serviceProvider.getOrMakeTrackerController();
}

/**
Expand All @@ -220,7 +219,7 @@ public synchronized static TrackerController getTracker(@NonNull String namespac
if (serviceProvider == null) {
return null;
}
return serviceProvider.getTrackerController();
return serviceProvider.getOrMakeTrackerController();
}

/**
Expand Down
Expand Up @@ -23,7 +23,7 @@ public EmitterControllerImpl(@NonNull ServiceProviderInterface serviceProvider)
}

private Emitter getEmitter() {
return serviceProvider.getTracker().getEmitter();
return serviceProvider.getOrMakeTracker().getEmitter();
}

// Getters and Setters
Expand Down
Expand Up @@ -10,7 +10,6 @@
import com.snowplowanalytics.snowplow.network.HttpMethod;
import com.snowplowanalytics.snowplow.network.NetworkConnection;
import com.snowplowanalytics.snowplow.network.OkHttpNetworkConnection;
import com.snowplowanalytics.snowplow.network.Protocol;

@RestrictTo(RestrictTo.Scope.LIBRARY)
public class NetworkControllerImpl extends Controller implements NetworkController {
Expand Down Expand Up @@ -76,7 +75,7 @@ public int getTimeout() {
// Private methods

private Emitter getEmitter() {
return serviceProvider.getEmitter();
return serviceProvider.getOrMakeEmitter();
}

private NetworkConfigurationUpdate getDirtyConfig() {
Expand Down
Expand Up @@ -98,7 +98,7 @@ public String getDocumentDescription() {

@NonNull
private Tracker getTracker() {
return serviceProvider.getTracker();
return serviceProvider.getOrMakeTracker();
}

@NonNull
Expand Down
Expand Up @@ -10,8 +10,6 @@
import com.snowplowanalytics.snowplow.internal.tracker.ServiceProviderInterface;
import com.snowplowanalytics.snowplow.internal.tracker.Tracker;

import java.util.List;
import java.util.Map;
import java.util.Set;

@RestrictTo(RestrictTo.Scope.LIBRARY)
Expand Down Expand Up @@ -41,6 +39,6 @@ public GlobalContext remove(@NonNull String tag) {
// Private methods

private Tracker getTracker() {
return serviceProvider.getTracker();
return serviceProvider.getOrMakeTracker();
}
}
Expand Up @@ -196,12 +196,12 @@ public boolean isEnabled() {

@NonNull
private Tracker getTracker() {
return serviceProvider.getTracker();
return serviceProvider.getOrMakeTracker();
}

@Nullable
private Session getSession() {
return serviceProvider.getTracker().getSession();
return serviceProvider.getOrMakeTracker().getSession();
}

@NonNull
Expand Down
Expand Up @@ -23,7 +23,6 @@
import com.snowplowanalytics.snowplow.internal.emitter.NetworkConfigurationUpdate;
import com.snowplowanalytics.snowplow.internal.emitter.NetworkControllerImpl;
import com.snowplowanalytics.snowplow.internal.gdpr.Gdpr;
import com.snowplowanalytics.snowplow.internal.gdpr.GdprConfigurationInterface;
import com.snowplowanalytics.snowplow.internal.gdpr.GdprConfigurationUpdate;
import com.snowplowanalytics.snowplow.internal.gdpr.GdprControllerImpl;
import com.snowplowanalytics.snowplow.internal.globalcontexts.GlobalContextsControllerImpl;
Expand Down Expand Up @@ -125,15 +124,15 @@ public ServiceProvider(@NonNull Context context, @NonNull String namespace, @Non
if (trackerConfigurationUpdate.sourceConfig == null) {
trackerConfigurationUpdate.sourceConfig = new TrackerConfiguration(appId);
}
getTracker(); // Build tracker to initialize NotificationCenter receivers
getOrMakeTracker(); // Build tracker to initialize NotificationCenter receivers
}

public void reset(@NonNull List<Configuration> configurations) {
stopServices();
resetConfigurationUpdates();
processConfigurations(configurations);
resetServices();
getTracker();
getOrMakeTracker();
}

public void shutdown() {
Expand Down Expand Up @@ -233,79 +232,95 @@ private void initializeConfigurationUpdates() {
// Getters

@NonNull
public Subject getSubject() {
@Override
public Subject getOrMakeSubject() {
if (subject == null) {
subject = makeSubject();
}
return subject;
}

@NonNull
public Emitter getEmitter() {
@Override
public Emitter getOrMakeEmitter() {
if (emitter == null) {
emitter = makeEmitter();
}
return emitter;
}

@NonNull
public Tracker getTracker() {
@Override
public Boolean isTrackerInitialized() {
return tracker != null;
}

@NonNull
@Override
public Tracker getOrMakeTracker() {
if (tracker == null) {
tracker = makeTracker();
}
return tracker;
}

@NonNull
public TrackerControllerImpl getTrackerController() {
@Override
public TrackerControllerImpl getOrMakeTrackerController() {
if (trackerController == null) {
trackerController = makeTrackerController();
}
return trackerController;
}

@NonNull
public SessionControllerImpl getSessionController() {
@Override
public SessionControllerImpl getOrMakeSessionController() {
if (sessionController == null) {
sessionController = makeSessionController();
}
return sessionController;
}

@NonNull
public EmitterControllerImpl getEmitterController() {
@Override
public EmitterControllerImpl getOrMakeEmitterController() {
if (emitterController == null) {
emitterController = makeEmitterController();
}
return emitterController;
}

@NonNull
public GdprControllerImpl getGdprController() {
@Override
public GdprControllerImpl getOrMakeGdprController() {
if (gdprController == null) {
gdprController = makeGdprController();
}
return gdprController;
}

@NonNull
public GlobalContextsControllerImpl getGlobalContextsController() {
@Override
public GlobalContextsControllerImpl getOrMakeGlobalContextsController() {
if (globalContextsController == null) {
globalContextsController = makeGlobalContextsController();
}
return globalContextsController;
}

@NonNull
public SubjectControllerImpl getSubjectController() {
@Override
public SubjectControllerImpl getOrMakeSubjectController() {
if (subjectController == null) {
subjectController = makeSubjectController();
}
return subjectController;
}

@NonNull
public NetworkControllerImpl getNetworkController() {
@Override
public NetworkControllerImpl getOrMakeNetworkController() {
if (networkController == null) {
networkController = makeNetworkController();
}
Expand All @@ -330,14 +345,14 @@ public SubjectConfigurationUpdate getSubjectConfigurationUpdate() {
return subjectConfigurationUpdate;
}

@Override
@NonNull
@Override
public EmitterConfigurationUpdate getEmitterConfigurationUpdate() {
return emitterConfigurationUpdate;
}

@Override
@NonNull
@Override
public SessionConfigurationUpdate getSessionConfigurationUpdate() {
return sessionConfigurationUpdate;
}
Expand Down Expand Up @@ -394,8 +409,8 @@ private Emitter makeEmitter() {

@NonNull
private Tracker makeTracker() {
Emitter emitter = getEmitter();
Subject subject = getSubject();
Emitter emitter = getOrMakeEmitter();
Subject subject = getOrMakeSubject();
TrackerConfigurationInterface trackerConfig = getTrackerConfigurationUpdate();
SessionConfigurationInterface sessionConfig = getSessionConfigurationUpdate();
Tracker.TrackerBuilder builder = new Tracker.TrackerBuilder(emitter, namespace, trackerConfig.getAppId(), context)
Expand Down Expand Up @@ -464,7 +479,7 @@ private EmitterControllerImpl makeEmitterController() {
@NonNull
private GdprControllerImpl makeGdprController() {
GdprControllerImpl controller = new GdprControllerImpl(this);
Gdpr gdpr = getTracker().getGdprContext();
Gdpr gdpr = getOrMakeTracker().getGdprContext();
if (gdpr != null) {
controller.reset(gdpr.basisForProcessing, gdpr.documentId, gdpr.documentVersion, gdpr.documentDescription);
}
Expand Down

0 comments on commit 2ed0c5e

Please sign in to comment.