use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-SDK-Android by Microsoft.
the class CrashesTest method manualProcessing.
@Test
public void manualProcessing() throws Exception {
/* Setup mock for a crash in disk. */
Context mockContext = mock(Context.class);
Channel mockChannel = mock(Channel.class);
ErrorReport report1 = new ErrorReport();
report1.setId(UUIDUtils.randomUUID().toString());
ErrorReport report2 = new ErrorReport();
mockStatic(ErrorLogHelper.class);
when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class), 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(report1).thenReturn(report2);
when(StorageHelper.InternalStorage.read(any(File.class))).thenReturn("");
when(StorageHelper.InternalStorage.readObject(any(File.class))).thenReturn(new RuntimeException());
LogSerializer logSerializer = mock(LogSerializer.class);
when(logSerializer.deserializeLog(anyString())).thenAnswer(new Answer<ManagedErrorLog>() {
@Override
public ManagedErrorLog answer(InvocationOnMock invocation) throws Throwable {
ManagedErrorLog log = mock(ManagedErrorLog.class);
when(log.getId()).thenReturn(UUID.randomUUID());
return log;
}
});
Crashes crashes = Crashes.getInstance();
crashes.setLogSerializer(logSerializer);
/* Create listener for user confirmation. */
CrashesListener listener = mock(CrashesListener.class);
Crashes.setListener(listener);
/* Set manual processing. */
WrapperSdkExceptionManager.setAutomaticProcessing(false);
/* Start crashes. */
crashes.onStarting(mAppCenterHandler);
crashes.onStarted(mockContext, "", mockChannel);
/* No log queued. */
verify(mockChannel, never()).enqueue(any(Log.class), eq(crashes.getGroupName()));
/* Get crash reports. */
Collection<ErrorReport> reports = WrapperSdkExceptionManager.getUnprocessedErrorReports().get();
assertNotNull(reports);
assertEquals(2, reports.size());
Iterator<ErrorReport> iterator = reports.iterator();
assertEquals(report1, iterator.next());
assertEquals(report2, iterator.next());
/* Listener not called yet on anything on manual processing. */
verifyZeroInteractions(listener);
/* Send only the first. */
assertFalse(WrapperSdkExceptionManager.sendCrashReportsOrAwaitUserConfirmation(Collections.singletonList(report1.getId())).get());
/* We used manual process function, listener not called. */
verifyZeroInteractions(listener);
/* No log sent until manual user confirmation in that mode (we are not in always send). */
verify(mockChannel, never()).enqueue(any(ManagedErrorLog.class), eq(crashes.getGroupName()));
/* Confirm with always send. */
Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND);
verifyStatic();
StorageHelper.PreferencesStorage.putBoolean(Crashes.PREF_KEY_ALWAYS_SEND, true);
when(StorageHelper.PreferencesStorage.getBoolean(eq(Crashes.PREF_KEY_ALWAYS_SEND), anyBoolean())).thenReturn(true);
/* 1 log sent. Other one is filtered. */
verify(mockChannel).enqueue(any(ManagedErrorLog.class), eq(crashes.getGroupName()));
/* We can send attachments via wrapper instead of using listener (both work but irrelevant to test with listener). */
ErrorAttachmentLog mockAttachment = mock(ErrorAttachmentLog.class);
when(mockAttachment.getId()).thenReturn(UUID.randomUUID());
when(mockAttachment.getData()).thenReturn(new byte[0]);
when(mockAttachment.isValid()).thenReturn(true);
WrapperSdkExceptionManager.sendErrorAttachments(report1.getId(), Collections.singletonList(mockAttachment));
verify(mockChannel).enqueue(eq(mockAttachment), eq(crashes.getGroupName()));
/* Send attachment with invalid UUID format for report identifier. */
mockAttachment = mock(ErrorAttachmentLog.class);
when(mockAttachment.getId()).thenReturn(UUID.randomUUID());
when(mockAttachment.getData()).thenReturn(new byte[0]);
when(mockAttachment.isValid()).thenReturn(true);
WrapperSdkExceptionManager.sendErrorAttachments("not-a-uuid", Collections.singletonList(mockAttachment));
verify(mockChannel, never()).enqueue(eq(mockAttachment), eq(crashes.getGroupName()));
/* We used manual process function, listener not called and our mock channel does not send events. */
verifyZeroInteractions(listener);
/* Reset instance to test another tine with always send. */
Crashes.unsetInstance();
crashes = Crashes.getInstance();
when(ErrorLogHelper.getErrorReportFromErrorLog(any(ManagedErrorLog.class), any(Throwable.class))).thenReturn(report1).thenReturn(report2);
WrapperSdkExceptionManager.setAutomaticProcessing(false);
crashes.setLogSerializer(logSerializer);
crashes.onStarting(mAppCenterHandler);
mockChannel = mock(Channel.class);
crashes.onStarted(mockContext, "", mockChannel);
assertTrue(Crashes.isEnabled().get());
verify(mockChannel, never()).enqueue(any(ManagedErrorLog.class), eq(crashes.getGroupName()));
/* Get crash reports, check always sent was returned and sent without confirmation. */
assertTrue(WrapperSdkExceptionManager.sendCrashReportsOrAwaitUserConfirmation(Collections.singletonList(report2.getId())).get());
verify(mockChannel).enqueue(any(ManagedErrorLog.class), eq(crashes.getGroupName()));
}
use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-SDK-Android by Microsoft.
the class CrashesTest method queuePendingCrashesShouldNotProcess.
@Test
public void queuePendingCrashesShouldNotProcess() throws IOException, ClassNotFoundException, JSONException {
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.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(report);
when(StorageHelper.InternalStorage.read(any(File.class))).thenReturn("");
when(StorageHelper.InternalStorage.readObject(any(File.class))).thenReturn(new RuntimeException()).thenReturn(new byte[] {});
CrashesListener mockListener = mock(CrashesListener.class);
when(mockListener.shouldProcess(report)).thenReturn(false);
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(mockContext, "", mockChannel);
verify(mockListener).shouldProcess(report);
verify(mockListener, never()).shouldAwaitUserConfirmation();
verify(mockListener, never()).getErrorAttachments(report);
verify(mockChannel, never()).enqueue(any(Log.class), eq(crashes.getGroupName()));
}
use of com.microsoft.appcenter.crashes.model.ErrorReport in project AppCenter-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.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(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.onStarting(mAppCenterHandler);
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.appcenter.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.
the class CrashesTest method testNativeCrashLog.
private ManagedErrorLog testNativeCrashLog(long appStartTime, long crashTime, boolean correlateSession, boolean hasDeviceInfo, boolean hasUserId) throws Exception {
/* Create minidump sub-folder. */
File minidumpSubfolder = mTemporaryFolder.newFolder("mockFolder");
String mockUserId = "user-id";
/* Create a file for a crash in disk. */
File minidumpFile = new File(minidumpSubfolder, "mockFile.dmp");
assertTrue(minidumpFile.createNewFile());
assertTrue(minidumpFile.setLastModified(crashTime));
/* Create an additional file in a folder to be filtered later. */
File otherFile = new File(minidumpSubfolder, "otherFile.txt");
long fakeCrashTime = new Date().getTime();
assertTrue(otherFile.createNewFile());
assertTrue(otherFile.setLastModified(fakeCrashTime));
/* Mock session context. */
mockStatic(SessionContext.class);
SessionContext sessionContext = mock(SessionContext.class);
when(SessionContext.getInstance()).thenReturn(sessionContext);
if (correlateSession) {
SessionContext.SessionInfo sessionInfo = mock(SessionContext.SessionInfo.class);
when(sessionContext.getSessionAt(crashTime)).thenReturn(sessionInfo);
when(sessionInfo.getAppLaunchTimestamp()).thenReturn(appStartTime);
}
/* Mock device info and ErrorLogHelper. */
mockStatic(ErrorLogHelper.class);
mockStatic(DeviceInfoHelper.class);
Device device = mock(Device.class);
when(DeviceInfoHelper.getDeviceInfo(any(Context.class))).thenReturn(mock(Device.class));
when(ErrorLogHelper.getStoredDeviceInfo(any(File.class))).thenReturn(hasDeviceInfo ? device : null);
when(ErrorLogHelper.getStoredUserInfo(any(File.class))).thenReturn(hasUserId ? mockUserId : null);
ErrorReport report = new ErrorReport();
File errorLogFile = mock(File.class);
when(errorLogFile.length()).thenReturn(1L);
when(ErrorLogHelper.getLastErrorLogFile()).thenReturn(errorLogFile);
when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[] { mock(File.class) });
when(ErrorLogHelper.getNewMinidumpFiles()).thenReturn(new File[] { minidumpSubfolder });
File pendingDir = mock(File.class);
Whitebox.setInternalState(pendingDir, "path", "");
when(ErrorLogHelper.getPendingMinidumpDirectory()).thenReturn(pendingDir);
when(ErrorLogHelper.getErrorReportFromErrorLog(any(ManagedErrorLog.class), anyString())).thenReturn(report);
when(ErrorLogHelper.parseLogFolderUuid(any(File.class))).thenReturn(UUID.randomUUID());
when(FileManager.read(any(File.class))).thenReturn("");
LogSerializer logSerializer = mock(LogSerializer.class);
ArgumentCaptor<Log> log = ArgumentCaptor.forClass(Log.class);
when(logSerializer.serializeLog(log.capture())).thenReturn("{}");
when(logSerializer.deserializeLog(anyString(), anyString())).thenAnswer(new Answer<ManagedErrorLog>() {
@Override
public ManagedErrorLog answer(InvocationOnMock invocation) {
com.microsoft.appcenter.crashes.ingestion.models.Exception mockException = new com.microsoft.appcenter.crashes.ingestion.models.Exception();
mockException.setType(MINIDUMP_FILE);
mockException.setMessage("message");
ManagedErrorLog log = mock(ManagedErrorLog.class);
when(log.getId()).thenReturn(UUID.randomUUID());
when(log.getException()).thenReturn(mockException);
return log;
}
});
/* Start crashes. */
Crashes crashes = Crashes.getInstance();
crashes.setLogSerializer(logSerializer);
crashes.onStarting(mAppCenterHandler);
crashes.onStarted(mock(Context.class), mock(Channel.class), "", null, true);
/* Verify timestamps on the crash log. */
assertTrue(Crashes.hasCrashedInLastSession().get());
assertTrue(log.getValue() instanceof ManagedErrorLog);
assertEquals(1, log.getAllValues().size());
assertNotEquals(new Date(fakeCrashTime), log.getValue().getTimestamp());
return (ManagedErrorLog) log.getValue();
}
use of com.microsoft.appcenter.crashes.model.ErrorReport in project mobile-center-sdk-android by Microsoft.
the class Crashes method processPendingErrors.
private void processPendingErrors() {
for (File logFile : ErrorLogHelper.getStoredErrorLogFiles()) {
AppCenterLog.debug(LOG_TAG, "Process pending error file: " + logFile);
String logfileContents = FileManager.read(logFile);
if (logfileContents != null) {
try {
ManagedErrorLog log = (ManagedErrorLog) mLogSerializer.deserializeLog(logfileContents, null);
UUID id = log.getId();
ErrorReport report = buildErrorReport(log);
if (report == null) {
removeAllStoredErrorLogFiles(id);
} else if (!mAutomaticProcessing || mCrashesListener.shouldProcess(report)) {
if (!mAutomaticProcessing) {
AppCenterLog.debug(LOG_TAG, "CrashesListener.shouldProcess returned true, continue processing log: " + id.toString());
}
mUnprocessedErrorReports.put(id, mErrorReportCache.get(id));
} else {
AppCenterLog.debug(LOG_TAG, "CrashesListener.shouldProcess returned false, clean up and ignore log: " + id.toString());
removeAllStoredErrorLogFiles(id);
}
} catch (JSONException e) {
AppCenterLog.error(LOG_TAG, "Error parsing error log. Deleting invalid file: " + logFile, e);
// noinspection ResultOfMethodCallIgnored
logFile.delete();
}
}
}
mHasReceivedMemoryWarningInLastSession = isMemoryRunningLevelWasReceived(SharedPreferencesManager.getInt(PREF_KEY_MEMORY_RUNNING_LEVEL, -1));
if (mHasReceivedMemoryWarningInLastSession) {
AppCenterLog.debug(LOG_TAG, "The application received a low memory warning in the last session.");
}
SharedPreferencesManager.remove(PREF_KEY_MEMORY_RUNNING_LEVEL);
/* If automatic processing is enabled. */
if (mAutomaticProcessing) {
/* Proceed to check if user confirmation is needed. */
sendCrashReportsOrAwaitUserConfirmation();
}
}
Aggregations