public async Task ReportMetricAsync_GetsValidInputWithMetricLabelWithSameKeyAsScrapeResult_SuccessfullyWritesMetricWithLabelValueFromScrapeResult() { // Arrange var metricName = _bogus.Name.FirstName(); var metricDescription = _bogus.Lorem.Sentence(); var metricValue = _bogus.Random.Double(); var labelName = _bogus.Name.FirstName(); var scrapeResultLabelValue = _bogus.Name.FirstName(); var metricConfigLabelValue = _bogus.Name.FirstName(); var expectedLabelName = labelName.ToLower(); var configuredLabels = new Dictionary <string, string> { { labelName.ToUpper(), metricConfigLabelValue } }; var scrapeResult = ScrapeResultGenerator.Generate(metricValue); scrapeResult.Labels.Add(labelName, scrapeResultLabelValue); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName, configuredLabels); var prometheusConfiguration = CreatePrometheusConfiguration(); var mocks = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(mocks.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); // Assert mocks.Factory.Verify(mock => mock.CreateGauge(metricName, metricDescription, It.IsAny <bool>(), It.Is <string[]>(specified => specified.Contains(expectedLabelName) && EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Keys.ToArray()))), Times.Once()); mocks.MetricFamily.Verify(mock => mock.WithLabels(It.Is <string[]>(specified => specified.Contains(scrapeResultLabelValue) && specified.Contains(metricConfigLabelValue) == false && EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Values.ToArray()))), Times.Once()); mocks.Gauge.Verify(mock => mock.Set(metricValue), Times.Once()); }
public async Task ReportMetricAsync_GetsValidInputWithTwoMetricValues_SuccessfullyWritesMultipleMetrics() { // Arrange var metricName = _bogus.Name.FirstName(); var metricDescription = _bogus.Lorem.Sentence(); var firstMetricValue = _bogus.Random.Double(); var secondMetricValue = _bogus.Random.Double(); var firstMetric = MeasuredMetric.CreateWithoutDimension(firstMetricValue); var secondMetric = MeasuredMetric.CreateWithoutDimension(secondMetricValue); var scrapeResult = ScrapeResultGenerator.GenerateFromMetric(firstMetric); scrapeResult.MetricValues.Add(secondMetric); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(); var mocks = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(mocks.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); // Assert mocks.Factory.Verify(mock => mock.CreateGauge(metricName, metricDescription, It.IsAny <bool>(), It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Keys.ToArray()))), Times.Exactly(2)); mocks.MetricFamily.Verify(mock => mock.WithLabels(It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Values.ToArray()))), Times.Exactly(2)); mocks.Gauge.Verify(mock => mock.Set(firstMetricValue), Times.Once()); mocks.Gauge.Verify(mock => mock.Set(secondMetricValue), Times.Once()); }
public async Task ReportMetricAsync_GetsValidInputWithOneDimensions_SuccessfullyWritesMetric() { // Arrange var metricName = _bogus.Name.FirstName(); var metricDescription = _bogus.Lorem.Sentence(); var metricValue = _bogus.Random.Double(); var dimensionName = _bogus.Name.FirstName(); var dimensionValue = _bogus.Name.FirstName(); var expectedDimensionName = dimensionName.ToLower(); var timeSeries = new TimeSeriesElement { Metadatavalues = new List <MetadataValue> { new MetadataValue(name: new LocalizableString(dimensionName), value: dimensionValue) } }; var measuredMetric = MeasuredMetric.CreateForDimension(metricValue, dimensionName.ToUpper(), timeSeries); var scrapeResult = ScrapeResultGenerator.GenerateFromMetric(measuredMetric); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(); var mocks = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(mocks.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); // Assert mocks.Factory.Verify(mock => mock.CreateGauge(metricName, metricDescription, It.IsAny <bool>(), It.Is <string[]>(specified => specified.Contains(expectedDimensionName) && EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Keys.ToArray()))), Times.Once()); mocks.MetricFamily.Verify(mock => mock.WithLabels(It.Is <string[]>(specified => specified.Contains(dimensionValue) && EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Values.ToArray()))), Times.Once()); mocks.Gauge.Verify(mock => mock.Set(metricValue), Times.Once()); }
public async Task ReportMetricAsync_InputDoesNotContainMeasuredMetric_ThrowsException() { // Arrange var metricName = _bogus.Name.FirstName(); var metricDescription = _bogus.Lorem.Sentence(); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(); var metricFactoryMock = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(metricFactoryMock.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act & Assert // ReSharper disable once ExpressionIsAlwaysNull await Assert.ThrowsAsync <ArgumentNullException>(() => metricSink.ReportMetricAsync(metricName, metricDescription, null)); }
public async Task ReportMetricAsync_InputDoesNotContainMetricDescription_Succeeds(string metricDescription) { // Arrange var metricName = _bogus.Name.FirstName(); var metricValue = _bogus.Random.Double(); var scrapeResult = ScrapeResultGenerator.Generate(metricValue); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(); var metricFactoryMock = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(metricFactoryMock.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act & Assert // ReSharper disable once ExpressionIsAlwaysNull await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); }
public async Task ReportMetricAsync_InputDoesNotContainMetricName_ThrowsException(string metricName) { // Arrange var metricDescription = BogusGenerator.Lorem.Sentence(); var metricValue = BogusGenerator.Random.Double(); var scrapeResult = ScrapeResultGenerator.Generate(metricValue); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(); var metricFactoryMock = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(metricFactoryMock.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act & Assert // ReSharper disable once ExpressionIsAlwaysNull await Assert.ThrowsAsync <ArgumentException>(() => metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult)); }
public async Task ReportMetricAsync_GetsValidInputWithMetricValueAndTimestampFlag_SuccessfullyWritesMetricWithRespectToTimestampFlag(bool includeTimestampsInMetrics) { // Arrange var metricName = _bogus.Name.FirstName(); var metricDescription = _bogus.Lorem.Sentence(); var metricValue = _bogus.Random.Double(); var scrapeResult = ScrapeResultGenerator.Generate(metricValue); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(enableMetricsTimestamps: includeTimestampsInMetrics); var mocks = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(mocks.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); // Assert mocks.Factory.Verify(mock => mock.CreateGauge(metricName, metricDescription, includeTimestampsInMetrics, It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Keys.ToArray()))), Times.Once()); mocks.MetricFamily.Verify(mock => mock.WithLabels(It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Values.ToArray()))), Times.Once()); mocks.Gauge.Verify(mock => mock.Set(metricValue), Times.Once()); }
public async Task ReportMetricAsync_GetsValidInputWithoutMetricValue_SuccessfullyWritesMetricWithDefault(double?expectedDefaultValue) { // Arrange double expectedMeasuredMetric = expectedDefaultValue ?? double.NaN; // If nothing is configured, NaN is used. var metricName = _bogus.Name.FirstName(); var metricDescription = _bogus.Lorem.Sentence(); double?metricValue = null; // ReSharper disable once ExpressionIsAlwaysNull var measuredMetric = MeasuredMetric.CreateWithoutDimension(metricValue); var scrapeResult = ScrapeResultGenerator.GenerateFromMetric(measuredMetric); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(metricUnavailableValue: expectedDefaultValue); var mocks = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(mocks.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); // Assert mocks.Factory.Verify(mock => mock.CreateGauge(metricName, metricDescription, It.IsAny <bool>(), It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Keys.ToArray()))), Times.Once()); mocks.MetricFamily.Verify(mock => mock.WithLabels(It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Values.ToArray()))), Times.Once()); mocks.Gauge.Verify(mock => mock.Set(expectedMeasuredMetric), Times.Once()); }
public async Task ReportMetricAsync_GetsValidInputWithUpperCaseLabelNames_SuccessfullyWritesMetricWithLowercaseLabels() { // Arrange var metricName = _bogus.Name.FirstName(); var metricDescription = _bogus.Lorem.Sentence(); var metricValue = _bogus.Random.Double(); var scrapeResult = ScrapeResultGenerator.Generate(metricValue); var mutatedLabels = scrapeResult.Labels.ToDictionary(kvp => kvp.Key.ToUpper(), kvp => kvp.Value); scrapeResult.Labels.Clear(); mutatedLabels.ForAll(kvp => scrapeResult.Labels.Add(kvp.Key.ToUpper(), kvp.Value)); var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName); var prometheusConfiguration = CreatePrometheusConfiguration(); var mocks = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(mocks.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); // Assert mocks.Factory.Verify(mock => mock.CreateGauge(metricName, metricDescription, It.IsAny <bool>(), It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Keys.ToArray()))), Times.Once()); mocks.MetricFamily.Verify(mock => mock.WithLabels(It.Is <string[]>(specified => EnsureAllArrayEntriesAreSpecified(specified, scrapeResult.Labels.Values.ToArray()))), Times.Once()); mocks.Gauge.Verify(mock => mock.Set(metricValue), Times.Once()); }
public async Task ReportMetricAsync_GetsValidInputWithMetricValue_SuccessfullyWritesMetric() { // Arrange var metricName = BogusGenerator.Name.FirstName(); var metricDescription = BogusGenerator.Lorem.Sentence(); var metricValue = BogusGenerator.Random.Double(); var scrapeResult = ScrapeResultGenerator.Generate(metricValue); var defaultLabels = new Dictionary <string, string> { { "app", "promitor" } }; var metricsDeclarationProvider = CreateMetricsDeclarationProvider(metricName, defaultLabels: defaultLabels); var prometheusConfiguration = CreatePrometheusConfiguration(); var mocks = CreatePrometheusMetricFactoryMock(); var metricSink = new PrometheusScrapingEndpointMetricSink(mocks.Factory.Object, metricsDeclarationProvider, prometheusConfiguration, NullLogger <PrometheusScrapingEndpointMetricSink> .Instance); // Act await metricSink.ReportMetricAsync(metricName, metricDescription, scrapeResult); // Assert mocks.Factory.Verify(mock => mock.CreateGauge(metricName, metricDescription, It.IsAny <bool>(), It.Is <string[]>(specified => EnsureAllLabelKeysAreSpecified(specified, scrapeResult.Labels.Keys.ToArray(), defaultLabels.Keys.ToArray()))), Times.Once()); mocks.MetricFamily.Verify(mock => mock.WithLabels(It.Is <string[]>(specified => EnsureAllLabelValuesAreSpecified(specified, scrapeResult.Labels.Values.ToArray(), defaultLabels.Values.ToArray()))), Times.Once()); mocks.Gauge.Verify(mock => mock.Set(metricValue), Times.Once()); }