public void LastSessionCrashReportWhenMultipleCrashesAndRecentCrashIsInvalid() { var oldFile = Mock.Of <File>(); var recentFile = Mock.Of <File>(); var expectedFiles = new List <File> { oldFile, recentFile }; var mockErrorLogHelper = Mock.Of <ErrorLogHelper>(); ErrorLogHelper.Instance = mockErrorLogHelper; var expectedRecentErrorLog = new ManagedErrorLog { Id = Guid.NewGuid(), AppLaunchTimestamp = DateTime.Now, Timestamp = DateTime.Now }; var expectedOldErrorLog = new ManagedErrorLog { Id = Guid.NewGuid(), AppLaunchTimestamp = DateTime.Now.AddDays(-200), Timestamp = DateTime.Now.AddDays(-200), Device = new Microsoft.AppCenter.Ingestion.Models.Device() }; // Stub get/read error files. Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetErrorLogFiles()).Returns(expectedFiles); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(recentFile)).Returns(expectedRecentErrorLog); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(oldFile)).Returns(expectedOldErrorLog); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetStoredExceptionFile(expectedOldErrorLog.Id)).Returns(Mock.Of <File>()); // Start crashes service in an enabled state to initiate the process of getting the error report. Crashes.SetEnabledAsync(true).Wait(); Crashes.Instance.OnChannelGroupReady(_mockChannelGroup.Object, string.Empty); var hasCrashedInLastSession = Crashes.HasCrashedInLastSessionAsync().Result; var lastSessionErrorReport = Crashes.GetLastSessionCrashReportAsync().Result; // Verify results. Assert.IsNotNull(lastSessionErrorReport); Assert.AreEqual(expectedOldErrorLog.Id.ToString(), lastSessionErrorReport.Id); Assert.IsTrue(hasCrashedInLastSession); }
public void SaveErrorLogFileWithObfuscateUserName() { // Prepared data. Constants.UserName = "******"; var pathWithUserName = $"C:\\{Constants.UserName}\\some\\path"; var errorLog = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = 123, Exception = new Ingestion.Models.Exception { StackTrace = pathWithUserName } }; var expectedException = new System.Exception(pathWithUserName); // Call method. ErrorLogHelper.SaveErrorLogFiles(expectedException, errorLog); // Verify obfuscated data. var fileExceptionContent = ErrorLogHelper.GetStoredExceptionFile(errorLog.Id).ReadAllText(); var fileErrorContant = ErrorLogHelper.GetStoredErrorLogFile(errorLog.Id).ReadAllText(); Assert.IsFalse(fileErrorContant.Contains(Constants.UserName)); Assert.IsFalse(fileExceptionContent.Contains(Constants.UserName)); }
public void SaveBinaryExceptionDoesNotThrow(Type exceptionType) { var errorLog = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = 123 }; var exception = exceptionType.GetConstructor(Type.EmptyTypes)?.Invoke(null) as System.Exception; var errorLogFilename = errorLog.Id + ".json"; var serializedErrorLog = LogSerializer.Serialize(errorLog); var exceptionFilename = errorLog.Id + ".exception"; var mockDirectory = Mock.Of <Directory>(); var mockStream = new System.IO.MemoryStream(); Mock.Get(mockDirectory).Setup(d => d.FullName).Returns("Errors"); // Cause stream to fail writing mockStream.Dispose(); // Given we succeed saving log file but fail saving exception file. ErrorLogHelper.Instance._crashesDirectory = mockDirectory; // When we save files. ErrorLogHelper.SaveErrorLogFiles(exception, errorLog); // Then it does not throw. Mock.Get(mockDirectory).Verify(d => d.CreateFile(errorLogFilename, serializedErrorLog)); Mock.Get(mockDirectory).Verify(d => d.CreateFile(exceptionFilename, exception.ToString())); }
/// <summary> /// Saves an error log on disk. /// </summary> /// <param name="exception">The exception that caused the crash.</param> /// <param name="errorLog">The error log.</param> public virtual void InstanceSaveErrorLogFiles(System.Exception exception, ManagedErrorLog errorLog) { try { // Serialize main log file. var errorLogString = LogSerializer.Serialize(errorLog); var errorLogFileName = errorLog.Id + ErrorLogFileExtension; AppCenterLog.Debug(Crashes.LogTag, "Saving uncaught exception."); var directory = InstanceGetErrorStorageDirectory(); directory.CreateFile(errorLogFileName, errorLogString); AppCenterLog.Debug(Crashes.LogTag, $"Saved error log in directory {ErrorStorageDirectoryName} with name {errorLogFileName}."); try { // Serialize exception as raw stack trace. var exceptionFileName = errorLog.Id + ExceptionFileExtension; directory.CreateFile(exceptionFileName, exception.ToString()); AppCenterLog.Debug(Crashes.LogTag, $"Saved exception in directory {ErrorStorageDirectoryName} with name {exceptionFileName}."); } catch (System.Exception ex) { AppCenterLog.Warn(Crashes.LogTag, "Failed to serialize exception for client side inspection.", ex); } } catch (System.Exception ex) { AppCenterLog.Error(Crashes.LogTag, "Failed to save error log.", ex); } }
/// <summary> /// Creates a new error report. /// </summary> /// <param name="log">The managed error log.</param> /// <param name="stackTrace">The associated exception stack trace.</param> public ErrorReport(ManagedErrorLog log, string stackTrace) { Id = log.Id.ToString(); AppStartTime = new DateTimeOffset(log.AppLaunchTimestamp.Value); AppErrorTime = new DateTimeOffset(log.Timestamp.Value); Device = new Device(log.Device); StackTrace = stackTrace; }
/// <summary> /// Creates a new error report. /// </summary> /// <param name="log">The managed error log.</param> /// <param name="exception">The associated exception object.</param> public ErrorReport(ManagedErrorLog log, System.Exception exception) { Id = log.Id.ToString(); AppStartTime = new DateTimeOffset(log.AppLaunchTimestamp.Value); AppErrorTime = new DateTimeOffset(log.Timestamp.Value); Device = new Device(log.Device); Exception = exception; }
public void OnChannelGroupReadySendsFilteredPendingCrashes() { var mockErrorLogFile1 = Mock.Of <File>(); var mockErrorLogFile2 = Mock.Of <File>(); var mockExceptionFile1 = Mock.Of <File>(); var mockExceptionFile2 = Mock.Of <File>(); var mockErrorLogHelper = Mock.Of <ErrorLogHelper>(); ErrorLogHelper.Instance = mockErrorLogHelper; var expectedManagedErrorLog1 = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = ExpectedProcessId, AppLaunchTimestamp = DateTime.Now, Timestamp = DateTime.Now, Device = Mock.Of <Microsoft.AppCenter.Ingestion.Models.Device>() }; var expectedManagedErrorLog2 = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = ExpectedProcessId, AppLaunchTimestamp = DateTime.Now, Timestamp = DateTime.Now, Device = Mock.Of <Microsoft.AppCenter.Ingestion.Models.Device>() }; // Stub get/read/delete error files. Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetErrorLogFiles()).Returns(new List <File> { mockErrorLogFile1, mockErrorLogFile2 }); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(mockErrorLogFile1)).Returns(expectedManagedErrorLog1); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(mockErrorLogFile2)).Returns(expectedManagedErrorLog2); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetStoredExceptionFile(expectedManagedErrorLog1.Id)).Returns(mockExceptionFile1); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetStoredExceptionFile(expectedManagedErrorLog2.Id)).Returns(mockExceptionFile2); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadExceptionFile(mockExceptionFile1)).Returns(new System.Exception()); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadExceptionFile(mockExceptionFile2)).Returns(new System.Exception()); // Implement ShouldProcess to send only one of the 2 crashes. Crashes.ShouldProcessErrorReport += report => report.Id == expectedManagedErrorLog2.Id.ToString(); // Start Crashes. Crashes.SetEnabledAsync(true).Wait(); Crashes.Instance.OnChannelGroupReady(_mockChannelGroup.Object, string.Empty); Crashes.Instance.ProcessPendingErrorsTask.Wait(); // Verify only the should processed logs have been queued to the channel. _mockChannel.Verify(channel => channel.EnqueueAsync(It.Is <ManagedErrorLog>(log => log.Id == expectedManagedErrorLog1.Id && log.ProcessId == ExpectedProcessId)), Times.Never()); _mockChannel.Verify(channel => channel.EnqueueAsync(It.Is <ManagedErrorLog>(log => log.Id == expectedManagedErrorLog2.Id && log.ProcessId == ExpectedProcessId)), Times.Once()); // Either way, all log files are deleted. Mock.Get(ErrorLogHelper.Instance).Verify(instance => instance.InstanceRemoveStoredErrorLogFile(expectedManagedErrorLog1.Id), Times.Once()); Mock.Get(ErrorLogHelper.Instance).Verify(instance => instance.InstanceRemoveStoredErrorLogFile(expectedManagedErrorLog2.Id), Times.Once()); // We remove exception file if filtering out. Mock.Get(ErrorLogHelper.Instance).Verify(instance => instance.InstanceRemoveStoredExceptionFile(expectedManagedErrorLog1.Id), Times.Once()); // We keep the exception file until sent or failed to send when processed. See other tests for sent/failed to send that verify that. Mock.Get(ErrorLogHelper.Instance).Verify(instance => instance.InstanceRemoveStoredExceptionFile(expectedManagedErrorLog2.Id), Times.Never()); }
public void ReadErrorLogFile() { var errorLog = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = 123 }; var serializedErrorLog = LogSerializer.Serialize(errorLog); var mockFile = Mock.Of <File>(); Mock.Get(mockFile).Setup(file => file.ReadAllText()).Returns(serializedErrorLog); var actualContents = ErrorLogHelper.ReadErrorLogFile(mockFile); Assert.AreEqual(errorLog.Id, actualContents.Id); Assert.AreEqual(errorLog.ProcessId, actualContents.ProcessId); }
public void OnChannelGroupReadySendsAllPendingCrashesIfShouldProcessNotImplemented() { var mockErrorLogFile1 = Mock.Of <File>(); var mockErrorLogFile2 = Mock.Of <File>(); var mockExceptionFile1 = Mock.Of <File>(); var mockExceptionFile2 = Mock.Of <File>(); var mockErrorLogHelper = new Mock <ErrorLogHelper>(); ErrorLogHelper.Instance = mockErrorLogHelper.Object; var expectedManagedErrorLog1 = new ManagedErrorLog { Id = Guid.NewGuid(), Timestamp = DateTime.Now, AppLaunchTimestamp = DateTime.Now, Device = Mock.Of <Microsoft.AppCenter.Ingestion.Models.Device>(), ProcessId = ExpectedProcessId }; var expectedManagedErrorLog2 = new ManagedErrorLog { Id = Guid.NewGuid(), Timestamp = DateTime.Now, AppLaunchTimestamp = DateTime.Now, Device = Mock.Of <Microsoft.AppCenter.Ingestion.Models.Device>(), ProcessId = ExpectedProcessId }; // Stub get/read/delete error files. mockErrorLogHelper.Setup(instance => instance.InstanceGetErrorLogFiles()).Returns(new List <File> { mockErrorLogFile1, mockErrorLogFile2 }); mockErrorLogHelper.Setup(instance => instance.InstanceReadErrorLogFile(mockErrorLogFile1)).Returns(expectedManagedErrorLog1); mockErrorLogHelper.Setup(instance => instance.InstanceReadErrorLogFile(mockErrorLogFile2)).Returns(expectedManagedErrorLog2); mockErrorLogHelper.Setup(instance => instance.InstanceGetStoredExceptionFile(expectedManagedErrorLog1.Id)).Returns(mockExceptionFile1); mockErrorLogHelper.Setup(instance => instance.InstanceGetStoredExceptionFile(expectedManagedErrorLog2.Id)).Returns(mockExceptionFile2); mockErrorLogHelper.Setup(instance => instance.InstanceReadExceptionFile(mockExceptionFile1)).Returns(new System.Exception()); mockErrorLogHelper.Setup(instance => instance.InstanceReadExceptionFile(mockExceptionFile2)).Returns(new System.Exception()); Crashes.SetEnabledAsync(true).Wait(); Crashes.Instance.OnChannelGroupReady(_mockChannelGroup.Object, string.Empty); Crashes.Instance.ProcessPendingErrorsTask.Wait(); // Verify crashes logs have been queued to the channel. _mockChannel.Verify(channel => channel.EnqueueAsync(It.Is <ManagedErrorLog>(log => log.Id == expectedManagedErrorLog1.Id && log.ProcessId == ExpectedProcessId)), Times.Once()); _mockChannel.Verify(channel => channel.EnqueueAsync(It.Is <ManagedErrorLog>(log => log.Id == expectedManagedErrorLog2.Id && log.ProcessId == ExpectedProcessId)), Times.Once()); mockErrorLogHelper.Verify(instance => instance.InstanceRemoveStoredErrorLogFile(expectedManagedErrorLog1.Id), Times.Once()); mockErrorLogHelper.Verify(instance => instance.InstanceRemoveStoredErrorLogFile(expectedManagedErrorLog2.Id), Times.Once()); }
public void SaveErrorLogFileDoesNotThrow(Type exceptionType) { // Use reflection to create an exception of the given C# type. var exception = exceptionType.GetConstructor(Type.EmptyTypes)?.Invoke(null) as System.Exception; var errorLog = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = 123 }; var mockDirectory = Mock.Of <Directory>(); ErrorLogHelper.Instance._crashesDirectory = mockDirectory; Mock.Get(mockDirectory).Setup(d => d.EnumerateFiles(It.IsAny <string>())).Throws(exception); ErrorLogHelper.SaveErrorLogFiles(null, errorLog); // No exception should be thrown. }
public void VerifyManagedErrorLog() { try { throw new System.Exception("test exception"); } catch (System.Exception e) { // TODO want to check binaries and frames, but this won't be available unless .net native is used. // is there a way to check that? Or should it fail unless on .net native? ManagedErrorLog managedErrorLog = ErrorLogHelper.CreateErrorLog(e); Assert.AreEqual(managedErrorLog.AppLaunchTimestamp.Value.Kind, DateTimeKind.Utc); #if RELEASE Assert.IsNotNull(managedErrorLog.Exception.Frames); Assert.IsTrue(managedErrorLog.Exception.Frames.Count > 0); Assert.IsNotNull(managedErrorLog.Binaries); Assert.IsTrue(managedErrorLog.Binaries.Count > 0); #endif } }
public void SaveErrorLogFiles() { var errorLog = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = 123 }; var expectedException = new System.Exception("test"); var errorLogFilename = errorLog.Id + ".json"; var serializedErrorLog = LogSerializer.Serialize(errorLog); var exceptionFilename = errorLog.Id + ".exception"; var mockStream = new System.IO.MemoryStream(); var mockDirectory = Mock.Of <Directory>(); ErrorLogHelper.Instance._crashesDirectory = mockDirectory; ErrorLogHelper.SaveErrorLogFiles(expectedException, errorLog); Mock.Get(mockDirectory).Verify(d => d.CreateFile(errorLogFilename, serializedErrorLog)); Mock.Get(mockDirectory).Verify(d => d.CreateFile(exceptionFilename, expectedException.ToString())); }
/// <summary> /// Saves an error log on disk. /// </summary> /// <param name="exception">The exception that caused the crash.</param> /// <param name="errorLog">The error log.</param> public virtual void InstanceSaveErrorLogFiles(System.Exception exception, ManagedErrorLog errorLog) { try { // Serialize main log file. var errorLogString = LogSerializer.Serialize(errorLog); var errorLogFileName = errorLog.Id + ErrorLogFileExtension; AppCenterLog.Debug(Crashes.LogTag, "Saving uncaught exception."); var directory = InstanceGetErrorStorageDirectory(); directory.CreateFile(errorLogFileName, errorLogString); AppCenterLog.Debug(Crashes.LogTag, $"Saved error log in directory {ErrorStorageDirectoryName} with name {errorLogFileName}."); // Serialize binary exception. var exceptionFileName = errorLog.Id + ExceptionFileExtension; SaveExceptionFile(directory, exceptionFileName, exception); } catch (System.Exception ex) { AppCenterLog.Error(Crashes.LogTag, "Failed to save error log.", ex); } }
public void SaveBinaryExceptionDoesNotThrow(Type exceptionType) { var errorLog = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = 123 }; var exception = exceptionType.GetConstructor(Type.EmptyTypes)?.Invoke(null) as System.Exception; var errorLogFilename = errorLog.Id + ".json"; var serializedErrorLog = LogSerializer.Serialize(errorLog); var exceptionFilename = errorLog.Id + ".exception"; var mockDirectory = Mock.Of <Directory>(); var mockStream = new System.IO.MemoryStream(); Mock.Get(mockDirectory).Setup(d => d.FullName).Returns("Errors"); var expectedFullFileName = $"Errors\\{exceptionFilename}"; string actualFullFileName = null; System.IO.FileMode?actualFileMode = null; // Cause stream to fail writing mockStream.Dispose(); // Given we succeed saving log file but fail saving exception file. ErrorLogHelper.Instance._crashesDirectory = mockDirectory; ErrorLogHelper.Instance.NewFileStream = (name, mode) => { actualFullFileName = name; actualFileMode = mode; return(mockStream); }; // When we save files. ErrorLogHelper.SaveErrorLogFiles(exception, errorLog); // Then it does not throw. Assert.AreEqual(expectedFullFileName, actualFullFileName); Assert.AreEqual(System.IO.FileMode.Create, actualFileMode); Mock.Get(mockDirectory).Verify(d => d.CreateFile(errorLogFilename, serializedErrorLog)); }
public void SaveErrorLogFiles() { var errorLog = new ManagedErrorLog { Id = Guid.NewGuid(), ProcessId = 123 }; var expectedException = new System.Exception("test"); var errorLogFilename = errorLog.Id + ".json"; var serializedErrorLog = LogSerializer.Serialize(errorLog); var exceptionFilename = errorLog.Id + ".exception"; var mockStream = new System.IO.MemoryStream(); var mockDirectory = Mock.Of <Directory>(); Mock.Get(mockDirectory).Setup(d => d.FullName).Returns("Errors"); var expectedFullFileName = $"Errors\\{exceptionFilename}"; string actualFullFileName = null; System.IO.FileMode?actualFileMode = null; ErrorLogHelper.Instance._crashesDirectory = mockDirectory; ErrorLogHelper.Instance.NewFileStream = (name, mode) => { actualFullFileName = name; actualFileMode = mode; return(mockStream); }; ErrorLogHelper.SaveErrorLogFiles(expectedException, errorLog); Assert.AreEqual(expectedFullFileName, actualFullFileName); Assert.AreEqual(System.IO.FileMode.Create, actualFileMode); Mock.Get(mockDirectory).Verify(d => d.CreateFile(errorLogFilename, serializedErrorLog)); // Check what was serialized. var actualException = new BinaryFormatter().Deserialize(new System.IO.MemoryStream(mockStream.ToArray())); Assert.IsInstanceOfType(actualException, expectedException.GetType()); Assert.AreEqual(expectedException.Message, ((System.Exception)actualException).Message); }
public void ProcessPendingCrashesIgnoresNullErrorAttachment() { var mockFile1 = Mock.Of <File>(); var mockErrorLogHelper = Mock.Of <ErrorLogHelper>(); ErrorLogHelper.Instance = mockErrorLogHelper; var expectedManagedErrorLog1 = new ManagedErrorLog { Id = Guid.NewGuid(), Timestamp = DateTime.Now, AppLaunchTimestamp = DateTime.Now, Device = new Microsoft.AppCenter.Ingestion.Models.Device() }; // Stub get/read/delete error files. Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetErrorLogFiles()).Returns(new List <File> { mockFile1 }); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(mockFile1)).Returns(expectedManagedErrorLog1); // Implement attachments callback. Crashes.GetErrorAttachments = errorReport => { if (errorReport.Id == expectedManagedErrorLog1.Id.ToString()) { return(new List <ErrorAttachmentLog> { null }); } return(null); }; Crashes.SetEnabledAsync(true).Wait(); Crashes.Instance.OnChannelGroupReady(_mockChannelGroup.Object, string.Empty); Crashes.Instance.ProcessPendingErrorsTask.Wait(); // Verify nothing has been enqueued. _mockChannel.Verify(channel => channel.EnqueueAsync(It.IsAny <ErrorAttachmentLog>()), Times.Never()); }
/// <summary> /// Saves an error log and an exception on disk. /// </summary> /// <param name="exception">The exception that caused the crash.</param> /// <param name="errorLog">The error log.</param> public static void SaveErrorLogFiles(System.Exception exception, ManagedErrorLog errorLog) => Instance.InstanceSaveErrorLogFiles(exception, errorLog);
public void VerifyAppLaunchTimestampUTC() { ManagedErrorLog managedErrorLog = ErrorLogHelper.CreateErrorLog(new System.Exception("Test Exception")); Assert.AreEqual(managedErrorLog.AppLaunchTimestamp.Value.Kind, DateTimeKind.Utc); }
public void ProcessPendingCrashesSendsErrorAttachment() { var mockFile1 = Mock.Of <File>(); var mockFile2 = Mock.Of <File>(); var mockExceptionFile1 = Mock.Of <File>(); var mockExceptionFile2 = Mock.Of <File>(); var mockErrorLogHelper = Mock.Of <ErrorLogHelper>(); ErrorLogHelper.Instance = mockErrorLogHelper; var lastExpectedManagedErrorLog = new ManagedErrorLog { Id = Guid.NewGuid(), Timestamp = DateTime.Now, AppLaunchTimestamp = DateTime.Now, Device = new Microsoft.AppCenter.Ingestion.Models.Device() }; var olderExpectedManagedErrorLog = new ManagedErrorLog { Id = Guid.NewGuid(), Timestamp = lastExpectedManagedErrorLog.Timestamp.Value.AddDays(-1), AppLaunchTimestamp = lastExpectedManagedErrorLog.Timestamp.Value.AddDays(-1), Device = new Microsoft.AppCenter.Ingestion.Models.Device() }; var validErrorAttachment = GetValidErrorAttachmentLog(); var expectedException = new ArgumentOutOfRangeException(); // Stub get/read/delete error files. Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetErrorLogFiles()).Returns(new List <File> { mockFile1, mockFile2 }); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(mockFile1)).Returns(lastExpectedManagedErrorLog); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(mockFile2)).Returns(olderExpectedManagedErrorLog); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetStoredExceptionFile(lastExpectedManagedErrorLog.Id)).Returns(mockExceptionFile1); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetStoredExceptionFile(olderExpectedManagedErrorLog.Id)).Returns(mockExceptionFile2); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadExceptionFile(mockExceptionFile1)).Returns(expectedException.ToString()); // Implement attachments callback. string actualException = null; Crashes.GetErrorAttachments = errorReport => { if (errorReport.Id == lastExpectedManagedErrorLog.Id.ToString()) { actualException = errorReport.StackTrace; return(new List <ErrorAttachmentLog> { validErrorAttachment }); } return(null); }; Crashes.SetEnabledAsync(true).Wait(); Crashes.Instance.OnChannelGroupReady(_mockChannelGroup.Object, string.Empty); Crashes.Instance.ProcessPendingErrorsTask.Wait(); // Verify attachment log has been queued to the channel. (And only one attachment log). _mockChannel.Verify(channel => channel.EnqueueAsync(validErrorAttachment), Times.Once()); _mockChannel.Verify(channel => channel.EnqueueAsync(It.IsAny <ErrorAttachmentLog>()), Times.Once()); // Verify that the attachment has been modified with the right fields. Assert.AreEqual(lastExpectedManagedErrorLog.Id, validErrorAttachment.ErrorId); Assert.AreNotEqual(Guid.Empty, validErrorAttachment.ErrorId); // Verify exception was attached to report in the callback. Assert.AreEqual(expectedException.ToString(), actualException); }
public void ProcessPendingCrashesIgnoresInvalidErrorAttachmentWithoutCrashing() { var mockFile1 = Mock.Of <File>(); var mockFile2 = Mock.Of <File>(); var mockExceptionFile1 = Mock.Of <File>(); var mockExceptionFile2 = Mock.Of <File>(); var mockErrorLogHelper = Mock.Of <ErrorLogHelper>(); ErrorLogHelper.Instance = mockErrorLogHelper; var expectedManagedErrorLog1 = new ManagedErrorLog { Id = Guid.NewGuid(), Timestamp = DateTime.Now, AppLaunchTimestamp = DateTime.Now, Device = new Microsoft.AppCenter.Ingestion.Models.Device() }; var expectedManagedErrorLog2 = new ManagedErrorLog { Id = Guid.NewGuid(), Timestamp = DateTime.Now, AppLaunchTimestamp = DateTime.Now, Device = new Microsoft.AppCenter.Ingestion.Models.Device() }; // Stub get/read/delete error files. Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetErrorLogFiles()).Returns(new List <File> { mockFile1, mockFile2 }); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(mockFile1)).Returns(expectedManagedErrorLog1); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceReadErrorLogFile(mockFile2)).Returns(expectedManagedErrorLog2); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetStoredExceptionFile(expectedManagedErrorLog1.Id)).Returns(mockExceptionFile1); Mock.Get(ErrorLogHelper.Instance).Setup(instance => instance.InstanceGetStoredExceptionFile(expectedManagedErrorLog2.Id)).Returns(mockExceptionFile2); // Create two valid and one invalid attachment and one huge attachment (discarded but otherwise valid). var invalidErrorAttachment1 = new ErrorAttachmentLog(); var validErrorAttachmentWithoutDevice = new ErrorAttachmentLog() { ContentType = "ContentType", ErrorId = Guid.NewGuid(), Data = new byte[] { 1 }, Id = Guid.NewGuid() }; var validErrorAttachment1 = GetValidErrorAttachmentLog(); var validErrorAttachment2 = GetValidErrorAttachmentLog(); var hugeAttachment = GetValidErrorAttachmentLog(); hugeAttachment.Data = new byte[7 * 1024 * 1024 + 1]; // Implement attachments callback. Crashes.GetErrorAttachments = errorReport => { if (errorReport.Id == expectedManagedErrorLog1.Id.ToString()) { return(new List <ErrorAttachmentLog> { invalidErrorAttachment1, validErrorAttachmentWithoutDevice, validErrorAttachment1, hugeAttachment }); } return(new List <ErrorAttachmentLog> { validErrorAttachment2 }); }; Crashes.SetEnabledAsync(true).Wait(); Crashes.Instance.OnChannelGroupReady(_mockChannelGroup.Object, string.Empty); Crashes.Instance.ProcessPendingErrorsTask.Wait(); // Verify all valid attachment logs has been queued to the channel, but not invalid one. _mockChannel.Verify(channel => channel.EnqueueAsync(invalidErrorAttachment1), Times.Never()); _mockChannel.Verify(channel => channel.EnqueueAsync(hugeAttachment), Times.Never()); _mockChannel.Verify(channel => channel.EnqueueAsync(validErrorAttachmentWithoutDevice), Times.Once()); _mockChannel.Verify(channel => channel.EnqueueAsync(validErrorAttachment1), Times.Once()); _mockChannel.Verify(channel => channel.EnqueueAsync(validErrorAttachment2), Times.Once()); }
public void OnCrashCaptured(ManagedErrorLog errorLog) { _errorLog = errorLog; JoinExceptionAndLog(); }