Example #1
0
        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);
        }
Example #2
0
        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));
        }
Example #3
0
        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;
 }
Example #7
0
        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());
        }
Example #8
0
        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);
        }
Example #9
0
        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());
        }
Example #10
0
        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.
        }
Example #11
0
        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
            }
        }
Example #12
0
        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()));
        }
Example #13
0
        /// <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);
            }
        }
Example #14
0
        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));
        }
Example #15
0
        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);
Example #18
0
        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());
        }
Example #21
0
 public void OnCrashCaptured(ManagedErrorLog errorLog)
 {
     _errorLog = errorLog;
     JoinExceptionAndLog();
 }