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,144 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using StellaOps.Concelier.Core.Jobs;
using StellaOps.Concelier.Merge.Identity;
using StellaOps.Concelier.Merge.Jobs;
namespace StellaOps.Concelier.Merge.Tests.Jobs;
public sealed class MergeHashBackfillJobTests
{
private readonly MergeHashBackfillJob _job;
public MergeHashBackfillJobTests()
{
var advisoryStore = new StellaOps.Concelier.Storage.Advisories.InMemoryAdvisoryStore();
var calculator = new Mock<IMergeHashCalculator>();
calculator.Setup(c => c.ComputeMergeHash(It.IsAny<StellaOps.Concelier.Models.Advisory>()))
.Returns("sha256:test");
var shadowWriteService = new MergeHashShadowWriteService(
advisoryStore,
calculator.Object,
NullLogger<MergeHashShadowWriteService>.Instance);
_job = new MergeHashBackfillJob(
shadowWriteService,
NullLogger<MergeHashBackfillJob>.Instance);
}
private static JobExecutionContext CreateContext(Dictionary<string, object?>? parameters = null)
{
var services = new ServiceCollection().BuildServiceProvider();
return new JobExecutionContext(
Guid.NewGuid(),
"merge-hash-backfill",
"manual",
parameters ?? new Dictionary<string, object?>(),
services,
TimeProvider.System,
NullLogger.Instance);
}
[Fact]
public async Task ExecuteAsync_NoSeed_CallsBackfillAll()
{
var context = CreateContext();
// Should not throw - runs BackfillAllAsync on empty store
await _job.ExecuteAsync(context, CancellationToken.None);
}
[Fact]
public async Task ExecuteAsync_WithSeed_CallsBackfillOne()
{
var context = CreateContext(new Dictionary<string, object?>
{
["seed"] = "CVE-2024-0001"
});
// Advisory not found, but should not throw (BackfillOneAsync returns false)
await _job.ExecuteAsync(context, CancellationToken.None);
}
[Fact]
public async Task ExecuteAsync_WithSeedAndForce_ParsesForceParameter()
{
var context = CreateContext(new Dictionary<string, object?>
{
["seed"] = "CVE-2024-0001",
["force"] = "true"
});
await _job.ExecuteAsync(context, CancellationToken.None);
}
[Fact]
public async Task ExecuteAsync_EmptySeed_FallsBackToAll()
{
var context = CreateContext(new Dictionary<string, object?>
{
["seed"] = ""
});
// Empty seed should fall through to BackfillAllAsync
await _job.ExecuteAsync(context, CancellationToken.None);
}
[Fact]
public async Task ExecuteAsync_WhitespaceSeed_FallsBackToAll()
{
var context = CreateContext(new Dictionary<string, object?>
{
["seed"] = " "
});
await _job.ExecuteAsync(context, CancellationToken.None);
}
[Fact]
public async Task ExecuteAsync_ForceNotTrue_DefaultsToFalse()
{
var context = CreateContext(new Dictionary<string, object?>
{
["seed"] = "CVE-2024-0001",
["force"] = "false"
});
await _job.ExecuteAsync(context, CancellationToken.None);
}
[Fact]
public async Task ExecuteAsync_ForceNotString_DefaultsToFalse()
{
var context = CreateContext(new Dictionary<string, object?>
{
["seed"] = "CVE-2024-0001",
["force"] = 42 // not a string
});
await _job.ExecuteAsync(context, CancellationToken.None);
}
// --- Constructor validation ---
[Fact]
public void Constructor_NullShadowWriteService_ThrowsArgumentNull()
{
Assert.Throws<ArgumentNullException>(() =>
new MergeHashBackfillJob(null!, NullLogger<MergeHashBackfillJob>.Instance));
}
[Fact]
public void Constructor_NullLogger_ThrowsArgumentNull()
{
var store = new StellaOps.Concelier.Storage.Advisories.InMemoryAdvisoryStore();
var calc = new Mock<IMergeHashCalculator>();
var svc = new MergeHashShadowWriteService(store, calc.Object, NullLogger<MergeHashShadowWriteService>.Instance);
Assert.Throws<ArgumentNullException>(() =>
new MergeHashBackfillJob(svc, null!));
}
}