Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Created project for StellaOps.Scanner.Analyzers.Native.Tests with necessary dependencies. - Documented roles and guidelines in AGENTS.md for Scheduler module. - Implemented IResolverJobService interface and InMemoryResolverJobService for handling resolver jobs. - Added ResolverBacklogNotifier and ResolverBacklogService for monitoring job metrics. - Developed API endpoints for managing resolver jobs and retrieving metrics. - Defined models for resolver job requests and responses. - Integrated dependency injection for resolver job services. - Implemented ImpactIndexSnapshot for persisting impact index data. - Introduced SignalsScoringOptions for configurable scoring weights in reachability scoring. - Added unit tests for ReachabilityScoringService and RuntimeFactsIngestionService. - Created dotnet-filter.sh script to handle command-line arguments for dotnet. - Established nuget-prime project for managing package downloads.
97 lines
3.8 KiB
C#
97 lines
3.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using StellaOps.Signals.Models;
|
|
using StellaOps.Signals.Persistence;
|
|
using StellaOps.Signals.Services;
|
|
using Xunit;
|
|
|
|
public class RuntimeFactsIngestionServiceTests
|
|
{
|
|
[Fact]
|
|
public async Task IngestAsync_AggregatesHits_AndRecomputesReachability()
|
|
{
|
|
var factRepository = new InMemoryReachabilityFactRepository();
|
|
var scoringService = new RecordingScoringService();
|
|
var service = new RuntimeFactsIngestionService(
|
|
factRepository,
|
|
TimeProvider.System,
|
|
scoringService,
|
|
NullLogger<RuntimeFactsIngestionService>.Instance);
|
|
|
|
var request = new RuntimeFactsIngestRequest
|
|
{
|
|
Subject = new ReachabilitySubject { Component = "web", Version = "2.1.0" },
|
|
CallgraphId = "cg-123",
|
|
Metadata = new Dictionary<string, string?> { { "source", "runtime" } },
|
|
Events = new List<RuntimeFactEvent>
|
|
{
|
|
new() { SymbolId = "svc.foo", HitCount = 2, Metadata = new Dictionary<string, string?> { { "pid", "12" } } },
|
|
new() { SymbolId = "svc.bar", HitCount = 1 },
|
|
new() { SymbolId = "svc.foo", HitCount = 3 }
|
|
}
|
|
};
|
|
|
|
var response = await service.IngestAsync(request, CancellationToken.None);
|
|
|
|
Assert.Equal("web|2.1.0", response.SubjectKey);
|
|
Assert.Equal("cg-123", response.CallgraphId);
|
|
|
|
var persisted = factRepository.Last ?? throw new Xunit.Sdk.XunitException("Fact not persisted");
|
|
Assert.Equal(2, persisted.RuntimeFacts?.Count);
|
|
|
|
var foo = persisted.RuntimeFacts?.Single(f => f.SymbolId == "svc.foo");
|
|
Assert.Equal(5, foo?.HitCount);
|
|
|
|
var bar = persisted.RuntimeFacts?.Single(f => f.SymbolId == "svc.bar");
|
|
Assert.Equal(1, bar?.HitCount);
|
|
|
|
var recorded = scoringService.LastRequest ?? throw new Xunit.Sdk.XunitException("Recompute not triggered");
|
|
Assert.Equal("cg-123", recorded.CallgraphId);
|
|
Assert.Contains("svc.foo", recorded.Targets);
|
|
Assert.Contains("svc.bar", recorded.RuntimeHits!);
|
|
Assert.Equal("runtime", recorded.Metadata?["source"]);
|
|
|
|
Assert.Equal("runtime", persisted.Metadata?["provenance.source"]);
|
|
Assert.Equal("cg-123", persisted.Metadata?["provenance.callgraphId"]);
|
|
Assert.NotNull(persisted.Metadata?["provenance.ingestedAt"]);
|
|
}
|
|
|
|
private sealed class InMemoryReachabilityFactRepository : IReachabilityFactRepository
|
|
{
|
|
public ReachabilityFactDocument? Last { get; private set; }
|
|
|
|
public Task<ReachabilityFactDocument?> GetBySubjectAsync(string subjectKey, CancellationToken cancellationToken)
|
|
{
|
|
return Task.FromResult(Last);
|
|
}
|
|
|
|
public Task<ReachabilityFactDocument> UpsertAsync(ReachabilityFactDocument document, CancellationToken cancellationToken)
|
|
{
|
|
Last = document;
|
|
return Task.FromResult(document);
|
|
}
|
|
}
|
|
|
|
private sealed class RecordingScoringService : IReachabilityScoringService
|
|
{
|
|
public ReachabilityRecomputeRequest? LastRequest { get; private set; }
|
|
|
|
public Task<ReachabilityFactDocument> RecomputeAsync(ReachabilityRecomputeRequest request, CancellationToken cancellationToken)
|
|
{
|
|
LastRequest = request;
|
|
return Task.FromResult(new ReachabilityFactDocument
|
|
{
|
|
CallgraphId = request.CallgraphId,
|
|
Subject = request.Subject,
|
|
SubjectKey = request.Subject?.ToSubjectKey() ?? string.Empty,
|
|
EntryPoints = request.EntryPoints,
|
|
States = new List<ReachabilityStateDocument>(),
|
|
RuntimeFacts = new List<RuntimeFactDocument>()
|
|
});
|
|
}
|
|
}
|
|
}
|