Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'trackAutomaticEvents' as a required param in getInstance' and remove Mixpanel server api call for Autotrack setting #794

Merged
merged 4 commits into from
Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions acceptance/README.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
1. install selenium webdriver lib by "pip install selenium"
2. change mDecideEndpoint and mEditorUrl to your IP address with port 8000.
eg. my IP is 172.16.20.43, so add
<meta-data android:name="com.mixpanel.android.MPConfig.DecideEndpoint" android:value="http://172.16.20.43:8000" />
<meta-data android:name="com.mixpanel.android.MPConfig.EditorUrl" android:value="http://172.16.20.43:8000" />
to AndroidManifest.xml of mixpanel-android.
3. change the android library location to your local library location in the build.gradle of the test app
4. launch emulator or hook up your Android device (make sure there's only 1 device/emulator connected to your
2. change the android library location to your local library location in the build.gradle of the test app
3. launch emulator or hook up your Android device (make sure there's only 1 device/emulator connected to your
machine
5. now run "run.sh"
4. now run "run.sh"
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION_NAME=6.5.3-SNAPSHOT
VERSION_NAME=7.0.0-SNAPSHOT

POM_PACKAGING=aar
GROUP=com.mixpanel.android
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,23 @@ public class AutomaticEventsTest {
private static final int MAX_TIMEOUT_POLL = 6500;
final private BlockingQueue<String> mPerformRequestEvents = new LinkedBlockingQueue<>();
private Future<SharedPreferences> mMockReferrerPreferences;
private byte[] mDecideResponse;
private int mTrackedEvents;
private CountDownLatch mLatch = new CountDownLatch(1);
private boolean mCanRunDecide;
private boolean mCanRunSecondDecideInstance;
private MPDbAdapter mockAdapter;
private CountDownLatch mMinRequestsLatch;

@Before
public void setUp() {
mMockReferrerPreferences = new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext());
mTrackedEvents = 0;
mCanRunDecide = true;
mMinRequestsLatch = new CountDownLatch(2); // First Time Open and Update
}

private void setUpInstance(boolean trackAutomaticEvents) {
final RemoteService mockPoster = new HttpService() {
@Override
public byte[] performRequest(String endpointUrl, Map<String, Object> params, SSLSocketFactory socketFactory) {

if (null == params) {
if (mDecideResponse == null) {
return TestUtils.bytes("{\"automatic_events\": true}");
}
return mDecideResponse;
}

final String jsonData = Base64Coder.decodeString(params.get("data").toString());
assertTrue(params.containsKey("data"));
try {
Expand All @@ -90,21 +82,20 @@ public byte[] performRequest(String endpointUrl, Map<String, Object> params, SSL
};

InstrumentationRegistry.getInstrumentation().getContext().deleteDatabase("mixpanel");

mockAdapter = new MPDbAdapter(InstrumentationRegistry.getInstrumentation().getContext()) {
@Override
public void cleanupEvents(String last_id, Table table, String token, boolean includeAutomaticEvents) {
public void cleanupEvents(String last_id, Table table, String token) {
if (token.equalsIgnoreCase(TOKEN)) {
super.cleanupEvents(last_id, table, token, includeAutomaticEvents);
super.cleanupEvents(last_id, table, token);
}
}

@Override
public int addJSON(JSONObject j, String token, Table table, boolean isAutomaticRecord) {
public int addJSON(JSONObject j, String token, Table table) {
if (token.equalsIgnoreCase(TOKEN)) {
mTrackedEvents++;
mLatch.countDown();
return super.addJSON(j, token, table, isAutomaticRecord);
return super.addJSON(j, token, table);
}

return 1;
Expand All @@ -131,25 +122,14 @@ protected Handler restartWorkerThread() {
final HandlerThread thread = new HandlerThread("com.mixpanel.android.AnalyticsWorker", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
final Handler ret = new AnalyticsMessageHandler(thread.getLooper()) {
@Override
protected DecideChecker createDecideChecker() {
return new DecideChecker(mContext, mConfig) {
@Override
public void runDecideCheck(String token, RemoteService poster) throws RemoteService.ServiceUnavailableException {
if (mCanRunDecide) {
super.runDecideCheck(token, poster);
}
}
};
}
};
return ret;
}
};
}
};

mCleanMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, false, null) {
mCleanMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, false, null, trackAutomaticEvents) {

@Override
/* package */ PersistentIdentity getPersistentIdentity(final Context context, final Future<SharedPreferences> referrerPreferences, final String token, final String instanceName) {
Expand Down Expand Up @@ -185,6 +165,7 @@ public void tearDown() throws Exception {
public void testAutomaticOneInstance() throws InterruptedException {
int calls = 3; // First Time Open, App Update, An Event One
mLatch = new CountDownLatch(calls);
setUpInstance(true);
mCleanMixpanelAPI.track("An event One");
mCleanMixpanelAPI.flush();
assertTrue(mLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
Expand All @@ -197,25 +178,21 @@ public void testAutomaticOneInstance() throws InterruptedException {

@Test
public void testDisableAutomaticEvents() throws InterruptedException {
mCanRunDecide = false;

mDecideResponse = TestUtils.bytes("{\"automatic_events\": false}");

int calls = 3; // First Time Open, App Update, An Event Three
int calls = 1;
setUpInstance(false);
mLatch = new CountDownLatch(calls);
mCleanMixpanelAPI.track("An Event Three");
assertTrue(mLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
assertEquals(calls, mTrackedEvents);

mCanRunDecide = true;
mCleanMixpanelAPI.track("Automatic Event Two", null, true); // dropped
mCleanMixpanelAPI.track("Automatic Event Three", null, true); // dropped
mCleanMixpanelAPI.track("Automatic Event Four", null, true); // dropped
mCleanMixpanelAPI.flush();
assertEquals("An Event Three", mPerformRequestEvents.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
assertEquals(null, mPerformRequestEvents.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));

String[] noEvents = mockAdapter.generateDataString(MPDbAdapter.Table.EVENTS, TOKEN, true);
String[] noEvents = mockAdapter.generateDataString(MPDbAdapter.Table.EVENTS, TOKEN);
assertNull(noEvents);

mCleanMixpanelAPI.flush();
Expand All @@ -225,20 +202,16 @@ public void testDisableAutomaticEvents() throws InterruptedException {
@Test
public void testAutomaticMultipleInstances() throws InterruptedException {
final String SECOND_TOKEN = "Automatic Events Token Two";
mCanRunDecide = true;
mDecideResponse = TestUtils.bytes("{\"automatic_events\": true}");
int initialCalls = 2;
setUpInstance(true);
mLatch = new CountDownLatch(initialCalls);

final CountDownLatch secondLatch = new CountDownLatch(initialCalls);
final BlockingQueue<String> secondPerformedRequests = new LinkedBlockingQueue<>();

final HttpService mpSecondPoster = new HttpService() {
@Override
public byte[] performRequest(String endpointUrl, Map<String, Object> params, SSLSocketFactory socketFactory) {
if (null == params) {
return TestUtils.bytes("{\"automatic_events\": false}");
}

final String jsonData = Base64Coder.decodeString(params.get("data").toString());
assertTrue(params.containsKey("data"));
try {
Expand All @@ -257,17 +230,17 @@ public byte[] performRequest(String endpointUrl, Map<String, Object> params, SSL

final MPDbAdapter mpSecondDbAdapter = new MPDbAdapter(InstrumentationRegistry.getInstrumentation().getContext()) {
@Override
public void cleanupEvents(String last_id, Table table, String token, boolean includeAutomaticEvents) {
public void cleanupEvents(String last_id, Table table, String token) {
if (token.equalsIgnoreCase(SECOND_TOKEN)) {
super.cleanupEvents(last_id, table, token, includeAutomaticEvents);
super.cleanupEvents(last_id, table, token);
}
}

@Override
public int addJSON(JSONObject j, String token, Table table, boolean isAutomaticRecord) {
public int addJSON(JSONObject j, String token, Table table) {
if (token.equalsIgnoreCase(SECOND_TOKEN)) {
secondLatch.countDown();
return super.addJSON(j, token, table, isAutomaticRecord);
return super.addJSON(j, token, table);
}

return 1;
Expand All @@ -293,40 +266,28 @@ protected Handler restartWorkerThread() {
final HandlerThread thread = new HandlerThread("com.mixpanel.android.AnalyticsWorker", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
final Handler ret = new AnalyticsMessageHandler(thread.getLooper()) {
@Override
protected DecideChecker createDecideChecker() {
return new DecideChecker(mContext, mConfig) {
@Override
public void runDecideCheck(String token, RemoteService poster) throws RemoteService.ServiceUnavailableException {
if (mCanRunSecondDecideInstance) {
super.runDecideCheck(token, poster);
}
}
};
}
};
return ret;
}
};
}
};

MixpanelAPI mpSecondInstance = new TestUtils.CleanMixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), SECOND_TOKEN) {
MixpanelAPI mpSecondInstance = new TestUtils.CleanMixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), SECOND_TOKEN, false) {
@Override
AnalyticsMessages getAnalyticsMessages() {
return mpSecondAnalyticsMessages;
}
};

assertTrue(mLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
assertEquals(initialCalls, mTrackedEvents);

assertTrue(secondLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
mLatch = new CountDownLatch(MPConfig.getInstance(InstrumentationRegistry.getInstrumentation().getContext()).getBulkUploadLimit() - initialCalls);
for (int i = 0; i < MPConfig.getInstance(InstrumentationRegistry.getInstrumentation().getContext()).getBulkUploadLimit() - initialCalls; i++) {
mCleanMixpanelAPI.track("Track event " + i);
}

assertTrue(mLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
mCleanMixpanelAPI.flush();

assertEquals(AutomaticEvents.FIRST_OPEN, mPerformRequestEvents.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
assertEquals(AutomaticEvents.APP_UPDATED, mPerformRequestEvents.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));
Expand All @@ -335,10 +296,8 @@ AnalyticsMessages getAnalyticsMessages() {
}

assertNull(mPerformRequestEvents.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));

assertNull(secondPerformedRequests.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS));

mCanRunSecondDecideInstance = true;
mpSecondInstance.flush();
mCleanMixpanelAPI.track("First Instance Event One");
mpSecondInstance.track("Second Instance Event One");
Expand Down
31 changes: 4 additions & 27 deletions src/androidTest/java/com/mixpanel/android/mpmetrics/HttpTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
@RunWith(AndroidJUnit4.class)
public class HttpTest {
private Future<SharedPreferences> mMockPreferences;
private List<Object> mFlushResults, mDecideResults;
private BlockingQueue<String> mPerformRequestCalls, mDecideCalls;
private List<Object> mFlushResults;
private BlockingQueue<String> mPerformRequestCalls;
private List<String> mCleanupCalls;
private MixpanelAPI mMetrics;
private volatile int mFlushInterval;
Expand All @@ -56,33 +56,14 @@ public void setUp() {
mMockPreferences = new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext());
mFlushResults = new ArrayList<Object>();
mPerformRequestCalls = new LinkedBlockingQueue<String>();
mDecideCalls = new LinkedBlockingQueue<String>();
mCleanupCalls = new ArrayList<String>();
mDecideResults = new ArrayList<Object>();
mForceOverMemThreshold = false;

final RemoteService mockPoster = new HttpService() {
@Override
public byte[] performRequest(String endpointUrl, Map<String, Object> params, SSLSocketFactory socketFactory)
throws ServiceUnavailableException, IOException {
try {
if (null == params) {
mDecideCalls.put(endpointUrl);

if (mDecideResults.isEmpty()) {
return TestUtils.bytes("{}");
}

final Object obj = mDecideResults.remove(0);
if (obj instanceof IOException) {
throw (IOException)obj;
} else if (obj instanceof MalformedURLException) {
throw (MalformedURLException)obj;
} else if (obj instanceof ServiceUnavailableException) {
throw (ServiceUnavailableException)obj;
}
return (byte[])obj;
}
if (mFlushResults.isEmpty()) {
mFlushResults.add(TestUtils.bytes("1\n"));
}
Expand Down Expand Up @@ -114,10 +95,6 @@ public byte[] performRequest(String endpointUrl, Map<String, Object> params, SSL
};

final MPConfig config = new MPConfig(new Bundle(), InstrumentationRegistry.getInstrumentation().getContext()) {
@Override
public String getDecideEndpoint() {
return "DECIDE ENDPOINT";
}

@Override
public String getEventsEndpoint() {
Expand All @@ -132,9 +109,9 @@ public int getFlushInterval() {

final MPDbAdapter mockAdapter = new MPDbAdapter(InstrumentationRegistry.getInstrumentation().getContext()) {
@Override
public void cleanupEvents(String last_id, Table table, String token, boolean includeAutomaticEvents) {
public void cleanupEvents(String last_id, Table table, String token) {
mCleanupCalls.add("called");
super.cleanupEvents(last_id, table, token, includeAutomaticEvents);
super.cleanupEvents(last_id, table, token);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@ public void testSetUseIpAddressForGeolocation() {
assertEquals("https://api.mixpanel.com/track/?ip=0", config.getEventsEndpoint());
assertEquals("https://api.mixpanel.com/engage/?ip=0", config.getPeopleEndpoint());
assertEquals("https://api.mixpanel.com/groups/?ip=0", config.getGroupsEndpoint());
assertEquals("https://api.mixpanel.com/decide", config.getDecideEndpoint());

mixpanelAPI.setUseIpAddressForGeolocation(true);
assertEquals("https://api.mixpanel.com/track/?ip=1", config.getEventsEndpoint());
assertEquals("https://api.mixpanel.com/engage/?ip=1", config.getPeopleEndpoint());
assertEquals("https://api.mixpanel.com/groups/?ip=1", config.getGroupsEndpoint());
assertEquals("https://api.mixpanel.com/decide", config.getDecideEndpoint());
}

@Test
Expand Down Expand Up @@ -92,13 +90,11 @@ public void testSetServerURL() throws Exception {
assertEquals("https://api.mixpanel.com/track/?ip=1", config.getEventsEndpoint());
assertEquals("https://api.mixpanel.com/engage/?ip=1", config.getPeopleEndpoint());
assertEquals("https://api.mixpanel.com/groups/?ip=1", config.getGroupsEndpoint());
assertEquals("https://api.mixpanel.com/decide", config.getDecideEndpoint());

mixpanelAPI.setServerURL("https://api-eu.mixpanel.com");
assertEquals("https://api-eu.mixpanel.com/track/?ip=1", config.getEventsEndpoint());
assertEquals("https://api-eu.mixpanel.com/engage/?ip=1", config.getPeopleEndpoint());
assertEquals("https://api-eu.mixpanel.com/groups/?ip=1", config.getGroupsEndpoint());
assertEquals("https://api-eu.mixpanel.com/decide", config.getDecideEndpoint());
}

@Test
Expand Down Expand Up @@ -187,6 +183,6 @@ private MPConfig mpConfig(final Bundle metaData) {
}

private MixpanelAPI mixpanelApi(final MPConfig config) {
return new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), TOKEN, config, false, null,null);
return new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), TOKEN, config, false, null,null, true);
}
}
Loading