Files
git.stella-ops.org/src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/AdvisoryAiTelemetryTests.cs
master 61f963fd52
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Implement ledger metrics for observability and add tests for Ruby packages endpoints
- Added `LedgerMetrics` class to record write latency and total events for ledger operations.
- Created comprehensive tests for Ruby packages endpoints, covering scenarios for missing inventory, successful retrieval, and identifier handling.
- Introduced `TestSurfaceSecretsScope` for managing environment variables during tests.
- Developed `ProvenanceMongoExtensions` for attaching DSSE provenance and trust information to event documents.
- Implemented `EventProvenanceWriter` and `EventWriter` classes for managing event provenance in MongoDB.
- Established MongoDB indexes for efficient querying of events based on provenance and trust.
- Added models and JSON parsing logic for DSSE provenance and trust information.
2025-11-13 09:29:09 +02:00

81 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Concelier.WebService.Services;
using StellaOps.Concelier.WebService.Diagnostics;
using Xunit;
namespace StellaOps.Concelier.WebService.Tests;
public sealed class AdvisoryAiTelemetryTests : IDisposable
{
private readonly MeterListener _listener;
private readonly List<(long Value, KeyValuePair<string, object?>[] Tags)> _guardrailMeasurements = new();
public AdvisoryAiTelemetryTests()
{
_listener = new MeterListener
{
InstrumentPublished = (instrument, listener) =>
{
if (instrument.Meter.Name == AdvisoryAiMetrics.MeterName)
{
listener.EnableMeasurementEvents(instrument);
}
}
};
_listener.SetMeasurementEventCallback<long>((instrument, measurement, tags, state) =>
{
if (instrument.Meter.Name == AdvisoryAiMetrics.MeterName &&
instrument.Name == "advisory_ai_guardrail_blocks_total")
{
_guardrailMeasurements.Add((measurement, tags.ToArray()));
}
});
_listener.Start();
}
[Fact]
public void TrackChunkResult_RecordsGuardrailCounts_ForCacheHits()
{
var telemetry = new AdvisoryAiTelemetry(NullLogger<AdvisoryAiTelemetry>.Instance);
var guardrailCounts = new Dictionary<AdvisoryChunkGuardrailReason, int>
{
{ AdvisoryChunkGuardrailReason.BelowMinimumLength, 2 }
};
telemetry.TrackChunkResult(new AdvisoryAiChunkRequestTelemetry(
Tenant: "tenant-a",
AdvisoryKey: "CVE-2099-0001",
Result: "ok",
Truncated: false,
CacheHit: true,
ObservationCount: 1,
SourceCount: 1,
ChunkCount: 1,
Duration: TimeSpan.FromMilliseconds(5),
GuardrailCounts: guardrailCounts));
var measurement = Assert.Single(_guardrailMeasurements);
Assert.Equal(2, measurement.Value);
var cacheHitTagFound = false;
foreach (var tag in measurement.Tags)
{
if (tag.Key == "cache" && (string?)tag.Value == "hit")
{
cacheHitTagFound = true;
break;
}
}
Assert.True(cacheHitTagFound, "guardrail measurement should be tagged with cache hit outcome.");
}
public void Dispose()
{
_listener.Dispose();
}
}