public async void createAValidListOfTemporaryExposureKeys_HaveDateGap_AllShouldBeKept() { SystemTime.ResetDateTime(); // Create keys ExposureKeyModel tek1 = new ExposureKeyModel(new byte[1], SystemTime.Now(), TimeSpan.FromDays(1), RiskLevel.Medium); ExposureKeyModel tek2 = new ExposureKeyModel(new byte[2], SystemTime.Now().AddDays(-1), TimeSpan.FromDays(1), RiskLevel.Medium); ExposureKeyModel tek3 = new ExposureKeyModel(new byte[3], SystemTime.Now().AddDays(-3), TimeSpan.FromDays(1), RiskLevel.Medium); // Process a list of copies IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>() { CopyTek(tek1), CopyTek(tek2), CopyTek(tek3) }; IEnumerable <ExposureKeyModel> processedKeys = UploadDiagnosisKeysHelper.CreateAValidListOfTemporaryExposureKeys(temporaryExposureKeys); // No keys should be filtered out Assert.Equal(processedKeys.Count(), temporaryExposureKeys.Count()); Assert.True(ContainsTek(tek3, processedKeys)); Assert.False((await _logManager.GetLogs(10)).Any()); }
public async void LogMessage_CreateModelsStoreInDatabasePullFromDatabaseConvertToDtos_DtosShouldContainCorrectValues() { DependencyInjectionConfig.Init(); // Clear the mock database ILoggingManager logManager = ServiceLocator.Current.GetInstance <ILoggingManager>(); await logManager.DeleteAll(); // Log models to the mock database LogUtils.LogMessage(Enums.LogSeverity.INFO, "My message"); LogUtils.LogMessage(Enums.LogSeverity.WARNING, "My message", "Additional info"); LogUtils.LogMessage(Enums.LogSeverity.ERROR, ""); //// Wait for async IO operations //await Task.Delay(1000); // Pull models from the mock database List <LogSQLiteModel> logSqliteModels = await logManager.GetLogs(10); Assert.Equal(3, logSqliteModels.Count); // Convert models to DTOs IEnumerable <LogDTO> logDtos = logSqliteModels.Select(x => new LogDTO(x)); //Check that DTOs correspond with arguments to LogMessage() foreach (LogDTO logDto in logDtos) { if (logDto.Severity == Enums.LogSeverity.INFO.ToString()) { Assert.Equal("My message", logDto.Description); } else if (logDto.Severity == Enums.LogSeverity.WARNING.ToString()) { Assert.Equal("My message", logDto.Description); Assert.Equal("Additional info (GPS: Mock version)", logDto.AdditionalInfo); } else if (logDto.Severity == Enums.LogSeverity.ERROR.ToString()) { Assert.Equal("", logDto.Description); } else { throw new Exception("At least one of the ifs is expected to be true"); } } }
public static async void SendAllLogs() { UpdateCorrelationId(null); ILoggingManager manager = ServiceLocator.Current.GetInstance <ILoggingManager>(); try { bool allLogsSent = false; while (!allLogsSent) { List <LogSQLiteModel> logs = await manager.GetLogs(_numLogsToSendAtATime); if (logs == null || !logs.Any()) { break; } // Try to post logs to the server List <LogDTO> dto = logs.Select(l => new LogDTO(l)).ToList(); bool success = await(new LoggingService()).PostAllLogs(dto); // If posting succeeded, delete them if (success) { await manager.DeleteLogs(logs); } // Else, we must try to send them another time. // Also make sure we don't store too many logs because sending keeps failing else { DeleteLogsIfTooMany(); break; } allLogsSent = logs.Count < _numLogsToSendAtATime; } } catch (Exception e) { System.Diagnostics.Debug.Print($"{nameof(LogUtils)}.{nameof(SendAllLogs)}: Failed to send logs. Wiping DB to prevent deadlock"); System.Diagnostics.Debug.Print(e.ToString()); await manager.DeleteAll(); } }
private static async void DeleteLogsIfTooMany() { ILoggingManager manager = ServiceLocator.Current.GetInstance <ILoggingManager>(); bool tooManyPersistedLogs = true; while (tooManyPersistedLogs) { // GetLogs gives the earliest logs List <LogSQLiteModel> logs = await manager.GetLogs(_maxNumOfPersistedLogsOnSendError * 2); tooManyPersistedLogs = logs.Count() > _maxNumOfPersistedLogsOnSendError; if (tooManyPersistedLogs) { int atLeastNLogsTooMany = logs.Count() - _maxNumOfPersistedLogsOnSendError; List <LogSQLiteModel> logsToDelete = logs.Take(atLeastNLogsTooMany).ToList(); await manager.DeleteLogs(logsToDelete); } } }
public async void LogException_CreateModelsStoreInDatabasePullFromDatabaseConvertToDtos_DtosShouldContainCorrectValues() { // Clear the mock database ILoggingManager logManager = ServiceLocator.Current.GetInstance <ILoggingManager>(); await logManager.DeleteAll(); // Log models to the mock database LogUtils.LogException(Enums.LogSeverity.INFO, new Exception("Hello"), "My context description"); LogUtils.LogException(Enums.LogSeverity.WARNING, new Exception("Goodbye"), "Context decription", "Additional info"); // Pull models from the mock database List <LogSQLiteModel> logSqliteModels = await logManager.GetLogs(10); Assert.Equal(2, logSqliteModels.Count); // Convert models to DTOs IEnumerable <LogDTO> logDtos = logSqliteModels.Select(x => new LogDTO(x)); // Check that DTOs correspond with arguments to LogMessage() foreach (LogDTO logDto in logDtos) { if (logDto.Severity == Enums.LogSeverity.INFO.ToString()) { Assert.Equal("Hello", logDto.ExceptionMessage); } else if (logDto.Severity == Enums.LogSeverity.WARNING.ToString()) { // (GPS: Mock version) is added in the Logdetails constructor Assert.Equal("Additional info (GPS: Mock version)", logDto.AdditionalInfo); } else { throw new Exception("At least one of the ifs is expected to be true"); } } }
[InlineData("2020-08-26 00:30 +2")] //This is still the 25th in UTC. public async void PullKeys_FetchZipsForMultipleDays_NoErrors(string todayString) { int lastBatchNumFromHeader = 5; //Given there are 3 batches for day1, 3 batches for day 2, 3 batches for day3 ExposureNotificationWebService mockedService = _helper.MockedService(new List <PullKeysMockData> { new PullKeysMockData(day1, 1).HttpStatusCode(200).WithLastBatchHeader(1).WithMoreBatchesExistHeader(true), new PullKeysMockData(day1, 2).HttpStatusCode(200).WithLastBatchHeader(2).WithMoreBatchesExistHeader(true), new PullKeysMockData(day1, 3).HttpStatusCode(200).WithLastBatchHeader(3).WithMoreBatchesExistHeader(false), new PullKeysMockData(day1, 4).HttpStatusCode(204), new PullKeysMockData(day2, 1).HttpStatusCode(200).WithLastBatchHeader(1).WithMoreBatchesExistHeader(true), new PullKeysMockData(day2, 2).HttpStatusCode(200).WithLastBatchHeader(2).WithMoreBatchesExistHeader(true), new PullKeysMockData(day2, 3).HttpStatusCode(200).WithLastBatchHeader(3).WithMoreBatchesExistHeader(false), new PullKeysMockData(day2, 4).HttpStatusCode(204), new PullKeysMockData(day3, 1).HttpStatusCode(200).WithLastBatchHeader(1).WithMoreBatchesExistHeader(true), new PullKeysMockData(day3, 2).HttpStatusCode(200).WithLastBatchHeader(2).WithMoreBatchesExistHeader(true), new PullKeysMockData(day3, 3).HttpStatusCode(200).WithLastBatchHeader(lastBatchNumFromHeader).WithMoreBatchesExistHeader(false), new PullKeysMockData(day3, 4).HttpStatusCode(204), }); //Given today is day3 DateTime newToday = DateTime.ParseExact(todayString, "yyyy-MM-dd HH:mm z", CultureInfo.GetCultureInfo("nn-NO")); SystemTime.SetDateTime(newToday); //Given last time we pulled was day3, batch2. _helper.SetLastPulledDate(day1, 2); //When pulling keys _developerTools.StartPullHistoryRecord(); List <string> zipLocations = (await new ZipDownloader().PullNewKeys(mockedService, new CancellationToken())).ToList(); //Then we pull the rest from day 1, all from day 2, and all from day 3 Assert.Equal(7, zipLocations.Count); //The last batch number is saved from header Assert.Equal(lastBatchNumFromHeader, LocalPreferencesHelper.LastPullKeysBatchNumberNotSubmitted); //And no errors were logged Assert.False((await _logManager.GetLogs(10)).Any()); //The history is stored for dev tools: string expected = $"Pulled the following keys (batches) at {newToday.ToUniversalTime().ToString("yyyy-MM-dd HH:mm")} UTC:\n" + $"* 2020-08-23_3_no.zip: 200 OK\n" + $"* 2020-08-24_1_no.zip: 200 OK\n" + $"* 2020-08-24_2_no.zip: 200 OK\n" + $"* 2020-08-24_3_no.zip: 200 OK\n" + $"* 2020-08-25_1_no.zip: 200 OK\n" + $"* 2020-08-25_2_no.zip: 200 OK\n" + $"* 2020-08-25_3_no.zip: 200 OK"; Assert.Equal(expected, _developerTools.LastPullHistory); Assert.Equal(expected, _developerTools.AllPullHistory); }
public async void LogApiError_CreateModelsStoreInDatabasePullFromDatabaseConvertToDtos_DtosShouldContainCorrectValues() { // Clear the mock database ILoggingManager logManager = ServiceLocator.Current.GetInstance <ILoggingManager>(); await logManager.DeleteAll(); // Log apiResponse1 string urlPrefix = Conf.URL_PREFIX; ApiResponse apiResponse1 = new ApiResponse(urlPrefix + "HELLO!", HttpMethod.Get); apiResponse1.StatusCode = 200; IEnumerable <ExposureKeyModel> temporaryExposureKeys = new List <ExposureKeyModel>() { new ExposureKeyModel(new byte[5], DateTimeOffset.FromUnixTimeSeconds(1234), TimeSpan.FromHours(24), RiskLevel.Medium), new ExposureKeyModel(new byte[5], DateTimeOffset.FromUnixTimeSeconds(1234), TimeSpan.FromHours(24), RiskLevel.Medium), new ExposureKeyModel(new byte[5], DateTimeOffset.FromUnixTimeSeconds(1234), TimeSpan.FromHours(24), RiskLevel.Medium), }; string redactedKeysJson = RedactedTekListHelper.CreateRedactedTekList(temporaryExposureKeys); LogUtils.LogApiError(Enums.LogSeverity.INFO, apiResponse1, false, redactedKeysJson); //Added Mockversion to test if version is set correctly in the Logdevicedetails redactedKeysJson += " (GPS: Mock version)"; // Log apiResponse2 ApiResponse apiResponse2 = new ApiResponse(urlPrefix + "GOODBYE!", HttpMethod.Get); apiResponse2.StatusCode = 201; LogUtils.LogApiError(Enums.LogSeverity.WARNING, apiResponse2, true); // Pull the two log models from the mock database List <LogSQLiteModel> logSqliteModels = await logManager.GetLogs(10); Assert.Equal(2, logSqliteModels.Count); // Convert the models to DTOs IEnumerable <LogDTO> logDtos = logSqliteModels.Select(x => new LogDTO(x)); // Check that the DTOs contain the expected values foreach (LogDTO logDto in logDtos) { // apiReponse1 string apiVersion = $"/v{Conf.APIVersion}/"; if (logDto.Severity == Enums.LogSeverity.INFO.ToString()) { Assert.Equal(apiVersion + "HELLO!", logDto.Api); Assert.Equal(200, logDto.ApiErrorCode); // We expect AdditionalInfo to consist of redactedKeysJson, after it's been processed with RedactText Assert.Equal(RedactText(redactedKeysJson), logDto.AdditionalInfo); // This part is just to double check redaction of key data works // Before redaction, the key data is a byte array of size 5, which is shown as "AAAAAAA=" // After redaction we do not want this to be in the string string nonRedactedKeysJson = JsonConvert.SerializeObject(temporaryExposureKeys, BaseWebService.JsonSerializerSettings); Assert.Contains("AAAAAAA=", nonRedactedKeysJson); Assert.DoesNotContain("AAAAAAA=", redactedKeysJson); } // apiResponse2 else if (logDto.Severity == Enums.LogSeverity.WARNING.ToString()) { Assert.Equal(apiVersion + "GOODBYE!", logDto.Api); Assert.Equal(201, logDto.ApiErrorCode); } // Should never be reached else { throw new Exception("At least one of the ifs is expected to be true"); } } }