Search in sources :

Example 31 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-SDK-Android by Microsoft.

the class CrashesTest method getChannelListener.

@Test
public void getChannelListener() throws IOException, ClassNotFoundException {
    ErrorReport errorReport = ErrorLogHelper.getErrorReportFromErrorLog(mErrorLog, EXCEPTION);
    mockStatic(ErrorLogHelper.class);
    when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class) });
    when(ErrorLogHelper.getNewMinidumpFiles()).thenReturn(new File[0]);
    File throwableFile = mock(File.class);
    when(throwableFile.length()).thenReturn(1L);
    when(ErrorLogHelper.getStoredThrowableFile(any(UUID.class))).thenReturn(throwableFile);
    when(ErrorLogHelper.getErrorReportFromErrorLog(mErrorLog, EXCEPTION)).thenReturn(errorReport);
    when(StorageHelper.InternalStorage.readObject(any(File.class))).thenReturn(EXCEPTION);
    CrashesListener crashesListener = mock(CrashesListener.class);
    Crashes.setListener(crashesListener);
    Crashes crashes = Crashes.getInstance();
    crashes.onStarting(mAppCenterHandler);
    crashes.onStarted(mock(Context.class), "", mock(Channel.class));
    ArgumentCaptor<ErrorReport> errorReportCaptor = ArgumentCaptor.forClass(ErrorReport.class);
    Channel.GroupListener channelListener = crashes.getChannelListener();
    channelListener.onBeforeSending(mErrorLog);
    verify(crashesListener).onBeforeSending(errorReportCaptor.capture());
    assertErrorEquals(mErrorLog, errorReportCaptor.getValue());
    channelListener.onSuccess(mErrorLog);
    verify(crashesListener).onSendingSucceeded(errorReportCaptor.capture());
    assertErrorEquals(mErrorLog, errorReportCaptor.getValue());
    channelListener.onFailure(mErrorLog, EXCEPTION);
    verify(crashesListener).onSendingFailed(errorReportCaptor.capture(), eq(EXCEPTION));
    assertErrorEquals(mErrorLog, errorReportCaptor.getValue());
}
Also used : ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) Context(android.content.Context) SessionContext(com.microsoft.appcenter.SessionContext) Channel(com.microsoft.appcenter.channel.Channel) UUID(java.util.UUID) File(java.io.File) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 32 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-SDK-Android by Microsoft.

the class CrashesTest method handleUserConfirmationDoNotSend.

@Test
public void handleUserConfirmationDoNotSend() throws IOException, ClassNotFoundException, JSONException {
    mockStatic(ErrorLogHelper.class);
    when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class) });
    when(ErrorLogHelper.getNewMinidumpFiles()).thenReturn(new File[0]);
    when(ErrorLogHelper.getStoredThrowableFile(any(UUID.class))).thenReturn(mock(File.class));
    when(ErrorLogHelper.getErrorReportFromErrorLog(any(ManagedErrorLog.class), any(Throwable.class))).thenReturn(new ErrorReport());
    when(StorageHelper.InternalStorage.read(any(File.class))).thenReturn("");
    when(StorageHelper.InternalStorage.readObject(any(File.class))).thenReturn(null);
    CrashesListener mockListener = mock(CrashesListener.class);
    when(mockListener.shouldProcess(any(ErrorReport.class))).thenReturn(true);
    when(mockListener.shouldAwaitUserConfirmation()).thenReturn(true);
    Crashes crashes = Crashes.getInstance();
    LogSerializer logSerializer = mock(LogSerializer.class);
    when(logSerializer.deserializeLog(anyString())).thenReturn(mErrorLog);
    crashes.setLogSerializer(logSerializer);
    crashes.setInstanceListener(mockListener);
    crashes.onStarting(mAppCenterHandler);
    crashes.onStarted(mock(Context.class), "", mock(Channel.class));
    Crashes.notifyUserConfirmation(Crashes.DONT_SEND);
    verify(mockListener, never()).getErrorAttachments(any(ErrorReport.class));
    verifyStatic();
    ErrorLogHelper.removeStoredErrorLogFile(mErrorLog.getId());
    verifyStatic();
    ErrorLogHelper.removeStoredThrowableFile(mErrorLog.getId());
}
Also used : ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) Context(android.content.Context) SessionContext(com.microsoft.appcenter.SessionContext) ManagedErrorLog(com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog) Channel(com.microsoft.appcenter.channel.Channel) LogSerializer(com.microsoft.appcenter.ingestion.models.json.LogSerializer) UUID(java.util.UUID) File(java.io.File) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 33 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-SDK-Android by Microsoft.

the class CrashesAndroidTest method testNoDuplicateCallbacksOrSending.

@Test
public void testNoDuplicateCallbacksOrSending() throws Exception {
    /* Crash on 1st process. */
    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) throws Throwable {
            assertNotNull(AppCenter.getInstallId().get());
            return AppCenter.isEnabled().get() && Crashes.isEnabled().get();
        }
    });
    when(crashesListener.shouldAwaitUserConfirmation()).thenReturn(true);
    startFresh(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(mMinidumpFilter).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);
            Throwable lastThrowable = errorReport.getThrowable();
            assertTrue(lastThrowable instanceof StackOverflowError);
            assertEquals(ErrorLogHelper.FRAME_LIMIT, lastThrowable.getStackTrace().length);
        }
    });
    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. */
    ArgumentMatcher<Log> matchCrashLog = new ArgumentMatcher<Log>() {

        @Override
        public boolean matches(Object o) {
            return o instanceof ManagedErrorLog;
        }
    };
    verify(mChannel, never()).enqueue(argThat(matchCrashLog), anyString());
    assertEquals(2, ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter).length);
    verify(crashesListener).shouldProcess(any(ErrorReport.class));
    verify(crashesListener).shouldAwaitUserConfirmation();
    verifyNoMoreInteractions(crashesListener);
    /* Confirm to resume processing. */
    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(mChannel).enqueue(argThat(matchCrashLog), anyString());
    Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND);
    assertTrue(Crashes.isEnabled().get());
    verify(mChannel).enqueue(argThat(matchCrashLog), anyString());
    assertNotNull(log.get());
    assertEquals(1, ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter).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(), groupListener.capture());
    groupListener.getValue().onBeforeSending(log.get());
    groupListener.getValue().onSuccess(log.get());
    /* 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();
    assertEquals(0, ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter).length);
    verify(mChannel, never()).enqueue(argThat(matchCrashLog), 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());
}
Also used : Semaphore(java.util.concurrent.Semaphore) ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) ManagedErrorLog(com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog) ArgumentMatcher(org.mockito.ArgumentMatcher) ErrorAttachmentLog(com.microsoft.appcenter.crashes.ingestion.models.ErrorAttachmentLog) ManagedErrorLog(com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog) Log(com.microsoft.appcenter.ingestion.models.Log) Channel(com.microsoft.appcenter.channel.Channel) AtomicReference(java.util.concurrent.atomic.AtomicReference) Answer(org.mockito.stubbing.Answer) Mockito.doAnswer(org.mockito.Mockito.doAnswer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.Test)

Example 34 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-SDK-Android by Microsoft.

the class Crashes method buildErrorReport.

@VisibleForTesting
@Nullable
ErrorReport buildErrorReport(ManagedErrorLog log) {
    UUID id = log.getId();
    if (mErrorReportCache.containsKey(id)) {
        return mErrorReportCache.get(id).report;
    } else {
        File file = ErrorLogHelper.getStoredThrowableFile(id);
        if (file != null) {
            try {
                Throwable throwable = null;
                if (file.length() > 0) {
                    throwable = StorageHelper.InternalStorage.readObject(file);
                }
                ErrorReport report = ErrorLogHelper.getErrorReportFromErrorLog(log, throwable);
                mErrorReportCache.put(id, new ErrorLogReport(log, report));
                return report;
            } catch (ClassNotFoundException ignored) {
                AppCenterLog.error(LOG_TAG, "Cannot read throwable file " + file.getName(), ignored);
            } catch (IOException ignored) {
                AppCenterLog.error(LOG_TAG, "Cannot access serialized throwable file " + file.getName(), ignored);
            }
        }
    }
    return null;
}
Also used : ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) IOException(java.io.IOException) UUID(java.util.UUID) File(java.io.File) VisibleForTesting(android.support.annotation.VisibleForTesting) Nullable(android.support.annotation.Nullable)

Example 35 with ErrorReport

use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-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)) {
        AppCenter.setLogUrl(logUrl);
    }
    /* Set listeners. */
    AnalyticsPrivateHelper.setListener(getAnalyticsListener());
    Crashes.setListener(getCrashesListener());
    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);
    }
    Push.setSenderId(SENDER_ID);
    /* Set crash attachments. */
    sCrashesListener.setTextAttachment(sSharedPreferences.getString(TEXT_ATTACHMENT_KEY, null));
    String fileAttachment = sSharedPreferences.getString(FILE_ATTACHMENT_KEY, null);
    if (fileAttachment != null) {
        sCrashesListener.setFileAttachment(Uri.parse(fileAttachment));
    }
    /* Enable Firebase analytics if we enabled the setting previously. */
    if (sSharedPreferences.getBoolean(FIREBASE_ENABLED_KEY, false)) {
        Push.enableFirebaseAnalytics(this);
    }
    /* Start App Center. */
    AppCenter.start(getApplication(), sSharedPreferences.getString(APP_SECRET_KEY, getString(R.string.app_secret)), Analytics.class, Crashes.class, Distribute.class, Push.class);
    /* Attach NDK Crash Handler (if available) after SDK is initialized. */
    CrashesPrivateHelper.getMinidumpDirectory().thenAccept(new AppCenterConsumer<String>() {

        @Override
        public void accept(String path) {
            /* Path is null when Crashes is disabled. */
            if (path != null) {
                setupNativeCrashesListener(path);
            }
        }
    });
    /* Use some App Center getters. */
    AppCenter.getInstallId().thenAccept(new AppCenterConsumer<UUID>() {

        @Override
        public void accept(UUID uuid) {
            Log.i(LOG_TAG, "InstallId=" + uuid);
        }
    });
    /* Print last crash. */
    Crashes.hasCrashedInLastSession().thenAccept(new AppCenterConsumer<Boolean>() {

        @Override
        public void accept(Boolean crashed) {
            Log.i(LOG_TAG, "Crashes.hasCrashedInLastSession=" + crashed);
        }
    });
    Crashes.getLastSessionCrashReport().thenAccept(new AppCenterConsumer<ErrorReport>() {

        @Override
        public void accept(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 = findViewById(R.id.list);
    listView.setAdapter(new TestFeaturesListAdapter(TestFeatures.getAvailableControls()));
    listView.setOnItemClickListener(TestFeatures.getOnItemClickListener());
}
Also used : SasquatchDistributeListener(com.microsoft.appcenter.sasquatch.SasquatchDistributeListener) TestFeaturesListAdapter(com.microsoft.appcenter.sasquatch.features.TestFeaturesListAdapter) ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) StrictMode(android.os.StrictMode) ListView(android.widget.ListView) TextView(android.widget.TextView) UUID(java.util.UUID)

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