more features checks. setup improvements

This commit is contained in:
master
2026-02-13 02:04:55 +02:00
parent 9911b7d73c
commit 9ca2de05df
675 changed files with 37550 additions and 1826 deletions

View File

@@ -0,0 +1,236 @@
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using StellaOps.Concelier.BackportProof.Models;
using StellaOps.Concelier.BackportProof.Repositories;
using StellaOps.Concelier.BackportProof.Services;
using Xunit;
namespace StellaOps.Concelier.BackportProof.Tests.Services;
public sealed class FixIndexServiceTests
{
private static readonly DateTimeOffset FixedTimestamp =
DateTimeOffset.Parse("2026-01-15T00:00:00Z");
private readonly Mock<IFixRuleRepository> _repository = new();
private FixIndexService CreateService() =>
new(_repository.Object, NullLogger<FixIndexService>.Instance);
[Fact]
public async Task GetActiveSnapshotId_Initially_ReturnsNull()
{
var sut = CreateService();
var id = await sut.GetActiveSnapshotIdAsync();
Assert.Null(id);
}
[Fact]
public async Task CreateSnapshot_ReturnsSnapshotWithLabel()
{
var sut = CreateService();
var snapshot = await sut.CreateSnapshotAsync("debian-2026-01-15");
Assert.Equal("debian-2026-01-15", snapshot.SourceLabel);
Assert.NotNull(snapshot.SnapshotId);
Assert.NotNull(snapshot.IndexDigest);
}
[Fact]
public async Task ActivateSnapshot_SetsActiveSnapshot()
{
var sut = CreateService();
var snapshot = await sut.CreateSnapshotAsync("test-label");
await sut.ActivateSnapshotAsync(snapshot.SnapshotId);
var activeId = await sut.GetActiveSnapshotIdAsync();
Assert.Equal(snapshot.SnapshotId, activeId);
}
[Fact]
public async Task ActivateSnapshot_InvalidId_Throws()
{
var sut = CreateService();
await Assert.ThrowsAsync<InvalidOperationException>(
() => sut.ActivateSnapshotAsync("nonexistent-snapshot-id").AsTask());
}
[Fact]
public async Task LookupAsync_NoActiveSnapshot_ReturnsEmpty()
{
var sut = CreateService();
var context = new ProductContext("debian", "bookworm", null, null);
var package = new PackageKey(PackageEcosystem.Deb, "curl", "curl");
var rules = await sut.LookupAsync(context, package, "CVE-2024-0001");
Assert.Empty(rules);
}
[Fact]
public async Task LookupAsync_WithActiveEmptySnapshot_ReturnsEmpty()
{
var sut = CreateService();
var snapshot = await sut.CreateSnapshotAsync("empty");
await sut.ActivateSnapshotAsync(snapshot.SnapshotId);
var context = new ProductContext("debian", "bookworm", null, null);
var package = new PackageKey(PackageEcosystem.Deb, "curl", "curl");
var rules = await sut.LookupAsync(context, package, "CVE-2024-0001");
Assert.Empty(rules);
}
[Fact]
public async Task LookupByPackageAsync_NoActiveSnapshot_ReturnsEmpty()
{
var sut = CreateService();
var context = new ProductContext("debian", "bookworm", null, null);
var package = new PackageKey(PackageEcosystem.Deb, "curl", "curl");
var rules = await sut.LookupByPackageAsync(context, package);
Assert.Empty(rules);
}
[Fact]
public async Task ListSnapshots_NoSnapshots_ReturnsEmpty()
{
var sut = CreateService();
var snapshots = await sut.ListSnapshotsAsync();
Assert.Empty(snapshots);
}
[Fact]
public async Task ListSnapshots_AfterCreate_ReturnsSnapshot()
{
var sut = CreateService();
var snapshot = await sut.CreateSnapshotAsync("test");
var listed = await sut.ListSnapshotsAsync();
Assert.Single(listed);
Assert.Equal(snapshot.SnapshotId, listed[0].SnapshotId);
Assert.False(listed[0].IsActive);
}
[Fact]
public async Task ListSnapshots_AfterActivate_MarksActive()
{
var sut = CreateService();
var snapshot = await sut.CreateSnapshotAsync("test");
await sut.ActivateSnapshotAsync(snapshot.SnapshotId);
var listed = await sut.ListSnapshotsAsync();
Assert.Single(listed);
Assert.True(listed[0].IsActive);
}
[Fact]
public async Task PruneOldSnapshots_KeepsRequestedCount()
{
var sut = CreateService();
await sut.CreateSnapshotAsync("snap-1");
await sut.CreateSnapshotAsync("snap-2");
await sut.CreateSnapshotAsync("snap-3");
await sut.PruneOldSnapshotsAsync(keepCount: 1);
var listed = await sut.ListSnapshotsAsync();
Assert.Single(listed);
}
[Fact]
public async Task PruneOldSnapshots_FewerThanKeepCount_DoesNothing()
{
var sut = CreateService();
await sut.CreateSnapshotAsync("snap-1");
await sut.PruneOldSnapshotsAsync(keepCount: 5);
var listed = await sut.ListSnapshotsAsync();
Assert.Single(listed);
}
[Fact]
public async Task GetStats_NoActiveSnapshot_ReturnsZeros()
{
var sut = CreateService();
var stats = await sut.GetStatsAsync();
Assert.Equal(0, stats.TotalRules);
Assert.Equal(0, stats.UniqueCves);
Assert.Equal(0, stats.UniquePackages);
Assert.Equal(0, stats.UniqueDistros);
Assert.Empty(stats.RulesByDistro);
Assert.Empty(stats.RulesByPriority);
Assert.Empty(stats.RulesByType);
}
[Fact]
public async Task GetStats_WithSnapshotId_ReturnsStatsForThatSnapshot()
{
var sut = CreateService();
var snapshot = await sut.CreateSnapshotAsync("stats-test");
var stats = await sut.GetStatsAsync(snapshot.SnapshotId);
Assert.Equal(0, stats.TotalRules);
}
[Fact]
public async Task GetStats_InvalidSnapshotId_ReturnsZeros()
{
var sut = CreateService();
var stats = await sut.GetStatsAsync("nonexistent");
Assert.Equal(0, stats.TotalRules);
}
[Fact]
public async Task CreateSnapshot_MultipleSnapshots_HaveUniqueIds()
{
var sut = CreateService();
var snap1 = await sut.CreateSnapshotAsync("snap-1");
var snap2 = await sut.CreateSnapshotAsync("snap-2");
Assert.NotEqual(snap1.SnapshotId, snap2.SnapshotId);
}
[Fact]
public async Task ActivateSnapshot_SwitchBetweenSnapshots()
{
var sut = CreateService();
var snap1 = await sut.CreateSnapshotAsync("first");
var snap2 = await sut.CreateSnapshotAsync("second");
await sut.ActivateSnapshotAsync(snap1.SnapshotId);
Assert.Equal(snap1.SnapshotId, await sut.GetActiveSnapshotIdAsync());
await sut.ActivateSnapshotAsync(snap2.SnapshotId);
Assert.Equal(snap2.SnapshotId, await sut.GetActiveSnapshotIdAsync());
}
[Fact]
public async Task CreateSnapshot_EmptyRules_DigestIsDeterministic()
{
var sut = CreateService();
var snap1 = await sut.CreateSnapshotAsync("test-1");
var snap2 = await sut.CreateSnapshotAsync("test-2");
// Both empty snapshots should have the same digest (SHA256 of empty sorted IDs)
Assert.Equal(snap1.IndexDigest, snap2.IndexDigest);
}
}