Skip to content

Commit 0624332

Browse files
authored
fix: Fix dimension mismatch in active evaluation metric (#679)
* fix: fix dimension mismatch in active evaluation metric Signed-off-by: burhansavci <burhansavci@gmail.com> * Refactor assertion in MetricsHookTests for readability Signed-off-by: burhansavci <burhansavci@gmail.com> --------- Signed-off-by: burhansavci <burhansavci@gmail.com>
1 parent dcd6649 commit 0624332

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

src/OpenFeature/Hooks/MetricsHook.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public override ValueTask<EvaluationContext> BeforeAsync<T>(HookContext<T> conte
4949
};
5050

5151
this.AddCustomDimensions(ref tagList);
52+
this.AddFlagMetadataDimensions(null, ref tagList);
5253

5354
this._evaluationActiveUpDownCounter.Add(1, tagList);
5455
this._evaluationRequestCounter.Add(1, tagList);

test/OpenFeature.Tests/Hooks/MetricsHookTests.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,4 +339,71 @@ public async Task With_CustomDimensions_Before_Test()
339339
Assert.Equal("my-provider", measurements.Tags["feature_flag.provider.name"]);
340340
Assert.Equal("custom_dimension_value", measurements.Tags["custom_dimension_key"]);
341341
}
342+
343+
[Fact]
344+
public async Task ActiveCounter_Before_And_Finally_Have_Same_Tags_Test()
345+
{
346+
// Arrange
347+
var metricsHookOptions = MetricsHookOptions.CreateBuilder()
348+
.WithCustomDimension("custom_dimension_key", "custom_dimension_value")
349+
.WithFlagEvaluationMetadata("boolean", m => m.GetBool("boolean"))
350+
.Build();
351+
352+
var metricsHook = new MetricsHook(metricsHookOptions);
353+
354+
using var collector = new MetricCollector<long>(metricsHook._evaluationActiveUpDownCounter);
355+
356+
var flagMetadata = new ImmutableMetadata(new Dictionary<string, object> { { "boolean", true } });
357+
358+
var evaluationContext = EvaluationContext.Empty;
359+
var ctx = new HookContext<string>("my-flag", "foo", Constant.FlagValueType.String,
360+
new ClientMetadata("my-client", "1.0"), new Metadata("my-provider"), evaluationContext);
361+
var evaluationDetails = new FlagEvaluationDetails<string>("my-flag", "foo", Constant.ErrorType.None, "STATIC", "default", flagMetadata: flagMetadata);
362+
363+
// Act
364+
await metricsHook.BeforeAsync(ctx, new Dictionary<string, object>()).ConfigureAwait(true);
365+
await metricsHook.FinallyAsync(ctx, evaluationDetails, new Dictionary<string, object>()).ConfigureAwait(true);
366+
367+
var measurements = collector.GetMeasurementSnapshot();
368+
369+
// Assert
370+
Assert.NotNull(measurements);
371+
Assert.Equal(2, measurements.Count);
372+
Assert.Equal(0, measurements.Sum(m => m.Value));
373+
374+
var beforeTagKeys = measurements[0].Tags.Keys.OrderBy(k => k).ToList();
375+
var finallyTagKeys = measurements[1].Tags.Keys.OrderBy(k => k).ToList();
376+
377+
Assert.Equal(beforeTagKeys, finallyTagKeys);
378+
}
379+
380+
[Fact]
381+
public async Task ActiveCounter_With_FlagMetadata_Before_Has_Null_Metadata_Test()
382+
{
383+
// Arrange
384+
var metricsHookOptions = MetricsHookOptions.CreateBuilder()
385+
.WithFlagEvaluationMetadata("boolean", m => m.GetBool("boolean"))
386+
.Build();
387+
388+
var metricsHook = new MetricsHook(metricsHookOptions);
389+
390+
using var collector = new MetricCollector<long>(metricsHook._evaluationActiveUpDownCounter);
391+
392+
var evaluationContext = EvaluationContext.Empty;
393+
var ctx = new HookContext<string>("my-flag", "foo", Constant.FlagValueType.String,
394+
new ClientMetadata("my-client", "1.0"), new Metadata("my-provider"), evaluationContext);
395+
396+
// Act - call BeforeAsync (no flag metadata available yet)
397+
await metricsHook.BeforeAsync(ctx, new Dictionary<string, object>()).ConfigureAwait(true);
398+
399+
var measurements = collector.LastMeasurement;
400+
401+
// Assert - should handle null metadata gracefully
402+
Assert.NotNull(measurements);
403+
Assert.Equal(1, measurements.Value);
404+
Assert.Equal("my-flag", measurements.Tags["feature_flag.key"]);
405+
Assert.Equal("my-provider", measurements.Tags["feature_flag.provider.name"]);
406+
Assert.Contains("boolean", measurements.Tags.Keys);
407+
Assert.Null(measurements.Tags["boolean"]);
408+
}
342409
}

0 commit comments

Comments
 (0)