123 lines
4.7 KiB
C#
123 lines
4.7 KiB
C#
// Copyright © 2025 StellaOps Contributors
|
|
// Licensed under AGPL-3.0-or-later
|
|
|
|
using FluentAssertions;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using StellaOps.Policy.Determinization;
|
|
using StellaOps.Policy.Determinization.Models;
|
|
using StellaOps.Policy.Determinization.Scoring;
|
|
using Xunit;
|
|
|
|
namespace StellaOps.Policy.Determinization.Tests.Integration;
|
|
|
|
[Trait("Category", "Unit")]
|
|
public sealed class ServiceRegistrationIntegrationTests
|
|
{
|
|
[Fact]
|
|
public void AddDeterminization_WithConfiguration_RegistersAllServices()
|
|
{
|
|
// Arrange
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(new Dictionary<string, string?>
|
|
{
|
|
["Determinization:ConfidenceHalfLifeDays"] = "21",
|
|
["Determinization:ConfidenceFloor"] = "0.15",
|
|
["Determinization:ManualReviewEntropyThreshold"] = "0.65",
|
|
["Determinization:SignalWeights:VexWeight"] = "0.30",
|
|
["Determinization:SignalWeights:EpssWeight"] = "0.15"
|
|
})
|
|
.Build();
|
|
|
|
var services = new ServiceCollection();
|
|
services.AddSingleton(TimeProvider.System);
|
|
services.AddLogging();
|
|
|
|
// Act
|
|
services.AddDeterminization(configuration);
|
|
var provider = services.BuildServiceProvider();
|
|
|
|
// Assert - verify all services are registered
|
|
provider.GetService<IUncertaintyScoreCalculator>().Should().NotBeNull();
|
|
provider.GetService<IDecayedConfidenceCalculator>().Should().NotBeNull();
|
|
provider.GetService<TrustScoreAggregator>().Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void AddDeterminization_WithConfigureAction_RegistersAllServices()
|
|
{
|
|
// Arrange
|
|
var services = new ServiceCollection();
|
|
services.AddSingleton(TimeProvider.System);
|
|
services.AddLogging();
|
|
|
|
// Act
|
|
services.AddDeterminization(options =>
|
|
{
|
|
// Options are immutable records, so can't mutate
|
|
// This tests that the configure action is called
|
|
});
|
|
var provider = services.BuildServiceProvider();
|
|
|
|
// Assert
|
|
provider.GetService<IUncertaintyScoreCalculator>().Should().NotBeNull();
|
|
provider.GetService<IDecayedConfidenceCalculator>().Should().NotBeNull();
|
|
provider.GetService<TrustScoreAggregator>().Should().NotBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void RegisteredServices_AreResolvableAndFunctional()
|
|
{
|
|
// Arrange
|
|
var configuration = new ConfigurationBuilder()
|
|
.AddInMemoryCollection(new Dictionary<string, string?>())
|
|
.Build();
|
|
|
|
var services = new ServiceCollection();
|
|
services.AddSingleton(TimeProvider.System);
|
|
services.AddLogging(b => b.AddProvider(NullLoggerProvider.Instance));
|
|
services.AddDeterminization(configuration);
|
|
var provider = services.BuildServiceProvider();
|
|
|
|
// Act - resolve and use services
|
|
var uncertaintyCalc = provider.GetRequiredService<IUncertaintyScoreCalculator>();
|
|
var decayCalc = provider.GetRequiredService<IDecayedConfidenceCalculator>();
|
|
var trustAgg = provider.GetRequiredService<TrustScoreAggregator>();
|
|
|
|
// Test uncertainty calculator
|
|
var snapshot = SignalSnapshot.Empty("CVE-2024-1234", "pkg:maven/test@1.0", DateTimeOffset.UtcNow);
|
|
|
|
// Assert - verify they work
|
|
var score = uncertaintyCalc.Calculate(snapshot);
|
|
score.Entropy.Should().Be(1.0); // All signals missing = maximum entropy
|
|
|
|
var decayed = decayCalc.Calculate(baseConfidence: 0.9, ageDays: 14.0, halfLifeDays: 14.0);
|
|
decayed.Should().BeApproximately(0.45, 0.01); // Half-life decay
|
|
|
|
// Trust aggregator requires an uncertainty score
|
|
var trust = trustAgg.Aggregate(snapshot, score);
|
|
trust.Should().BeInRange(0.0, 1.0);
|
|
}
|
|
|
|
[Fact]
|
|
public void RegisteredServices_AreSingletons()
|
|
{
|
|
// Arrange
|
|
var configuration = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>()).Build();
|
|
var services = new ServiceCollection();
|
|
services.AddSingleton(TimeProvider.System);
|
|
services.AddLogging();
|
|
services.AddDeterminization(configuration);
|
|
var provider = services.BuildServiceProvider();
|
|
|
|
// Act - resolve same service multiple times
|
|
var calc1 = provider.GetService<IUncertaintyScoreCalculator>();
|
|
var calc2 = provider.GetService<IUncertaintyScoreCalculator>();
|
|
|
|
// Assert - should be same instance (singleton)
|
|
calc1.Should().BeSameAs(calc2);
|
|
}
|
|
}
|