feat: Add initial implementation of Vulnerability Resolver Jobs
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.
This commit is contained in:
master
2025-11-18 07:52:15 +02:00
parent e69b57d467
commit 8355e2ff75
299 changed files with 13293 additions and 2444 deletions

View File

@@ -0,0 +1,96 @@
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>()
});
}
}
}