Search in sources :

Example 11 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.

the class Crashes method buildErrorReport.

@VisibleForTesting
ErrorReport buildErrorReport(ManagedErrorLog log) {
    UUID id = log.getId();
    if (mErrorReportCache.containsKey(id)) {
        ErrorReport report = mErrorReportCache.get(id).report;
        report.setDevice(log.getDevice());
        return report;
    } else {
        String stackTrace = null;
        /* If exception in the log doesn't have stack trace try get it from the .throwable file. */
        File file = ErrorLogHelper.getStoredThrowableFile(id);
        if (file != null) {
            if (file.length() > 0) {
                stackTrace = FileManager.read(file);
            }
        }
        if (stackTrace == null) {
            if (MINIDUMP_FILE.equals(log.getException().getType())) {
                stackTrace = getStackTraceString(new NativeException());
            } else {
                stackTrace = buildStackTrace(log.getException());
            }
        }
        ErrorReport report = ErrorLogHelper.getErrorReportFromErrorLog(log, stackTrace);
        mErrorReportCache.put(id, new ErrorLogReport(log, report));
        return report;
    }
}
Also used : ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) Log.getStackTraceString(android.util.Log.getStackTraceString) UUID(java.util.UUID) File(java.io.File) NativeException(com.microsoft.appcenter.crashes.model.NativeException) VisibleForTesting(androidx.annotation.VisibleForTesting)

Example 12 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.

the class WrapperSdkExceptionManager method buildHandledErrorReport.

/**
 * Get a generic error report representation for an handled exception.
 * Since this is used by wrapper SDKs, stack trace and thread name are not known at Java level.
 *
 * @param context       context.
 * @param errorReportId The error report identifier.
 * @return an error report.
 */
public static ErrorReport buildHandledErrorReport(Context context, String errorReportId) {
    ErrorReport report = new ErrorReport();
    report.setId(errorReportId);
    report.setAppErrorTime(new Date());
    report.setAppStartTime(new Date(Crashes.getInstance().getInitializeTimestamp()));
    try {
        report.setDevice(Crashes.getInstance().getDeviceInfo(context));
    } catch (DeviceInfoHelper.DeviceInfoException e) {
        /* The exception is already logged, just adding this log for context and avoid empty catch. */
        AppCenterLog.warn(LOG_TAG, "Handled error report cannot get device info, errorReportId=" + errorReportId);
    }
    return report;
}
Also used : ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) DeviceInfoHelper(com.microsoft.appcenter.utils.DeviceInfoHelper) Date(java.util.Date)

Example 13 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.

the class CrashesAndroidTest method testNoDuplicateCallbacksOrSending.

@Test
public void testNoDuplicateCallbacksOrSending() throws Exception {
    /* Crash on 1st process. */
    Crashes.unsetInstance();
    assertFalse(Crashes.hasCrashedInLastSession().get());
    android.util.Log.i(TAG, "Process 1");
    Thread.UncaughtExceptionHandler uncaughtExceptionHandler = mock(Thread.UncaughtExceptionHandler.class);
    Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
    CrashesListener crashesListener = mock(CrashesListener.class);
    /* While testing should process, call methods that require the handler to test we avoid a dead lock and run directly. */
    when(crashesListener.shouldProcess(any(ErrorReport.class))).thenAnswer(new Answer<Boolean>() {

        @Override
        public Boolean answer(InvocationOnMock invocationOnMock) {
            assertNotNull(AppCenter.getInstallId().get());
            return AppCenter.isEnabled().get() && Crashes.isEnabled().get();
        }
    });
    when(crashesListener.shouldAwaitUserConfirmation()).thenReturn(true);
    startFresh(crashesListener);
    final RuntimeException exception = new RuntimeException();
    final Thread thread = new Thread() {

        @Override
        public void run() {
            throw exception;
        }
    };
    thread.start();
    thread.join();
    verify(uncaughtExceptionHandler).uncaughtException(thread, exception);
    File[] files = ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter);
    assertNotNull(files);
    assertEquals(1, files.length);
    verifyZeroInteractions(crashesListener);
    /* Second process: enqueue log but network is down... */
    android.util.Log.i(TAG, "Process 2");
    startFresh(crashesListener);
    /* Check last session error report. */
    Crashes.getLastSessionCrashReport().thenAccept(new AppCenterConsumer<ErrorReport>() {

        @Override
        public void accept(ErrorReport errorReport) {
            assertNotNull(errorReport);
            assertNotNull(errorReport.getStackTrace());
        }
    });
    assertTrue(Crashes.hasCrashedInLastSession().get());
    /* Wait U.I. thread callback (shouldAwaitUserConfirmation). */
    final Semaphore semaphore = new Semaphore(0);
    HandlerUtils.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            semaphore.release();
        }
    });
    semaphore.acquire();
    /* Waiting user confirmation so no log sent yet. */
    verify(mChannel, never()).enqueue(isA(ManagedErrorLog.class), anyString(), anyInt());
    files = ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter);
    assertNotNull(files);
    assertEquals(1, files.length);
    verify(crashesListener).shouldProcess(any(ErrorReport.class));
    verify(crashesListener).shouldAwaitUserConfirmation();
    verifyNoMoreInteractions(crashesListener);
    /* Confirm to resume processing. */
    Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND);
    assertTrue(Crashes.isEnabled().get());
    ArgumentCaptor<ManagedErrorLog> log = ArgumentCaptor.forClass(ManagedErrorLog.class);
    verify(mChannel).enqueue(log.capture(), anyString(), eq(CRITICAL));
    assertNotNull(log.getValue());
    assertEquals(mUserId, log.getValue().getUserId());
    files = ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter);
    assertNotNull(files);
    assertEquals(0, files.length);
    verify(crashesListener).getErrorAttachments(any(ErrorReport.class));
    verifyNoMoreInteractions(crashesListener);
    /* Third process: sending succeeds. */
    android.util.Log.i(TAG, "Process 3");
    mChannel = mock(Channel.class);
    ArgumentCaptor<Channel.GroupListener> groupListener = ArgumentCaptor.forClass(Channel.GroupListener.class);
    startFresh(crashesListener);
    verify(mChannel).addGroup(anyString(), anyInt(), anyInt(), anyInt(), isNull(Ingestion.class), groupListener.capture());
    groupListener.getValue().onBeforeSending(log.getValue());
    groupListener.getValue().onSuccess(log.getValue());
    /* Wait callback to be processed in background thread (file manipulations) then called back in UI. */
    /*
         * Wait background thread to process the 2 previous commands,
         * to do we check if crashed in last session, since we restarted process again after crash,
         * it's false even if we couldn't send the log yet.
         */
    assertFalse(Crashes.hasCrashedInLastSession().get());
    assertNull(Crashes.getLastSessionCrashReport().get());
    /* Wait U.I. thread callbacks. */
    HandlerUtils.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            semaphore.release();
        }
    });
    semaphore.acquire();
    files = ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter);
    assertNotNull(files);
    assertEquals(0, files.length);
    verify(mChannel, never()).enqueue(isA(ManagedErrorLog.class), anyString(), anyInt());
    verify(crashesListener).onBeforeSending(any(ErrorReport.class));
    verify(crashesListener).onSendingSucceeded(any(ErrorReport.class));
    verifyNoMoreInteractions(crashesListener);
}
Also used : Channel(com.microsoft.appcenter.channel.Channel) Semaphore(java.util.concurrent.Semaphore) Ingestion(com.microsoft.appcenter.ingestion.Ingestion) ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) ManagedErrorLog(com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog) InvocationOnMock(org.mockito.invocation.InvocationOnMock) File(java.io.File) Test(org.junit.Test)

Example 14 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.

the class CrashesTest method crashTest.

/**
 * Crash and sending report test.
 * <p>
 * We can't truly restart application in tests, so some kind of crashes can't be tested by this method.
 * Out of memory or stack overflow - crash the test process;
 * UI states errors - problems with restart activity;
 * <p>
 * Also to avoid flakiness, please setup your test environment
 * (https://google.github.io/android-testing-support-library/docs/espresso/setup/index.html#setup-your-test-environment).
 * On your device, under Settings->Developer options disable the following 3 settings:
 * - Window animation scale
 * - Transition animation scale
 * - Animator duration scale
 *
 * @param titleId Title string resource to find list item.
 * @throws InterruptedException If the current thread is interrupted.
 */
private void crashTest(@StringRes int titleId) throws InterruptedException {
    /* Crash. */
    onView(allOf(withChild(withText(R.string.title_crashes)), withChild(withText(R.string.description_crashes)))).perform(click());
    CrashFailureHandler failureHandler = new CrashFailureHandler();
    onCrash(titleId).withFailureHandler(failureHandler).perform(click());
    /* Check error report. */
    assertTrue(Crashes.hasCrashedInLastSession().get());
    ErrorReport errorReport = Crashes.getLastSessionCrashReport().get();
    assertNotNull(errorReport);
    assertNotNull(errorReport.getId());
    assertEquals(mContext.getMainLooper().getThread().getName(), errorReport.getThreadName());
    assertThat("AppStartTime", new Date().getTime() - errorReport.getAppStartTime().getTime(), lessThan(60000L));
    assertThat("AppErrorTime", new Date().getTime() - errorReport.getAppErrorTime().getTime(), lessThan(10000L));
    assertNotNull(errorReport.getDevice());
    assertTrue(errorReport.getStackTrace().contains(failureHandler.uncaughtException.getMessage()));
    /* Send report. */
    waitFor(onView(withText(R.string.crash_confirmation_dialog_send_button)).inRoot(isDialog()), 1000).perform(click());
    /* Check toasts. */
    waitFor(onToast(mActivityTestRule.getActivity(), withText(R.string.crash_before_sending)), TOAST_DELAY).check(matches(isDisplayed()));
    onView(isRoot()).perform(waitFor(CHECK_DELAY));
    waitFor(onToast(mActivityTestRule.getActivity(), anyOf(withContainsText(R.string.crash_sent_succeeded), withText(R.string.crash_sent_failed))), TOAST_DELAY).check(matches(isDisplayed()));
}
Also used : ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) Date(java.util.Date)

Example 15 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.

the class CrashesTest method handleUserConfirmationDoNotSend.

@Test
public void handleUserConfirmationDoNotSend() throws JSONException {
    /* Prepare data. Mock classes. */
    mockStatic(ErrorLogHelper.class);
    when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class) });
    when(ErrorLogHelper.getNewMinidumpFiles()).thenReturn(new File[0]);
    when(ErrorLogHelper.getErrorReportFromErrorLog(any(ManagedErrorLog.class), anyString())).thenReturn(new ErrorReport());
    File pendingFolder = mock(File.class);
    when(ErrorLogHelper.getPendingMinidumpDirectory()).thenReturn(pendingFolder);
    when(FileManager.read(any(File.class))).thenReturn("");
    CrashesListener mockListener = mock(CrashesListener.class);
    when(mockListener.shouldProcess(any(ErrorReport.class))).thenReturn(true);
    when(mockListener.shouldAwaitUserConfirmation()).thenReturn(true);
    /* Prepare data. Set values. */
    Crashes crashes = Crashes.getInstance();
    LogSerializer logSerializer = mock(LogSerializer.class);
    when(logSerializer.deserializeLog(anyString(), anyString())).thenReturn(mErrorLog);
    crashes.setLogSerializer(logSerializer);
    crashes.setInstanceListener(mockListener);
    crashes.onStarting(mAppCenterHandler);
    crashes.onStarted(mock(Context.class), mock(Channel.class), "", null, true);
    /* Verify. */
    Crashes.notifyUserConfirmation(Crashes.DONT_SEND);
    verify(mockListener, never()).getErrorAttachments(any(ErrorReport.class));
    verifyStatic();
    ErrorLogHelper.cleanPendingMinidumps();
    verifyStatic();
    ErrorLogHelper.removeStoredErrorLogFile(mErrorLog.getId());
    verifyStatic(never());
    ErrorLogHelper.removeLostThrowableFiles();
}
Also used : ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) SessionContext(com.microsoft.appcenter.utils.context.SessionContext) Context(android.content.Context) ManagedErrorLog(com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog) Channel(com.microsoft.appcenter.channel.Channel) DefaultLogSerializer(com.microsoft.appcenter.ingestion.models.json.DefaultLogSerializer) LogSerializer(com.microsoft.appcenter.ingestion.models.json.LogSerializer) File(java.io.File) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Aggregations

ErrorReport (com.microsoft.appcenter.crashes.model.ErrorReport)54 Test (org.junit.Test)40 File (java.io.File)36 ManagedErrorLog (com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog)31 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)31 Context (android.content.Context)26 Channel (com.microsoft.appcenter.channel.Channel)25 LogSerializer (com.microsoft.appcenter.ingestion.models.json.LogSerializer)22 UUID (java.util.UUID)21 ErrorAttachmentLog (com.microsoft.appcenter.crashes.ingestion.models.ErrorAttachmentLog)18 Device (com.microsoft.appcenter.ingestion.models.Device)12 DefaultLogSerializer (com.microsoft.appcenter.ingestion.models.json.DefaultLogSerializer)12 SessionContext (com.microsoft.appcenter.utils.context.SessionContext)12 SessionContext (com.microsoft.appcenter.SessionContext)11 Log (com.microsoft.appcenter.ingestion.models.Log)11 HandledErrorLog (com.microsoft.appcenter.crashes.ingestion.models.HandledErrorLog)10 AppCenterLog (com.microsoft.appcenter.utils.AppCenterLog)10 JSONException (org.json.JSONException)10 InvocationOnMock (org.mockito.invocation.InvocationOnMock)10 TestCrashException (com.microsoft.appcenter.crashes.model.TestCrashException)9