Skip to content

Commit

Permalink
Modify error reporting for API >= 26 (#472)
Browse files Browse the repository at this point in the history
  • Loading branch information
nkukday authored and Harsha Sura committed Apr 21, 2020
1 parent 09101ec commit 8d1438c
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 137 deletions.
2 changes: 1 addition & 1 deletion gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ext {

pluginVersion = [
checkstyle : '8.4',
gradle : '3.5.3',
gradle : '3.6.1',
dependencyGraph : '0.5.0',
mapboxSdkVersions: '1.0.1'
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mapbox.android.telemetry.crash;
package com.mapbox.android.telemetry.errors;

import android.content.Context;
import android.content.SharedPreferences;
Expand All @@ -19,14 +19,14 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class CrashReporterClientInstrumentationTest {
public class ErrorReporterClientInstrumentationTest {
private static final String TEST_DIR_PATH = "com.mapbox.android.telemetry.test";
private static final String CRASH_FILENAME_FORMAT = "%s/%s.crash";
private static final String crashEvent =
"{\"event\":\"mobile.crash\",\"created\":\"2019-02-21T21:58:43.000Z\",\"stackTraceHash\":\"%s\"}";

private File directory;
private CrashReporterClient crashReporterClient;
private ErrorReporterClient errorReporterClient;
private Context context;

@Before
Expand All @@ -40,24 +40,24 @@ public void setUp() {
for (File file: directory.listFiles()) {
file.delete();
}
crashReporterClient = CrashReporterClient.create(context);
errorReporterClient = ErrorReporterClient.create(context);
}

@Test
public void loadInvalidNullPath() {
CrashReporterClient client = crashReporterClient.loadFrom(null);
ErrorReporterClient client = errorReporterClient.loadFrom(null);
assertFalse(client.hasNextEvent());
}

@Test
public void loadInvalidPath() {
CrashReporterClient client = crashReporterClient.loadFrom(new File(""));
ErrorReporterClient client = errorReporterClient.loadFrom(new File(""));
assertFalse(client.hasNextEvent());
}

@Test
public void verifyEventNotLoadedFromEmptyPath() {
CrashReporterClient client = crashReporterClient.loadFrom(directory);
ErrorReporterClient client = errorReporterClient.loadFrom(directory);
assertFalse(client.hasNextEvent());
}

Expand All @@ -67,7 +67,7 @@ public void verifyEventLoadedWithValidHash() throws IOException {
File file = FileUtils.getFile(context, String.format(CRASH_FILENAME_FORMAT, TEST_DIR_PATH, crashHash));
FileUtils.writeToFile(file, String.format(crashEvent, crashHash));

CrashReporterClient client = crashReporterClient.loadFrom(directory);
ErrorReporterClient client = errorReporterClient.loadFrom(directory);
assertTrue(client.hasNextEvent());
}

Expand All @@ -77,7 +77,7 @@ public void verifyEventLoadedFirstTime() throws IOException {
File file = FileUtils.getFile(context, String.format(CRASH_FILENAME_FORMAT, TEST_DIR_PATH, crashHash));
FileUtils.writeToFile(file, String.format(crashEvent, crashHash));

CrashReporterClient client = crashReporterClient.loadFrom(directory);
ErrorReporterClient client = errorReporterClient.loadFrom(directory);
assertTrue(client.hasNextEvent());
}

Expand All @@ -87,10 +87,10 @@ public void verifyFileCursorReset() throws IOException {
File file = FileUtils.getFile(context, String.format(CRASH_FILENAME_FORMAT, TEST_DIR_PATH, crashHash));
FileUtils.writeToFile(file, String.format(crashEvent, crashHash));

CrashReporterClient client = crashReporterClient.loadFrom(directory);
ErrorReporterClient client = errorReporterClient.loadFrom(directory);
assertTrue(client.hasNextEvent());

client = crashReporterClient.loadFrom(new File(""));
client = errorReporterClient.loadFrom(new File(""));
assertFalse(client.hasNextEvent());
}

Expand All @@ -100,7 +100,7 @@ public void verifyDisabledState() {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(MAPBOX_PREF_ENABLE_CRASH_REPORTER, false);
editor.commit();
assertFalse(crashReporterClient.isEnabled());
assertFalse(errorReporterClient.isEnabled());
}

@Test
Expand All @@ -109,7 +109,7 @@ public void verifyEnabledState() {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(MAPBOX_PREF_ENABLE_CRASH_REPORTER, true);
editor.commit();
assertTrue(crashReporterClient.isEnabled());
assertTrue(errorReporterClient.isEnabled());
}

@Test
Expand All @@ -122,21 +122,21 @@ public void filterDupEventsBasedOnHash() throws IOException {
FileUtils.writeToFile(file, String.format(crashEvent, crashHash));

// Need to toggle this flag to simulate telem success
crashReporterClient.loadFrom(directory);
CrashEvent event = crashReporterClient.nextEvent();
assertFalse(crashReporterClient.isDuplicate(event));
errorReporterClient.loadFrom(directory);
CrashEvent event = errorReporterClient.nextEvent();
assertFalse(errorReporterClient.isDuplicate(event));

AtomicBoolean success = new AtomicBoolean(true);
CountDownLatch latch = new CountDownLatch(1);
crashReporterClient.sendSync(event, success, latch);
errorReporterClient.sendSync(event, success, latch);

event = crashReporterClient.nextEvent();
assertTrue(crashReporterClient.isDuplicate(event));
event = errorReporterClient.nextEvent();
assertTrue(errorReporterClient.isDuplicate(event));
}

@Test(expected = IllegalStateException.class)
public void nextCalledPriorLoadEvent() {
crashReporterClient.nextEvent();
errorReporterClient.nextEvent();
}

@Test
Expand All @@ -158,19 +158,19 @@ public void verifyMappedFileDeleted() throws IOException {

@Test
public void deleteInvalidEvent() {
crashReporterClient.loadFrom(directory);
assertFalse(crashReporterClient.delete(new CrashEvent("mobile.crash", "2019-02-21T21:58:43.000Z")));
errorReporterClient.loadFrom(directory);
assertFalse(errorReporterClient.delete(new CrashEvent("mobile.crash", "2019-02-21T21:58:43.000Z")));
}

@Test
public void attemptToDeleteAlreadyDeletedFile() throws IOException {
File file = FileUtils.getFile(context, String.format(CRASH_FILENAME_FORMAT, TEST_DIR_PATH, "crash"));
FileUtils.writeToFile(file, String.format(crashEvent, UUID.randomUUID().toString()));
crashReporterClient.loadFrom(directory);
CrashEvent crashEvent = crashReporterClient.nextEvent();
errorReporterClient.loadFrom(directory);
CrashEvent crashEvent = errorReporterClient.nextEvent();

assertTrue(file.delete());
assertFalse(crashReporterClient.delete(crashEvent));
assertFalse(errorReporterClient.delete(crashEvent));
}

private SharedPreferences getSharedPreferences() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.mapbox.android.telemetry.crash;
package com.mapbox.android.telemetry.errors;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.test.InstrumentationRegistry;

import com.mapbox.android.core.FileUtils;

import org.junit.Before;
import org.junit.Test;

Expand All @@ -16,7 +18,8 @@
import static com.mapbox.android.telemetry.MapboxTelemetryConstants.MAPBOX_TELEMETRY_PACKAGE;
import static org.junit.Assert.assertEquals;

public class CrashReporterJobIntentServiceInstrumentationTest {
public class ErrorReporterEngineInstrumentedTest {

private static final String CRASH_FILENAME_FORMAT = "%s/%s.crash";
private static final String crashEvent =
"{\"event\":\"mobile.crash\",\"created\":\"2019-02-21T21:58:43.000Z\",\"stackTraceHash\":\"%s\"}";
Expand All @@ -32,17 +35,11 @@ public void setUp() {
directory.mkdir();
}

for (File file: directory.listFiles()) {
for (File file : directory.listFiles()) {
file.delete();
}
}

@Test
public void enqueueWork() {
CrashReporterJobIntentService.enqueueWork(InstrumentationRegistry.getTargetContext());
// TODO: verify work is executed
}

@Test
public void handleCrashReports() throws IOException {
SharedPreferences sharedPreferences =
Expand All @@ -54,11 +51,10 @@ public void handleCrashReports() throws IOException {
File file = FileUtils.getFile(context, String.format(CRASH_FILENAME_FORMAT, MAPBOX_TELEMETRY_PACKAGE, "crash1"));
FileUtils.writeToFile(file, String.format(crashEvent, UUID.randomUUID().toString()));

CrashReporterJobIntentService jobIntentService = new CrashReporterJobIntentService();
jobIntentService.handleCrashReports(CrashReporterClient
.create(InstrumentationRegistry.getTargetContext())
ErrorReporterEngine.handleErrorReports(ErrorReporterClient
.create(context.getApplicationContext())
.loadFrom(directory)
.debug(true));
assertEquals(0, FileUtils.listAllFiles(directory).length);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.mapbox.android.telemetry.errors;


import android.support.test.InstrumentationRegistry;

import org.junit.Test;

public class ErrorReporterJobIntentServiceInstrumentationTest {

@Test
public void enqueueWork() {
ErrorReporterJobIntentService.enqueueWork(InstrumentationRegistry.getInstrumentation().getTargetContext());
// TODO: verify work is executed
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mapbox.android.telemetry.crash;
package com.mapbox.android.telemetry.errors;

import android.content.Intent;
import android.support.test.InstrumentationRegistry;
Expand Down
2 changes: 1 addition & 1 deletion libtelemetry/src/full/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
android:authorities="${applicationId}.mapboxtelemetryinitprovider"
android:exported="false"
android:initOrder="100"/>
<service android:name=".crash.CrashReporterJobIntentService"
<service android:name=".errors.ErrorReporterJobIntentService"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
package com.mapbox.android.telemetry;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import com.mapbox.android.telemetry.errors.ErrorReporterEngine;

import java.io.IOException;
import java.util.List;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;

import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;

import android.util.Log;

import okhttp3.Call;
import okhttp3.Callback;
Expand Down Expand Up @@ -54,7 +53,8 @@ public class MapboxTelemetry implements FullQueueCallback, ServiceTaskCallback {

public MapboxTelemetry(Context context, String accessToken, String userAgent) {
initializeContext(context);
setAccessToken(context, accessToken);
this.executorService = ExecutorServiceFactory.create("MapboxTelemetryExecutor", 3, 20);
setAccessToken(context, accessToken, executorService);
this.userAgent = userAgent;
AlarmReceiver alarmReceiver = obtainAlarmReceiver();
this.schedulerFlusher = new SchedulerFlusherFactory(applicationContext, alarmReceiver).supply();
Expand All @@ -63,8 +63,6 @@ public MapboxTelemetry(Context context, String accessToken, String userAgent) {
initializeAttachmentListeners();
// Initializing callback after listeners object is instantiated
this.httpCallback = getHttpCallback(telemetryListeners);
this.executorService = ExecutorServiceFactory.create("MapboxTelemetryExecutor", 3,
20);
this.queue = EventsQueue.create(this, executorService);
}

Expand All @@ -73,7 +71,7 @@ public MapboxTelemetry(Context context, String accessToken, String userAgent) {
TelemetryClient telemetryClient, Callback httpCallback, SchedulerFlusher schedulerFlusher,
Clock clock, TelemetryEnabler telemetryEnabler, ExecutorService executorService) {
initializeContext(context);
setAccessToken(context, accessToken);
setAccessToken(context, accessToken, executorService);
this.userAgent = userAgent;
this.telemetryClient = telemetryClient;
this.schedulerFlusher = schedulerFlusher;
Expand Down Expand Up @@ -412,13 +410,15 @@ public void run() {
});
}

private static synchronized void setAccessToken(@NonNull Context context, @NonNull String accessToken) {
private static synchronized void setAccessToken(@NonNull final Context context,
@NonNull String accessToken,
@NonNull ExecutorService executorService) {
if (TelemetryUtils.isEmpty(accessToken)) {
return;
}
// Set token and check return value to see if it was previously nil and send pending error reports
if (sAccessToken.getAndSet(accessToken).isEmpty()) {
LocalBroadcastManager.getInstance(context)
.sendBroadcast(new Intent(MapboxTelemetryConstants.ACTION_TOKEN_CHANGED));
ErrorReporterEngine.sendErrorReports(context, executorService);
}
}

Expand Down
Loading

0 comments on commit 8d1438c

Please sign in to comment.