feat(metrics): Add new histograms for chunk latency, results, and sources in AdvisoryAiMetrics
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

feat(telemetry): Record chunk latency, result count, and source count in AdvisoryAiTelemetry

fix(endpoint): Include telemetry source count in advisory chunks endpoint response

test(metrics): Enhance WebServiceEndpointsTests to validate new metrics for chunk latency, results, and sources

refactor(tests): Update test utilities for Deno language analyzer tests

chore(tests): Add performance tests for AdvisoryGuardrail with scenarios and blocked phrases

docs: Archive Sprint 137 design document for scanner and surface enhancements
This commit is contained in:
master
2025-11-10 22:26:43 +02:00
parent 56c687253f
commit b059bc7675
22 changed files with 427 additions and 37 deletions

View File

@@ -11,10 +11,15 @@ namespace StellaOps.Scanner.Analyzers.Lang.Deno.Tests.Observations;
public sealed class DenoLanguageAnalyzerObservationTests
{
private readonly ITestOutputHelper _output;
public DenoLanguageAnalyzerObservationTests(ITestOutputHelper output)
=> _output = output;
[Fact]
public async Task AnalyzerStoresObservationPayloadInAnalysisStoreAsync()
{
var (root, envDenoDir) = DenoWorkspaceTestFixture.Create();
var (workspaceRoot, envDenoDir) = DenoWorkspaceTestFixture.Create();
var previousDenoDir = Environment.GetEnvironmentVariable("DENO_DIR");
try
@@ -23,7 +28,7 @@ public sealed class DenoLanguageAnalyzerObservationTests
var store = new ScanAnalysisStore();
var context = new LanguageAnalyzerContext(
root,
workspaceRoot,
TimeProvider.System,
usageHints: null,
services: null,
@@ -40,31 +45,31 @@ public sealed class DenoLanguageAnalyzerObservationTests
Assert.NotNull(payload.Metadata);
Assert.True(payload.Metadata!.ContainsKey("deno.observation.hash"));
using var document = JsonDocument.Parse(payload.Content.Span);
var root = document.RootElement;
using var document = JsonDocument.Parse(payload.Content.ToArray());
var observationRoot = document.RootElement;
var entrypoints = root.GetProperty("entrypoints").EnumerateArray().Select(element => element.GetString()).ToArray();
var entrypoints = observationRoot.GetProperty("entrypoints").EnumerateArray().Select(element => element.GetString()).ToArray();
Assert.Contains("src/main.ts", entrypoints);
var capabilities = root.GetProperty("capabilities").EnumerateArray().ToArray();
var capabilities = observationRoot.GetProperty("capabilities").EnumerateArray().ToArray();
Assert.Contains(capabilities, capability => capability.GetProperty("reason").GetString() == "builtin.deno.ffi");
Assert.Contains(capabilities, capability => capability.GetProperty("reason").GetString() == "builtin.node.worker_threads");
Assert.Contains(capabilities, capability => capability.GetProperty("reason").GetString() == "builtin.node.fs");
var dynamicImports = root.GetProperty("dynamicImports").EnumerateArray().Select(element => element.GetProperty("specifier").GetString()).ToArray();
var dynamicImports = observationRoot.GetProperty("dynamicImports").EnumerateArray().Select(element => element.GetProperty("specifier").GetString()).ToArray();
Assert.Contains("https://cdn.example.com/dynamic/mod.ts", dynamicImports);
var literalFetches = root.GetProperty("literalFetches").EnumerateArray().Select(element => element.GetProperty("url").GetString()).ToArray();
var literalFetches = observationRoot.GetProperty("literalFetches").EnumerateArray().Select(element => element.GetProperty("url").GetString()).ToArray();
Assert.Contains("https://api.example.com/data.json", literalFetches);
var bundles = root.GetProperty("bundles").EnumerateArray().ToArray();
var bundles = observationRoot.GetProperty("bundles").EnumerateArray().ToArray();
Assert.Contains(bundles, bundle => bundle.GetProperty("type").GetString() == "eszip");
Assert.Contains(bundles, bundle => bundle.GetProperty("type").GetString() == "deno-compile");
}
finally
{
Environment.SetEnvironmentVariable("DENO_DIR", previousDenoDir);
DenoWorkspaceTestFixture.Cleanup(root);
DenoWorkspaceTestFixture.Cleanup(workspaceRoot);
}
}
}