Files
git.stella-ops.org/src/__Libraries/__Tests/StellaOps.TestKit.Tests/ObservabilityContractTests.OTelContractAssert.cs

94 lines
2.8 KiB
C#

using System.Diagnostics;
using System.Linq;
using FluentAssertions;
using StellaOps.TestKit.Observability;
using Xunit;
namespace StellaOps.TestKit.Tests;
public sealed partial class ObservabilityContractTests
{
[Fact]
public void HasRequiredSpans_AllPresent_NoException()
{
using var source = new ActivitySource("TestSource");
using var capture = new OtelCapture("TestSource");
using (source.StartActivity("Span1")) { }
using (source.StartActivity("Span2")) { }
var act = () => OTelContractAssert.HasRequiredSpans(capture, "Span1", "Span2");
act.Should().NotThrow();
}
[Fact]
public void HasRequiredSpans_Missing_ThrowsContractViolation()
{
using var source = new ActivitySource("TestSource2");
using var capture = new OtelCapture("TestSource2");
using (source.StartActivity("Span1")) { }
var act = () => OTelContractAssert.HasRequiredSpans(capture, "Span1", "MissingSpan");
act.Should().Throw<ContractViolationException>()
.WithMessage("*MissingSpan*");
}
[Fact]
public void SpanHasAttributes_AllPresent_NoException()
{
using var source = new ActivitySource("TestSource3");
using var capture = new OtelCapture("TestSource3");
using (var activity = source.StartActivity("TestSpan"))
{
activity?.SetTag("user_id", "123");
activity?.SetTag("tenant_id", "acme");
}
var span = capture.CapturedActivities.First();
var act = () => OTelContractAssert.SpanHasAttributes(span, "user_id", "tenant_id");
act.Should().NotThrow();
}
[Fact]
public void SpanHasAttributes_Missing_ThrowsContractViolation()
{
using var source = new ActivitySource("TestSource4");
using var capture = new OtelCapture("TestSource4");
using (var activity = source.StartActivity("TestSpan"))
{
activity?.SetTag("user_id", "123");
}
var span = capture.CapturedActivities.First();
var act = () => OTelContractAssert.SpanHasAttributes(span, "user_id", "missing_attr");
act.Should().Throw<ContractViolationException>()
.WithMessage("*missing_attr*");
}
[Fact]
public void AttributeCardinality_WithinThreshold_NoException()
{
using var source = new ActivitySource("TestSource5");
using var capture = new OtelCapture("TestSource5");
for (int i = 0; i < 5; i++)
{
using (var activity = source.StartActivity($"Span{i}"))
{
activity?.SetTag("status", i % 3 == 0 ? "ok" : "error");
}
}
var act = () => OTelContractAssert.AttributeCardinality(capture, "status", maxCardinality: 10);
act.Should().NotThrow();
}
}