use of com.microsoft.azure.mobile.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.
the class CrashesAndroidTest method testNoDuplicateCallbacksOrSending.
@Test
public void testNoDuplicateCallbacksOrSending() throws InterruptedException {
/* Crash on 1st process. */
assertFalse(Crashes.hasCrashedInLastSession());
android.util.Log.i(TAG, "Process 1");
Thread.UncaughtExceptionHandler uncaughtExceptionHandler = mock(Thread.UncaughtExceptionHandler.class);
Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
Channel channel = mock(Channel.class);
Crashes.getInstance().onStarted(sContext, "", channel);
CrashesListener crashesListener = mock(CrashesListener.class);
when(crashesListener.shouldProcess(any(ErrorReport.class))).thenReturn(true);
when(crashesListener.shouldAwaitUserConfirmation()).thenReturn(true);
Crashes.setListener(crashesListener);
final Error exception = generateStackOverflowError();
assertTrue(exception.getStackTrace().length > ErrorLogHelper.FRAME_LIMIT);
final Thread thread = new Thread() {
@Override
public void run() {
throw exception;
}
};
thread.start();
thread.join();
assertEquals(ErrorLogHelper.FRAME_LIMIT, exception.getStackTrace().length);
verify(uncaughtExceptionHandler).uncaughtException(thread, exception);
assertEquals(2, ErrorLogHelper.getErrorStorageDirectory().listFiles().length);
verifyZeroInteractions(crashesListener);
/* Second process: enqueue log but network is down... */
android.util.Log.i(TAG, "Process 2");
final AtomicReference<Log> log = new AtomicReference<>();
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
log.set((Log) invocationOnMock.getArguments()[0]);
return null;
}
}).when(channel).enqueue(any(Log.class), anyString());
Crashes.unsetInstance();
Crashes.setListener(crashesListener);
Crashes.getInstance().onStarted(sContext, "", channel);
waitForCrashesHandlerTasksToComplete();
/* Check last session error report. */
assertTrue(Crashes.hasCrashedInLastSession());
Crashes.getLastSessionCrashReport(new ResultCallback<ErrorReport>() {
@Override
public void onResult(ErrorReport errorReport) {
assertNotNull(errorReport);
Throwable lastThrowable = errorReport.getThrowable();
assertTrue(lastThrowable instanceof StackOverflowError);
assertEquals(ErrorLogHelper.FRAME_LIMIT, lastThrowable.getStackTrace().length);
}
});
/* Waiting user confirmation so no log sent yet. */
verify(channel, never()).enqueue(any(Log.class), anyString());
assertEquals(2, ErrorLogHelper.getErrorStorageDirectory().listFiles().length);
verify(crashesListener).shouldProcess(any(ErrorReport.class));
verify(crashesListener).shouldAwaitUserConfirmation();
verifyNoMoreInteractions(crashesListener);
/* Confirm to resume processing. */
Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND);
verify(channel).enqueue(any(Log.class), anyString());
assertNotNull(log.get());
assertEquals(1, ErrorLogHelper.getErrorStorageDirectory().listFiles().length);
verify(crashesListener).getErrorAttachments(any(ErrorReport.class));
verifyNoMoreInteractions(crashesListener);
/* Third process: sending succeeds. */
android.util.Log.i(TAG, "Process 3");
final AtomicReference<Channel.GroupListener> groupListener = new AtomicReference<>();
channel = mock(Channel.class);
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Channel.GroupListener listener = (Channel.GroupListener) invocationOnMock.getArguments()[4];
groupListener.set(listener);
listener.onBeforeSending(log.get());
return null;
}
}).when(channel).addGroup(anyString(), anyInt(), anyInt(), anyInt(), any(Channel.GroupListener.class));
Crashes.unsetInstance();
Crashes.setListener(crashesListener);
Crashes.getInstance().onStarted(sContext, "", channel);
waitForCrashesHandlerTasksToComplete();
assertFalse(Crashes.hasCrashedInLastSession());
Crashes.getLastSessionCrashReport(new ResultCallback<ErrorReport>() {
@Override
public void onResult(ErrorReport errorReport) {
assertNull(errorReport);
}
});
assertNotNull(groupListener.get());
groupListener.get().onSuccess(log.get());
waitForCrashesHandlerTasksToComplete();
assertEquals(0, ErrorLogHelper.getErrorStorageDirectory().listFiles().length);
verify(channel, never()).enqueue(any(Log.class), anyString());
verify(crashesListener).onBeforeSending(any(ErrorReport.class));
verify(crashesListener).onSendingSucceeded(any(ErrorReport.class));
verifyNoMoreInteractions(crashesListener);
/* Verify log was truncated to 256 frames. */
assertTrue(log.get() instanceof ManagedErrorLog);
ManagedErrorLog errorLog = (ManagedErrorLog) log.get();
assertNotNull(errorLog.getException());
assertNotNull(errorLog.getException().getFrames());
assertEquals(ErrorLogHelper.FRAME_LIMIT, errorLog.getException().getFrames().size());
}
use of com.microsoft.azure.mobile.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.
the class MainActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sSharedPreferences = getSharedPreferences("Sasquatch", Context.MODE_PRIVATE);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().build());
/* Set custom log URL if one was configured in settings. */
String logUrl = sSharedPreferences.getString(LOG_URL_KEY, getString(R.string.log_url));
if (!TextUtils.isEmpty(logUrl)) {
MobileCenter.setLogUrl(logUrl);
}
/* Set listeners. */
AnalyticsPrivateHelper.setListener(getAnalyticsListener());
Crashes.setListener(new SasquatchCrashesListener(this));
Distribute.setListener(new SasquatchDistributeListener());
Push.setListener(getPushListener());
/* Set distribute urls. */
String installUrl = getString(R.string.install_url);
if (!TextUtils.isEmpty(installUrl)) {
Distribute.setInstallUrl(installUrl);
}
String apiUrl = getString(R.string.api_url);
if (!TextUtils.isEmpty(apiUrl)) {
Distribute.setApiUrl(apiUrl);
}
/* Enable Firebase analytics if we enabled the setting previously. */
if (sSharedPreferences.getBoolean(FIREBASE_ENABLED_KEY, false)) {
Push.enableFirebaseAnalytics(this);
}
/* Start Mobile center. */
MobileCenter.start(getApplication(), sSharedPreferences.getString(APP_SECRET_KEY, getString(R.string.app_secret)), Analytics.class, Crashes.class, Distribute.class, Push.class);
/* Print last crash. */
Log.i(LOG_TAG, "Crashes.hasCrashedInLastSession=" + Crashes.hasCrashedInLastSession());
Crashes.getLastSessionCrashReport(new ResultCallback<ErrorReport>() {
@Override
public void onResult(@Nullable ErrorReport data) {
if (data != null) {
Log.i(LOG_TAG, "Crashes.getLastSessionCrashReport().getThrowable()=", data.getThrowable());
}
}
});
/* Populate UI. */
((TextView) findViewById(R.id.package_name)).setText(String.format(getString(R.string.sdk_source_format), getPackageName().substring(getPackageName().lastIndexOf(".") + 1)));
TestFeatures.initialize(this);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(new TestFeaturesListAdapter(TestFeatures.getAvailableControls()));
listView.setOnItemClickListener(TestFeatures.getOnItemClickListener());
}
use of com.microsoft.azure.mobile.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.
the class CrashesTest method crashInLastSessionCorrupted.
@Test
public void crashInLastSessionCorrupted() throws IOException {
mockStatic(ErrorLogHelper.class);
File file = errorStorageDirectory.newFile("last-error-log.json");
when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { file });
when(ErrorLogHelper.getLastErrorLogFile()).thenReturn(file);
Crashes.getInstance().onStarted(mock(Context.class), "", mock(Channel.class));
assertFalse(Crashes.hasCrashedInLastSession());
Crashes.getLastSessionCrashReport(new ResultCallback<ErrorReport>() {
@Override
public void onResult(ErrorReport data) {
assertNull(data);
}
});
}
use of com.microsoft.azure.mobile.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.
the class CrashesTest method queuePendingCrashesShouldProcess.
@Test
public void queuePendingCrashesShouldProcess() throws IOException, ClassNotFoundException, JSONException {
/* Setup mock. */
Context mockContext = mock(Context.class);
Channel mockChannel = mock(Channel.class);
ErrorReport report = new ErrorReport();
mockStatic(ErrorLogHelper.class);
when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class) });
when(ErrorLogHelper.getStoredThrowableFile(any(UUID.class))).thenReturn(mock(File.class));
when(ErrorLogHelper.getErrorReportFromErrorLog(any(ManagedErrorLog.class), any(Throwable.class))).thenReturn(report);
when(StorageHelper.InternalStorage.read(any(File.class))).thenReturn("");
when(StorageHelper.InternalStorage.readObject(any(File.class))).thenReturn(new RuntimeException());
CrashesListener mockListener = mock(CrashesListener.class);
when(mockListener.shouldProcess(report)).thenReturn(true);
when(mockListener.shouldAwaitUserConfirmation()).thenReturn(false);
ErrorAttachmentLog mockAttachment = mock(ErrorAttachmentLog.class);
when(mockAttachment.getId()).thenReturn(UUID.randomUUID());
when(mockAttachment.getErrorId()).thenReturn(UUID.randomUUID());
when(mockAttachment.getContentType()).thenReturn("");
when(mockAttachment.getFileName()).thenReturn("");
when(mockAttachment.getData()).thenReturn(new byte[0]);
when(mockAttachment.isValid()).thenReturn(true);
ErrorAttachmentLog mockEmptyAttachment = mock(ErrorAttachmentLog.class);
final int skipAttachmentLogsCount = 2;
List<ErrorAttachmentLog> errorAttachmentLogList = Arrays.asList(mockAttachment, mockAttachment, mockEmptyAttachment, null);
when(mockListener.getErrorAttachments(report)).thenReturn(errorAttachmentLogList);
LogSerializer logSerializer = mock(LogSerializer.class);
when(logSerializer.deserializeLog(anyString())).thenReturn(mErrorLog);
Crashes crashes = Crashes.getInstance();
crashes.setLogSerializer(logSerializer);
crashes.setInstanceListener(mockListener);
crashes.onStarted(mockContext, "", mockChannel);
/* Test. */
verify(mockListener).shouldProcess(report);
verify(mockListener).shouldAwaitUserConfirmation();
verify(mockListener).getErrorAttachments(report);
verify(mockChannel).enqueue(argThat(new ArgumentMatcher<Log>() {
@Override
public boolean matches(Object log) {
return log.equals(mErrorLog);
}
}), eq(crashes.getGroupName()));
verify(mockChannel, times(errorAttachmentLogList.size() - skipAttachmentLogsCount)).enqueue(mockAttachment, crashes.getGroupName());
}
use of com.microsoft.azure.mobile.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.
the class CrashesTest method disabledDuringHandleUserConfirmation.
@Test
public void disabledDuringHandleUserConfirmation() throws IOException, ClassNotFoundException, JSONException {
ManagedErrorLog errorLog = ErrorLogHelper.createErrorLog(mock(Context.class), Thread.currentThread(), new RuntimeException(), Thread.getAllStackTraces(), 0, true);
ErrorReport errorReport1 = ErrorLogHelper.getErrorReportFromErrorLog(mErrorLog, EXCEPTION);
ErrorReport errorReport2 = ErrorLogHelper.getErrorReportFromErrorLog(errorLog, EXCEPTION);
File errorStorageDirectory = mock(File.class);
when(errorStorageDirectory.listFiles()).thenReturn(new File[0]);
CrashesListener listener = mock(CrashesListener.class);
when(listener.shouldProcess(any(ErrorReport.class))).thenReturn(true);
LogSerializer logSerializer = mock(LogSerializer.class);
when(logSerializer.deserializeLog(anyString())).thenReturn(mErrorLog).thenReturn(errorLog);
Channel channel = mock(Channel.class);
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Crashes.setEnabled(false);
return null;
}
}).when(channel).enqueue(any(Log.class), anyString());
mockStatic(ErrorLogHelper.class);
when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class), mock(File.class) });
when(ErrorLogHelper.getErrorStorageDirectory()).thenReturn(errorStorageDirectory);
when(ErrorLogHelper.getStoredThrowableFile(any(UUID.class))).thenReturn(mock(File.class));
when(ErrorLogHelper.getErrorReportFromErrorLog(mErrorLog, EXCEPTION)).thenReturn(errorReport1);
when(ErrorLogHelper.getErrorReportFromErrorLog(errorLog, EXCEPTION)).thenReturn(errorReport2);
when(StorageHelper.InternalStorage.readObject(any(File.class))).thenReturn(EXCEPTION);
when(StorageHelper.InternalStorage.read(any(File.class))).thenReturn("");
Crashes crashes = Crashes.getInstance();
crashes.setLogSerializer(logSerializer);
crashes.setInstanceListener(listener);
crashes.onStarted(mock(Context.class), "", channel);
verify(mMockLooper).quit();
verify(listener, times(2)).shouldProcess(any(ErrorReport.class));
verify(listener).shouldAwaitUserConfirmation();
verify(channel).enqueue(any(Log.class), anyString());
verify(listener).getErrorAttachments(any(ErrorReport.class));
verifyNoMoreInteractions(listener);
}
Aggregations