public async Task VerifyMetricForGaps(Metrics type, bool shouldSucceed) { // Arrange var metric = new Metric { Type = type.AsInt(), Source = "the-source" }; var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); // Act & Assert if (shouldSucceed) { // It will pass metric check, will try to interact with data layer and fail await Assert.ThrowsAsync <NullReferenceException>( async() => await discrepancyService.FindGapsAsync(metric, new TimeSpan()) ); } else { await Assert.ThrowsAsync <ArgumentException>( async() => await discrepancyService.FindGapsAsync(metric, new TimeSpan()) ); } }
public void PingFailureNoData() { // Arrange var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); // Act var actual = discrepancyService .FindPingFailuresFromDataPoints( new List <PingDataPoint>(), new PingSetting { MaxFailures = 1 }, new Metric { Type = Metrics.Ping.AsInt(), Source = "the-source" } ); // Assert Assert.Empty(actual); }
public async Task ResolvesGapInData(bool shouldResolve) { // Arrange var input = new List <Discrepancy> { new Discrepancy { DateFirstOffense = DateTime.UtcNow, Type = DiscrepancyType.GapInData, MetricSource = "the-source-1", MetricType = Metrics.CpuLoad, } }; var metric = new Metric { Type = Metrics.CpuLoad.AsInt(), Source = "the-source-1" }; var context = _serviceProvider.GetRequiredService <IDataContext>(); await context.Metrics.AddAsync(metric); await context.NumericDataPoints.AddRangeAsync( new NumericDataPoint { Metric = metric, Value = 50, Timestamp = DateTime.UtcNow.AddMinutes(-2) }, new NumericDataPoint { Metric = metric, Value = 92, Timestamp = DateTime.UtcNow.AddMinutes(shouldResolve ? 1 : -1) } ); await context.SaveChangesAsync(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); // Act var actual = await discrepancyService.FindResolvedDiscrepanciesAsync(input); // Assert if (shouldResolve) { Assert.NotEmpty(actual); Assert.Equal(input, actual); } else { Assert.Empty(actual); } }
public void MultipleGapsInData() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Gaps:MaxDifference"]) .Returns("60"); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, mockConfig.Object ); var input = new List <DateTime>() { DateTime.UtcNow - new TimeSpan(0, 0, 0), DateTime.UtcNow - new TimeSpan(0, 1, 0), DateTime.UtcNow - new TimeSpan(0, 4, 0), DateTime.UtcNow - new TimeSpan(0, 5, 0), DateTime.UtcNow - new TimeSpan(0, 7, 0) }; var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = input[2], Type = DiscrepancyType.GapInData, MetricType = Metrics.CpuLoad, MetricSource = "the-source" }, new Discrepancy { DateFirstOffense = input[4], Type = DiscrepancyType.GapInData, MetricType = Metrics.CpuLoad, MetricSource = "the-source" } } .OrderBy(d => d.DateFirstOffense); // Act var actual = discrepancyService .FindGapsInDataPoints( input, new Metric { Type = Metrics.CpuLoad.AsInt(), Source = "the-source" } ) .OrderBy(d => d.DateFirstOffense); // Assert Assert.Equal(expected, actual); }
public async Task ResolvesLowHealth(bool shouldResolve) { // Arrange var input = new List <Discrepancy> { new Discrepancy { DateFirstOffense = DateTime.UtcNow, Type = DiscrepancyType.LowHealth, MetricSource = "the-source-1", MetricType = Metrics.Health, } }; var metric = new Metric { Type = Metrics.Health.AsInt(), Source = "the-source-1" }; var context = _serviceProvider.GetRequiredService <IDataContext>(); await context.Metrics.AddAsync(metric); await context.HealthReports.AddRangeAsync( DiscrepancyServiceTest.GenerateHealthReport(true, metric, DateTime.UtcNow.AddMinutes(-1)), DiscrepancyServiceTest.GenerateHealthReport(false, metric, DateTime.UtcNow.AddMinutes(1)), DiscrepancyServiceTest.GenerateHealthReport(false, metric, DateTime.UtcNow.AddMinutes(2)), DiscrepancyServiceTest.GenerateHealthReport(shouldResolve, metric, DateTime.UtcNow.AddMinutes(3)) ); await context.SaveChangesAsync(); var config = new Mock <IConfiguration>(); config .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Health:Threshold"]) .Returns(99.ToString()); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, new Mock <INotificationService>().Object, config.Object ); // Act var actual = await discrepancyService.FindResolvedDiscrepanciesAsync(input); // Assert if (shouldResolve) { Assert.NotEmpty(actual); Assert.Equal(input, actual); } else { Assert.Empty(actual); } }
public void SingleLowHealthInData() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Health:Threshold"]) .Returns(90.ToString()); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Health:MaxFailures"]) .Returns(2.ToString()); // 3 is discrepancy var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, mockConfig.Object ); var input = new List <HealthReport>() { ConfigureHealthReport(95, DateTime.UtcNow), // good ConfigureHealthReport(89, DateTime.UtcNow.AddMinutes(-1)), // bad ConfigureHealthReport(70, DateTime.UtcNow.AddMinutes(-2)), // bad ConfigureHealthReport(75, DateTime.UtcNow.AddMinutes(-3)), // bad ConfigureHealthReport(100, DateTime.UtcNow.AddMinutes(-4)), // good ConfigureHealthReport(56, DateTime.UtcNow.AddMinutes(-5)), // bad ConfigureHealthReport(69, DateTime.UtcNow.AddMinutes(-6)), // bad ConfigureHealthReport(99, DateTime.UtcNow.AddMinutes(-7)), // good }; var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = input[3].Timestamp, Type = DiscrepancyType.LowHealth, MetricType = Metrics.Health, MetricSource = "the-source" } }; // Act var actual = discrepancyService .FindLowHealthInDataPoints( input, new Metric { Type = Metrics.Health.AsInt(), Source = "the-source" } ); // Assert Assert.Equal(expected, actual); }
public void NoPingFailures() { // Arrange var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); var input = new List <PingDataPoint>() { new PingDataPoint { HttpStatusCode = HttpStatusCode.OK.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 0, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.OK.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 1, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.ServiceUnavailable.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 2, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.OK.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 3, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.OK.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 4, 0) }, }; // Act var actual = discrepancyService .FindPingFailuresFromDataPoints( input, new PingSetting { MaxFailures = 1 }, new Metric { Type = Metrics.Ping.AsInt(), Source = "the-source" } ); // Assert Assert.Empty(actual); }
public async Task RecordsDiscrepanciesEmptyList() { // Arrange var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); // Act var actual = await discrepancyService.RecordDiscrepanciesAsync(new List <Discrepancy>()); // Assert Assert.Empty(actual); }
public async Task ResolvesDiscrepanciesAlreadyResolved() { // Arrange var logger = new Mock <ILogger <DiscrepancyService> >(); var context = _serviceProvider.GetRequiredService <IDataContext>(); var discrepancyService = new DiscrepancyService( logger.Object, context, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); var input = new List <Discrepancy> { new Discrepancy { DateFirstOffense = DateTime.UtcNow, Type = DiscrepancyType.GapInData, MetricSource = "the-source-1", MetricType = Metrics.CpuLoad, Resolved = true }, new Discrepancy { DateFirstOffense = DateTime.UtcNow, Type = DiscrepancyType.GapInData, MetricSource = "the-source-2", MetricType = Metrics.CpuLoad, Resolved = true } }; // Act var actual = await discrepancyService.ResolveDiscrepanciesAsync(input); // Assert Assert.Equal(input, actual); logger .Verify( log => log.Log( LogLevel.Warning, It.IsAny <EventId>(), It.IsAny <FormattedLogValues>(), It.IsAny <Exception>(), It.IsAny <Func <object, Exception, string> >() ), Times.Exactly(2) ); }
public void PermanentLowHealthInData() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Health:Threshold"]) .Returns(90.ToString()); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Health:MaxFailures"]) .Returns(2.ToString()); // 3 is discrepancy var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, mockConfig.Object ); var input = new List <HealthReport>() { ConfigureHealthReport(80, DateTime.UtcNow), // bad ConfigureHealthReport(89, DateTime.UtcNow.AddMinutes(-1)), // bad ConfigureHealthReport(70, DateTime.UtcNow.AddMinutes(-2)), // bad ConfigureHealthReport(60, DateTime.UtcNow.AddMinutes(-3)), // bad ConfigureHealthReport(85, DateTime.UtcNow.AddMinutes(-4)), // bad ConfigureHealthReport(56, DateTime.UtcNow.AddMinutes(-5)), // bad ConfigureHealthReport(69, DateTime.UtcNow.AddMinutes(-6)), // bad ConfigureHealthReport(9, DateTime.UtcNow.AddMinutes(-7)), // bad }; // Act var actual = discrepancyService .FindLowHealthInDataPoints( input, new Metric { Type = Metrics.Health.AsInt(), Source = "the-source" } ); // Assert Assert.Empty(actual); }
public async Task ResolvesDiscrepancies() { // Arrange var input = new List <Discrepancy> { new Discrepancy { DateFirstOffense = DateTime.UtcNow.AddMinutes(-2), Type = DiscrepancyType.GapInData, MetricSource = "the-source-1", MetricType = Metrics.CpuLoad, } }; var notifications = new Mock <INotificationService>(); var context = _serviceProvider.GetRequiredService <IDataContext>(); await context.Discrepancies.AddRangeAsync(input); await context.SaveChangesAsync(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, notifications.Object, new Mock <IConfiguration>().Object ); // Act var actual = await discrepancyService.ResolveDiscrepanciesAsync(input); // Assert Assert.True(actual.First().Resolved); Assert.InRange(actual.First().DateResolved, DateTime.UtcNow.AddMinutes(-1), DateTime.UtcNow.AddMinutes(1)); Assert.True(await context.Discrepancies.AnyAsync(d => d.Resolved)); notifications .Verify( notif => notif .ScheduleNotificationAsync( It.Is <string>(msg => msg.Contains("resolve", StringComparison.OrdinalIgnoreCase)), NotificationSeverity.High ) ); }
public async Task UsesCorrectTimeZone() { // Arrange var config = new Mock <IConfiguration>(); config .SetupGet(conf => conf["ServiceManager:NotificationService:TimeZone"]) .Returns("Asia/Kabul"); var date = DateTime.SpecifyKind(new DateTime(2017, 07, 14, 18, 25, 43), DateTimeKind.Utc); var context = _serviceProvider.GetRequiredService <IDataContext>(); var mockNotifications = new Mock <INotificationService>(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, mockNotifications.Object, config.Object ); var input = new List <Discrepancy> { new Discrepancy { DateFirstOffense = date, Type = DiscrepancyType.GapInData, MetricSource = "the-source", MetricType = Metrics.CpuLoad } }; // Act await discrepancyService.RecordDiscrepanciesAsync(input); // Assert mockNotifications .Verify( n => n.ScheduleNotificationAsync( It.Is <string>(s => s.Contains(date.ToStringUsingTimeZone("Asia/Kabul"))), NotificationSeverity.High ) ); }
public void NoGapsInData() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Gaps:MaxDifference"]) .Returns("60"); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, mockConfig.Object ); var input = new List <DateTime>() { DateTime.UtcNow - new TimeSpan(0, 0, 0), DateTime.UtcNow - new TimeSpan(0, 1, 0), DateTime.UtcNow - new TimeSpan(0, 2, 0), DateTime.UtcNow - new TimeSpan(0, 3, 0), DateTime.UtcNow - new TimeSpan(0, 4, 0), DateTime.UtcNow - new TimeSpan(0, 5, 0) }; // Act var actual = discrepancyService .FindGapsInDataPoints( input, new Metric { Type = Metrics.CpuLoad.AsInt(), Source = "the-source" } ); // Assert Assert.Empty(actual); }
public void GapNoData() { // Arrange var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); // Act var actual = discrepancyService .FindGapsInDataPoints( new List <DateTime>(), new Metric { Type = Metrics.CpuLoad.AsInt(), Source = "the-source" } ); // Assert Assert.Empty(actual); }
public void SinglePingFailure() { // Arrange var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); var input = new List <PingDataPoint>() { new PingDataPoint { Success = true, Timestamp = DateTime.UtcNow - new TimeSpan(0, 0, 0) }, new PingDataPoint { Success = false, Timestamp = DateTime.UtcNow - new TimeSpan(0, 1, 0) }, new PingDataPoint { Success = false, Timestamp = DateTime.UtcNow - new TimeSpan(0, 2, 0) }, new PingDataPoint { Success = true, Timestamp = DateTime.UtcNow - new TimeSpan(0, 3, 0) }, new PingDataPoint { Success = true, Timestamp = DateTime.UtcNow - new TimeSpan(0, 4, 0) }, }; var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = input[2].Timestamp, Type = DiscrepancyType.PingFailedNTimes, MetricType = Metrics.Ping, MetricSource = "the-source" } }; // Act var actual = discrepancyService .FindPingFailuresFromDataPoints( input, new PingSetting { MaxFailures = 1 }, new Metric { Type = Metrics.Ping.AsInt(), Source = "the-source" } ); // Assert Assert.Equal(expected, actual); }
public async Task FindsLowHealth() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Health:Threshold"]) .Returns(99.ToString()); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:LoHealthad:MaxFailures"]) .Returns(1.ToString()); // 3 is discrepancy var context = _serviceProvider.GetRequiredService <IDataContext>(); var metric = await context.Metrics.AddAsync( new Metric { Source = "the-source", Type = Metrics.Health.AsInt() } ); var dataPoints = new List <HealthReport>() { new HealthReport { // good Data = new List <HealthReportDataPoint> { new HealthReportDataPoint { Label = AutoLabels.Normal.ToString() }, new HealthReportDataPoint { Label = AutoLabels.Normal.ToString() }, }, Timestamp = DateTime.UtcNow, Metric = metric.Entity }, new HealthReport { Data = new List <HealthReportDataPoint> { // bad new HealthReportDataPoint { Label = AutoLabels.Normal.ToString() }, new HealthReportDataPoint { Label = AutoLabels.Critical.ToString() }, }, Timestamp = DateTime.UtcNow.AddMinutes(-1), Metric = metric.Entity }, new HealthReport { Data = new List <HealthReportDataPoint> { // bad new HealthReportDataPoint { Label = AutoLabels.Normal.ToString() }, new HealthReportDataPoint { Label = AutoLabels.Warning.ToString() }, }, Timestamp = DateTime.UtcNow.AddMinutes(-2), Metric = metric.Entity }, new HealthReport { // good Data = new List <HealthReportDataPoint> { new HealthReportDataPoint { Label = AutoLabels.Normal.ToString() }, new HealthReportDataPoint { Label = AutoLabels.Normal.ToString() }, }, Timestamp = DateTime.UtcNow.AddMinutes(-3), Metric = metric.Entity } }; await context.HealthReports.AddRangeAsync(dataPoints); await context.SaveChangesAsync(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, new Mock <INotificationService>().Object, mockConfig.Object ); var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = dataPoints[2].Timestamp, Type = DiscrepancyType.LowHealth, MetricType = Metrics.Health, MetricSource = "the-source" } }; // Act var actual = await discrepancyService .FindLowHealthsAsync( metric.Entity, new TimeSpan(0, 30, 0) ); // Assert Assert.Equal(expected, actual); }
public void MultiplePingFailures() { // Arrange var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); var input = new List <PingDataPoint>() { new PingDataPoint { HttpStatusCode = HttpStatusCode.OK.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 0, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.ServiceUnavailable.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 1, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.ServiceUnavailable.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 2, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.OK.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 3, 0) }, new PingDataPoint { HttpStatusCode = HttpStatusCode.ServiceUnavailable.AsInt(), Timestamp = DateTime.UtcNow - new TimeSpan(0, 4, 0) }, }; var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = input[4].Timestamp, Type = DiscrepancyType.PingFailedNTimes, MetricType = Metrics.Ping, MetricSource = "the-source" }, new Discrepancy { DateFirstOffense = input[2].Timestamp, Type = DiscrepancyType.PingFailedNTimes, MetricType = Metrics.Ping, MetricSource = "the-source" } } .OrderBy(d => d.DateFirstOffense);; // Act var actual = discrepancyService .FindPingFailuresFromDataPoints( input, new PingSetting { MaxFailures = 0 }, new Metric { Type = Metrics.Ping.AsInt(), Source = "the-source" } ) .OrderBy(d => d.DateFirstOffense);; // Assert Assert.Equal(expected, actual); }
public async Task FindsGap() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Gaps:MaxDifference"]) .Returns(60.ToString()); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:DataTimeframe"]) .Returns(1800.ToString()); var context = _serviceProvider.GetRequiredService <IDataContext>(); var metric = await context.Metrics.AddAsync( new Metric { Source = "the-source", Type = Metrics.CpuLoad.AsInt() } ); var dataPoints = new List <NumericDataPoint> { new NumericDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(0), Metric = metric.Entity }, new NumericDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-1), Metric = metric.Entity }, new NumericDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-2), Metric = metric.Entity }, new NumericDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-4), Metric = metric.Entity }, new NumericDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-5), Metric = metric.Entity } }; await context.NumericDataPoints.AddRangeAsync(dataPoints); await context.SaveChangesAsync(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, new Mock <INotificationService>().Object, mockConfig.Object ); var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = dataPoints[3].Timestamp, Type = DiscrepancyType.GapInData, MetricType = Metrics.CpuLoad, MetricSource = "the-source" } }; // Act var actual = await discrepancyService .FindGapsAsync( metric.Entity, new TimeSpan(0, 30, 0) ); // Assert Assert.Equal(expected, actual); }
public async Task ResolvesPingFailure(bool shouldResolve) { // Arrange var input = new List <Discrepancy> { new Discrepancy { DateFirstOffense = DateTime.UtcNow, Type = DiscrepancyType.PingFailedNTimes, MetricSource = "lolchik.com", MetricType = Metrics.Ping, } }; var metric = new Metric { Type = Metrics.Ping.AsInt(), Source = "lolchik.com" }; var context = _serviceProvider.GetRequiredService <IDataContext>(); await context.Metrics.AddAsync(metric); await context.PingDataPoints.AddRangeAsync( new PingDataPoint { Metric = metric, Success = true, Timestamp = DateTime.UtcNow.AddMinutes(-1) }, new PingDataPoint { Metric = metric, Success = false, Timestamp = DateTime.UtcNow.AddMinutes(1) }, new PingDataPoint { Metric = metric, Success = false, Timestamp = DateTime.UtcNow.AddMinutes(2) }, new PingDataPoint { Metric = metric, Success = shouldResolve, Timestamp = DateTime.UtcNow.AddMinutes(3) } ); await context.SaveChangesAsync(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); // Act var actual = await discrepancyService.FindResolvedDiscrepanciesAsync(input); // Assert if (shouldResolve) { Assert.NotEmpty(actual); Assert.Equal(input, actual); } else { Assert.Empty(actual); } }
public async Task ResolvesHighLoad(bool shouldResolve) { // Arrange var input = new List <Discrepancy> { new Discrepancy { DateFirstOffense = DateTime.UtcNow, Type = DiscrepancyType.HighLoad, MetricSource = "the-source-1", MetricType = Metrics.CpuLoad, } }; var metric = new Metric { Type = Metrics.CpuLoad.AsInt(), Source = "the-source-1" }; var context = _serviceProvider.GetRequiredService <IDataContext>(); await context.Metrics.AddAsync(metric); await context.NumericDataPoints.AddRangeAsync( new NumericDataPoint { Metric = metric, Value = 50, Timestamp = DateTime.UtcNow.AddMinutes(-1) }, new NumericDataPoint { Metric = metric, Value = 95, Timestamp = DateTime.UtcNow.AddMinutes(1) }, new NumericDataPoint { Metric = metric, Value = 91, Timestamp = DateTime.UtcNow.AddMinutes(2) }, new NumericDataPoint { Metric = metric, Value = shouldResolve ? 85 : 92, Timestamp = DateTime.UtcNow.AddMinutes(3) } ); await context.SaveChangesAsync(); var config = new Mock <IConfiguration>(); config .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Load:Threshold"]) .Returns(90.ToString()); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, new Mock <INotificationService>().Object, config.Object ); // Act var actual = await discrepancyService.FindResolvedDiscrepanciesAsync(input); // Assert if (shouldResolve) { Assert.NotEmpty(actual); Assert.Equal(input, actual); } else { Assert.Empty(actual); } }
public async Task FindsPingFailure() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:DataTimeframe"]) .Returns(1800.ToString()); var context = _serviceProvider.GetRequiredService <IDataContext>(); var metric = await context.Metrics.AddAsync( new Metric { Source = "the-source", Type = Metrics.Ping.AsInt() } ); var dataPoints = new List <PingDataPoint> { new PingDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(0), Metric = metric.Entity, HttpStatusCode = HttpStatusCode.OK.AsInt() }, new PingDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-1), Metric = metric.Entity, HttpStatusCode = HttpStatusCode.ServiceUnavailable.AsInt() }, new PingDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-2), Metric = metric.Entity, HttpStatusCode = HttpStatusCode.ServiceUnavailable.AsInt() }, new PingDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-3), Metric = metric.Entity, HttpStatusCode = HttpStatusCode.OK.AsInt() }, new PingDataPoint { Timestamp = DateTime.UtcNow.AddMinutes(-4), Metric = metric.Entity, HttpStatusCode = HttpStatusCode.OK.AsInt() } }; await context.PingDataPoints.AddRangeAsync(dataPoints); await context.PingSettings.AddAsync( new PingSetting { ServerUrl = "the-source", MaxFailures = 1 } ); await context.SaveChangesAsync(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, new Mock <INotificationService>().Object, mockConfig.Object ); var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = dataPoints[2].Timestamp, Type = DiscrepancyType.PingFailedNTimes, MetricType = Metrics.Ping, MetricSource = "the-source" } }; // Act var actual = await discrepancyService .FindPingFailuresAsync( metric.Entity, new TimeSpan(0, 30, 0) ); // Assert Assert.Equal(expected, actual); }
public void PingFailuresDataStartsWithFailure() { // Arrange var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, new Mock <IConfiguration>().Object ); var input = new List <PingDataPoint>() { new PingDataPoint { Success = true, Timestamp = DateTime.UtcNow.AddMinutes(0) }, new PingDataPoint { Success = false, Timestamp = DateTime.UtcNow.AddMinutes(-1) }, new PingDataPoint { Success = false, Timestamp = DateTime.UtcNow.AddMinutes(-2) }, new PingDataPoint { Success = true, Timestamp = DateTime.UtcNow.AddMinutes(-3) }, new PingDataPoint { Success = false, Timestamp = DateTime.UtcNow.AddMinutes(-4) }, new PingDataPoint { Success = false, Timestamp = DateTime.UtcNow.AddMinutes(-5) } }; var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = input[2].Timestamp, Type = DiscrepancyType.PingFailedNTimes, MetricType = Metrics.Ping, MetricSource = "the-source" } } .OrderBy(d => d.DateFirstOffense);; // Act var actual = discrepancyService .FindPingFailuresFromDataPoints( input, new PingSetting { MaxFailures = 0 }, new Metric { Type = Metrics.Ping.AsInt(), Source = "the-source" } ) .OrderBy(d => d.DateFirstOffense);; // Assert Assert.Equal(expected, actual); }
public async Task RecordsDiscrepancies() { // Arrange var twoDaysAgo = DateTime.UtcNow.AddDays(-2); var hourAgo = DateTime.UtcNow.AddHours(-1); var now = DateTime.UtcNow; var context = _serviceProvider.GetRequiredService <IDataContext>(); await context.Discrepancies.AddRangeAsync( new List <Discrepancy> { new Discrepancy { DateFirstOffense = now, Type = DiscrepancyType.GapInData, MetricSource = "the-source", MetricType = Metrics.CpuLoad }, new Discrepancy { DateFirstOffense = hourAgo, Type = DiscrepancyType.PingFailedNTimes, MetricSource = "the-source", MetricType = Metrics.Ping }, new Discrepancy { DateFirstOffense = twoDaysAgo, Type = DiscrepancyType.GapInData, MetricSource = "the-source", MetricType = Metrics.CpuLoad } } ); await context.SaveChangesAsync(); var mockNotifications = new Mock <INotificationService>(); var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, context, mockNotifications.Object, new Mock <IConfiguration>().Object ); var input = new List <Discrepancy> { new Discrepancy { // already exists DateFirstOffense = now, Type = DiscrepancyType.GapInData, MetricSource = "the-source", MetricType = Metrics.CpuLoad }, new Discrepancy { // new DateFirstOffense = hourAgo, Type = DiscrepancyType.PingFailedNTimes, MetricSource = "the-other-source", MetricType = Metrics.Ping }, new Discrepancy { // new DateFirstOffense = twoDaysAgo.AddHours(1), Type = DiscrepancyType.GapInData, MetricSource = "the-source", MetricType = Metrics.CpuLoad } }; var expected = new List <Discrepancy> { input[1], input[2] }; // Act var actual = await discrepancyService.RecordDiscrepanciesAsync(input); // Assert Assert.Equal( expected.OrderBy(d => d.DateFirstOffense), actual.OrderBy(d => d.DateFirstOffense) ); mockNotifications .Verify( n => n.ScheduleNotificationAsync( It.IsAny <string>(), NotificationSeverity.High ), Times.Exactly(expected.Count) ); Assert.Equal(5, context.Discrepancies.Count()); }
public void MultipleHighLoadInData() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Load:Threshold"]) .Returns(90.ToString()); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Load:MaxFailures"]) .Returns(2.ToString()); // 3 is discrepancy var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, mockConfig.Object ); var input = new List <NumericDataPoint>() { new NumericDataPoint { // Good Timestamp = DateTime.UtcNow.AddMinutes(0), Value = 68 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-1), Value = 91 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-2), Value = 99 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-3), Value = 95 }, new NumericDataPoint { // Good Timestamp = DateTime.UtcNow.AddMinutes(-4), Value = 68 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-5), Value = 99 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-6), Value = 98 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-7), Value = 92 }, new NumericDataPoint { // Good Timestamp = DateTime.UtcNow.AddMinutes(-8), Value = 68 } }; var expected = new List <Discrepancy> { new Discrepancy { DateFirstOffense = input[3].Timestamp, Type = DiscrepancyType.HighLoad, MetricType = Metrics.CpuLoad, MetricSource = "the-source" }, new Discrepancy { DateFirstOffense = input[7].Timestamp, Type = DiscrepancyType.HighLoad, MetricType = Metrics.CpuLoad, MetricSource = "the-source" } }; // Act var actual = discrepancyService .FindHighLoadInDataPoints( input, new Metric { Type = Metrics.CpuLoad.AsInt(), Source = "the-source" } ); // Assert Assert.Equal(expected, actual); }
public void PermanentHighLoadInData() { // Arrange var mockConfig = new Mock <IConfiguration>(); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Load:Threshold"]) .Returns(90.ToString()); mockConfig .SetupGet(conf => conf["ServiceManager:DiscrepancyService:Load:MaxFailures"]) .Returns(3.ToString()); // 4 is discrepancy var discrepancyService = new DiscrepancyService( new Mock <ILogger <DiscrepancyService> >().Object, new Mock <IDataContext>().Object, new Mock <INotificationService>().Object, mockConfig.Object ); var input = new List <NumericDataPoint>() { new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(0), Value = 93 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-1), Value = 91 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-2), Value = 99 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-3), Value = 95 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-4), Value = 98 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-5), Value = 99 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-6), Value = 98 }, new NumericDataPoint { // Bad Timestamp = DateTime.UtcNow.AddMinutes(-7), Value = 90 } }; // Act var actual = discrepancyService .FindHighLoadInDataPoints( input, new Metric { Type = Metrics.CpuLoad.AsInt(), Source = "the-source" } ); // Assert Assert.Empty(actual); }