Add unit test to check that metric dimensions are order insensitive (#2788)
This commit is contained in:
parent
fcb6b40bfa
commit
d4cf69301d
|
|
@ -382,6 +382,188 @@ namespace OpenTelemetry.Metrics.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void DimensionsAreOrderInsensitiveWithSortedKeysFirst(bool exportDelta)
|
||||
{
|
||||
var exportedItems = new List<Metric>();
|
||||
|
||||
using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{exportDelta}");
|
||||
var counterLong = meter.CreateCounter<long>("Counter");
|
||||
using var meterProvider = Sdk.CreateMeterProviderBuilder()
|
||||
.AddMeter(meter.Name)
|
||||
.AddReader(new BaseExportingMetricReader(new InMemoryExporter<Metric>(exportedItems))
|
||||
{
|
||||
Temporality = exportDelta ? AggregationTemporality.Delta : AggregationTemporality.Cumulative,
|
||||
})
|
||||
.Build();
|
||||
|
||||
// Emit the first metric with the sorted order of tag keys
|
||||
counterLong.Add(5, new("Key1", "Value1"), new("Key2", "Value2"), new("Key3", "Value3"));
|
||||
counterLong.Add(10, new("Key1", "Value1"), new("Key3", "Value3"), new("Key2", "Value2"));
|
||||
counterLong.Add(10, new("Key2", "Value20"), new("Key1", "Value10"), new("Key3", "Value30"));
|
||||
|
||||
// Emit a metric with different set of keys but the same set of values as one of the previous metric points
|
||||
counterLong.Add(25, new("Key4", "Value1"), new("Key5", "Value3"), new("Key6", "Value2"));
|
||||
counterLong.Add(25, new("Key4", "Value1"), new("Key6", "Value3"), new("Key5", "Value2"));
|
||||
|
||||
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForFirstMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key1", "Value1"),
|
||||
new("Key2", "Value2"),
|
||||
new("Key3", "Value3"),
|
||||
};
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForSecondMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key1", "Value10"),
|
||||
new("Key2", "Value20"),
|
||||
new("Key3", "Value30"),
|
||||
};
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForThirdMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key4", "Value1"),
|
||||
new("Key5", "Value3"),
|
||||
new("Key6", "Value2"),
|
||||
};
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForFourthMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key4", "Value1"),
|
||||
new("Key5", "Value2"),
|
||||
new("Key6", "Value3"),
|
||||
};
|
||||
|
||||
Assert.Equal(4, GetNumberOfMetricPoints(exportedItems));
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFirstMetricPoint, 1);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForSecondMetricPoint, 2);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForThirdMetricPoint, 3);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFourthMetricPoint, 4);
|
||||
long sumReceived = GetLongSum(exportedItems);
|
||||
Assert.Equal(75, sumReceived);
|
||||
|
||||
exportedItems.Clear();
|
||||
|
||||
counterLong.Add(5, new("Key2", "Value2"), new("Key1", "Value1"), new("Key3", "Value3"));
|
||||
counterLong.Add(5, new("Key2", "Value2"), new("Key1", "Value1"), new("Key3", "Value3"));
|
||||
counterLong.Add(10, new("Key2", "Value2"), new("Key3", "Value3"), new("Key1", "Value1"));
|
||||
counterLong.Add(10, new("Key2", "Value20"), new("Key3", "Value30"), new("Key1", "Value10"));
|
||||
counterLong.Add(20, new("Key4", "Value1"), new("Key6", "Value2"), new("Key5", "Value3"));
|
||||
counterLong.Add(20, new("Key4", "Value1"), new("Key5", "Value2"), new("Key6", "Value3"));
|
||||
|
||||
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||
|
||||
Assert.Equal(4, GetNumberOfMetricPoints(exportedItems));
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFirstMetricPoint, 1);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForSecondMetricPoint, 2);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForThirdMetricPoint, 3);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFourthMetricPoint, 4);
|
||||
sumReceived = GetLongSum(exportedItems);
|
||||
if (exportDelta)
|
||||
{
|
||||
Assert.Equal(70, sumReceived);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(145, sumReceived);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void DimensionsAreOrderInsensitiveWithUnsortedKeysFirst(bool exportDelta)
|
||||
{
|
||||
var exportedItems = new List<Metric>();
|
||||
|
||||
using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{exportDelta}");
|
||||
var counterLong = meter.CreateCounter<long>("Counter");
|
||||
using var meterProvider = Sdk.CreateMeterProviderBuilder()
|
||||
.AddMeter(meter.Name)
|
||||
.AddReader(new BaseExportingMetricReader(new InMemoryExporter<Metric>(exportedItems))
|
||||
{
|
||||
Temporality = exportDelta ? AggregationTemporality.Delta : AggregationTemporality.Cumulative,
|
||||
})
|
||||
.Build();
|
||||
|
||||
// Emit the first metric with the unsorted order of tag keys
|
||||
counterLong.Add(5, new("Key1", "Value1"), new("Key3", "Value3"), new("Key2", "Value2"));
|
||||
counterLong.Add(10, new("Key1", "Value1"), new("Key2", "Value2"), new("Key3", "Value3"));
|
||||
counterLong.Add(10, new("Key2", "Value20"), new("Key1", "Value10"), new("Key3", "Value30"));
|
||||
|
||||
// Emit a metric with different set of keys but the same set of values as one of the previous metric points
|
||||
counterLong.Add(25, new("Key4", "Value1"), new("Key5", "Value3"), new("Key6", "Value2"));
|
||||
counterLong.Add(25, new("Key4", "Value1"), new("Key6", "Value3"), new("Key5", "Value2"));
|
||||
|
||||
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForFirstMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key1", "Value1"),
|
||||
new("Key2", "Value2"),
|
||||
new("Key3", "Value3"),
|
||||
};
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForSecondMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key1", "Value10"),
|
||||
new("Key2", "Value20"),
|
||||
new("Key3", "Value30"),
|
||||
};
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForThirdMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key4", "Value1"),
|
||||
new("Key5", "Value3"),
|
||||
new("Key6", "Value2"),
|
||||
};
|
||||
|
||||
List<KeyValuePair<string, object>> expectedTagsForFourthMetricPoint = new List<KeyValuePair<string, object>>()
|
||||
{
|
||||
new("Key4", "Value1"),
|
||||
new("Key5", "Value2"),
|
||||
new("Key6", "Value3"),
|
||||
};
|
||||
|
||||
Assert.Equal(4, GetNumberOfMetricPoints(exportedItems));
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFirstMetricPoint, 1);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForSecondMetricPoint, 2);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForThirdMetricPoint, 3);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFourthMetricPoint, 4);
|
||||
long sumReceived = GetLongSum(exportedItems);
|
||||
Assert.Equal(75, sumReceived);
|
||||
|
||||
exportedItems.Clear();
|
||||
|
||||
counterLong.Add(5, new("Key2", "Value2"), new("Key1", "Value1"), new("Key3", "Value3"));
|
||||
counterLong.Add(5, new("Key2", "Value2"), new("Key1", "Value1"), new("Key3", "Value3"));
|
||||
counterLong.Add(10, new("Key2", "Value2"), new("Key3", "Value3"), new("Key1", "Value1"));
|
||||
counterLong.Add(10, new("Key2", "Value20"), new("Key3", "Value30"), new("Key1", "Value10"));
|
||||
counterLong.Add(20, new("Key4", "Value1"), new("Key6", "Value2"), new("Key5", "Value3"));
|
||||
counterLong.Add(20, new("Key4", "Value1"), new("Key5", "Value2"), new("Key6", "Value3"));
|
||||
|
||||
meterProvider.ForceFlush(MaxTimeToAllowForFlush);
|
||||
|
||||
Assert.Equal(4, GetNumberOfMetricPoints(exportedItems));
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFirstMetricPoint, 1);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForSecondMetricPoint, 2);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForThirdMetricPoint, 3);
|
||||
CheckTagsForNthMetricPoint(exportedItems, expectedTagsForFourthMetricPoint, 4);
|
||||
sumReceived = GetLongSum(exportedItems);
|
||||
if (exportDelta)
|
||||
{
|
||||
Assert.Equal(70, sumReceived);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(145, sumReceived);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(AggregationTemporality.Cumulative)]
|
||||
[InlineData(AggregationTemporality.Delta)]
|
||||
|
|
@ -658,6 +840,41 @@ namespace OpenTelemetry.Metrics.Tests
|
|||
return sum;
|
||||
}
|
||||
|
||||
private static int GetNumberOfMetricPoints(List<Metric> metrics)
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var metric in metrics)
|
||||
{
|
||||
foreach (ref readonly var metricPoint in metric.GetMetricPoints())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Provide tags input sorted by Key
|
||||
private static void CheckTagsForNthMetricPoint(List<Metric> metrics, List<KeyValuePair<string, object>> tags, int n)
|
||||
{
|
||||
var metric = metrics[0];
|
||||
var metricPointEnumerator = metric.GetMetricPoints().GetEnumerator();
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
Assert.True(metricPointEnumerator.MoveNext());
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
var metricPoint = metricPointEnumerator.Current;
|
||||
foreach (var tag in metricPoint.Tags)
|
||||
{
|
||||
Assert.Equal(tags[index].Key, tag.Key);
|
||||
Assert.Equal(tags[index].Value, tag.Value);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private static void CounterUpdateThread<T>(object obj)
|
||||
where T : struct, IComparable
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue