Skip to content

Commit 24818e7

Browse files
fix: refactor OTEL metrics tests to make them more stable (#212)
Signed-off-by: Jens Henneberg <[email protected]>
1 parent d93242c commit 24818e7

File tree

1 file changed

+27
-61
lines changed

1 file changed

+27
-61
lines changed

test/OpenFeature.Contrib.Hooks.Otel.Test/MetricsHookTest.cs

Lines changed: 27 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Threading;
54
using OpenFeature.Model;
65
using OpenTelemetry;
76
using OpenTelemetry.Metrics;
@@ -12,30 +11,32 @@ namespace OpenFeature.Contrib.Hooks.Otel.Test
1211
{
1312
public class MetricsHookTest
1413
{
15-
[Fact]
16-
public void After_Test()
14+
readonly List<Metric> exportedItems;
15+
readonly MeterProvider meterProvider;
16+
HookContext<string> hookContext = new HookContext<string>("my-flag", "foo", Constant.FlagValueType.String, new ClientMetadata("my-client", "1.0"), new Metadata("my-provider"), EvaluationContext.Empty);
17+
18+
public MetricsHookTest()
1719
{
18-
// Arrange metrics collector
19-
var exportedItems = new List<Metric>();
20-
Sdk.CreateMeterProviderBuilder()
20+
exportedItems = new List<Metric>();
21+
meterProvider = Sdk.CreateMeterProviderBuilder()
2122
.AddMeter("*")
2223
.ConfigureResource(r => r.AddService("openfeature"))
23-
.AddInMemoryExporter(exportedItems, option => option.PeriodicExportingMetricReaderOptions = new PeriodicExportingMetricReaderOptions { ExportIntervalMilliseconds = 100 })
24+
.AddInMemoryExporter(exportedItems)
2425
.Build();
26+
}
2527

28+
[Fact]
29+
public async void After_Test()
30+
{
2631
// Arrange
2732
const string metricName = "feature_flag.evaluation_success_total";
2833
var otelHook = new MetricsHook();
29-
var evaluationContext = EvaluationContext.Empty;
30-
var ctx = new HookContext<string>("my-flag", "foo", Constant.FlagValueType.String, new ClientMetadata("my-client", "1.0"), new Metadata("my-provider"), evaluationContext);
3134

3235
// Act
33-
var hookTask = otelHook.After(ctx, new FlagEvaluationDetails<string>("my-flag", "foo", Constant.ErrorType.None, "STATIC", "default"), new Dictionary<string, object>());
34-
// Wait for the metrics to be exported
35-
Thread.Sleep(150);
36+
await otelHook.After(hookContext, new FlagEvaluationDetails<string>("my-flag", "foo", Constant.ErrorType.None, "STATIC", "default"), new Dictionary<string, object>());
3637

37-
// Assert
38-
Assert.True(hookTask.IsCompleted);
38+
// Flush metrics
39+
meterProvider.ForceFlush();
3940

4041
// Assert metrics
4142
Assert.NotEmpty(exportedItems);
@@ -49,29 +50,17 @@ public void After_Test()
4950
}
5051

5152
[Fact]
52-
public void Error_Test()
53+
public async void Error_Test()
5354
{
54-
// Arrange metrics collector
55-
var exportedItems = new List<Metric>();
56-
Sdk.CreateMeterProviderBuilder()
57-
.AddMeter("*")
58-
.ConfigureResource(r => r.AddService("openfeature"))
59-
.AddInMemoryExporter(exportedItems, option => option.PeriodicExportingMetricReaderOptions = new PeriodicExportingMetricReaderOptions { ExportIntervalMilliseconds = 100 })
60-
.Build();
61-
6255
// Arrange
6356
const string metricName = "feature_flag.evaluation_error_total";
6457
var otelHook = new MetricsHook();
65-
var evaluationContext = EvaluationContext.Empty;
66-
var ctx = new HookContext<string>("my-flag", "foo", Constant.FlagValueType.String, new ClientMetadata("my-client", "1.0"), new Metadata("my-provider"), evaluationContext);
6758

6859
// Act
69-
var hookTask = otelHook.Error(ctx, new Exception(), new Dictionary<string, object>());
70-
// Wait for the metrics to be exported
71-
Thread.Sleep(150);
60+
await otelHook.Error(hookContext, new Exception(), new Dictionary<string, object>());
7261

73-
// Assert
74-
Assert.True(hookTask.IsCompleted);
62+
// Flush metrics
63+
meterProvider.ForceFlush();
7564

7665
// Assert metrics
7766
Assert.NotEmpty(exportedItems);
@@ -85,29 +74,17 @@ public void Error_Test()
8574
}
8675

8776
[Fact]
88-
public void Finally_Test()
77+
public async void Finally_Test()
8978
{
90-
// Arrange metrics collector
91-
var exportedItems = new List<Metric>();
92-
Sdk.CreateMeterProviderBuilder()
93-
.AddMeter("*")
94-
.ConfigureResource(r => r.AddService("openfeature"))
95-
.AddInMemoryExporter(exportedItems, option => option.PeriodicExportingMetricReaderOptions = new PeriodicExportingMetricReaderOptions { ExportIntervalMilliseconds = 100 })
96-
.Build();
97-
9879
// Arrange
9980
const string metricName = "feature_flag.evaluation_active_count";
10081
var otelHook = new MetricsHook();
101-
var evaluationContext = EvaluationContext.Empty;
102-
var ctx = new HookContext<string>("my-flag", "foo", Constant.FlagValueType.String, new ClientMetadata("my-client", "1.0"), new Metadata("my-provider"), evaluationContext);
10382

10483
// Act
105-
var hookTask = otelHook.Finally(ctx, new Dictionary<string, object>());
106-
// Wait for the metrics to be exported
107-
Thread.Sleep(150);
84+
await otelHook.Finally(hookContext, new Dictionary<string, object>());
10885

109-
// Assert
110-
Assert.True(hookTask.IsCompleted);
86+
// Flush metrics
87+
meterProvider.ForceFlush();
11188

11289
// Assert metrics
11390
Assert.NotEmpty(exportedItems);
@@ -121,30 +98,19 @@ public void Finally_Test()
12198
}
12299

123100
[Fact]
124-
public void Before_Test()
101+
public async void Before_Test()
125102
{
126-
// Arrange metrics collector
127-
var exportedItems = new List<Metric>();
128-
Sdk.CreateMeterProviderBuilder()
129-
.AddMeter("*")
130-
.ConfigureResource(r => r.AddService("openfeature"))
131-
.AddInMemoryExporter(exportedItems, option => option.PeriodicExportingMetricReaderOptions = new PeriodicExportingMetricReaderOptions { ExportIntervalMilliseconds = 100 })
132-
.Build();
133103

134104
// Arrange
135105
const string metricName1 = "feature_flag.evaluation_active_count";
136106
const string metricName2 = "feature_flag.evaluation_requests_total";
137107
var otelHook = new MetricsHook();
138-
var evaluationContext = EvaluationContext.Empty;
139-
var ctx = new HookContext<string>("my-flag", "foo", Constant.FlagValueType.String, new ClientMetadata("my-client", "1.0"), new Metadata("my-provider"), evaluationContext);
140108

141109
// Act
142-
var hookTask = otelHook.Before(ctx, new Dictionary<string, object>());
143-
// Wait for the metrics to be exported
144-
Thread.Sleep(150);
110+
await otelHook.Before(hookContext, new Dictionary<string, object>());
145111

146-
// Assert
147-
Assert.True(hookTask.IsCompleted);
112+
// Flush metrics
113+
meterProvider.ForceFlush();
148114

149115
// Assert metrics
150116
Assert.NotEmpty(exportedItems);

0 commit comments

Comments
 (0)