using System.Collections.Generic; using System.Diagnostics.Metrics; using FluentAssertions; using StellaOps.TestKit.Observability; using Xunit; namespace StellaOps.TestKit.Tests; public sealed partial class ObservabilityContractTests { [Fact] public void MetricExists_Present_NoException() { using var meter = new Meter("TestMeter1"); using var capture = new MetricsCapture("TestMeter1"); var counter = meter.CreateCounter("test_requests_total"); counter.Add(1); var act = () => MetricsContractAssert.MetricExists(capture, "test_requests_total"); act.Should().NotThrow(); } [Fact] public void MetricExists_Missing_ThrowsContractViolation() { using var meter = new Meter("TestMeter2"); using var capture = new MetricsCapture("TestMeter2"); var counter = meter.CreateCounter("some_other_metric"); counter.Add(1); var act = () => MetricsContractAssert.MetricExists(capture, "missing_metric"); act.Should().Throw() .WithMessage("*missing_metric*not found*"); } [Fact] public void LabelCardinalityBounded_WithinThreshold_NoException() { using var meter = new Meter("TestMeter3"); using var capture = new MetricsCapture("TestMeter3"); var counter = meter.CreateCounter("http_requests_total"); counter.Add(1, new KeyValuePair("method", "GET")); counter.Add(1, new KeyValuePair("method", "POST")); var act = () => MetricsContractAssert.LabelCardinalityBounded( capture, "http_requests_total", maxLabels: 10); act.Should().NotThrow(); } [Fact] public void LabelCardinalityBounded_ExceedsThreshold_ThrowsContractViolation() { using var meter = new Meter("TestMeter4"); using var capture = new MetricsCapture("TestMeter4"); var counter = meter.CreateCounter("requests_by_user"); for (int i = 0; i < 10; i++) { counter.Add(1, new KeyValuePair("user_id", $"user-{i}")); } var act = () => MetricsContractAssert.LabelCardinalityBounded( capture, "requests_by_user", maxLabels: 5); act.Should().Throw() .WithMessage("*cardinality*exceeds*"); } }