Files
git.stella-ops.org/src/Policy/__Tests/StellaOps.Policy.Engine.Tests/PolicyWorkerServiceTests.cs
2026-01-08 08:54:27 +02:00

81 lines
2.9 KiB
C#

using Xunit;
using Microsoft.Extensions.Time.Testing;
using StellaOps.Policy.Engine.Orchestration;
using StellaOps.TestKit;
namespace StellaOps.Policy.Engine.Tests;
public sealed class PolicyWorkerServiceTests
{
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ExecuteAsync_ReturnsDeterministicResults()
{
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T13:00:00Z"));
var jobStore = new InMemoryOrchestratorJobStore();
var resultStore = new InMemoryWorkerResultStore(jobStore);
var service = new PolicyWorkerService(clock, jobStore, resultStore);
var job = new OrchestratorJob(
JobId: "01HZX1QJP6Z3MNA0Q2T3VCPV5K",
TenantId: "tenant",
ContextId: "ctx",
PolicyProfileHash: "hash",
RequestedAt: clock.GetUtcNow(),
Priority: "normal",
BatchItems: new[]
{
new OrchestratorJobItem("pkg:npm/alpha@1.0.0", "ADV-1"),
new OrchestratorJobItem("pkg:npm/zeta@1.0.0", "ADV-2")
},
Callbacks: null,
TraceRef: "trace",
Status: "queued",
DeterminismHash: "hash-determinism");
await jobStore.SaveAsync(job);
var result = await service.ExecuteAsync(new WorkerRunRequest(job.JobId), TestContext.Current.CancellationToken);
Assert.Equal(job.JobId, result.JobId);
Assert.Equal("worker-stub", result.WorkerId);
Assert.Equal(2, result.Results.Count);
Assert.True(result.Results.All(r => !string.IsNullOrWhiteSpace(r.Status)));
var fetched = await resultStore.GetByJobIdAsync(job.JobId);
Assert.NotNull(fetched);
Assert.Equal(result.ResultHash, fetched!.ResultHash);
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ExecuteAsync_IsIdempotentOnRetry()
{
var clock = new FakeTimeProvider(DateTimeOffset.Parse("2025-11-24T14:00:00Z"));
var jobStore = new InMemoryOrchestratorJobStore();
var resultStore = new InMemoryWorkerResultStore(jobStore);
var service = new PolicyWorkerService(clock, jobStore, resultStore);
var job = new OrchestratorJob(
JobId: "job-id",
TenantId: "tenant",
ContextId: "ctx",
PolicyProfileHash: "hash",
RequestedAt: clock.GetUtcNow(),
Priority: "normal",
BatchItems: new[] { new OrchestratorJobItem("pkg:a", "ADV-1") },
Callbacks: null,
TraceRef: "trace",
Status: "queued",
DeterminismHash: "hash");
await jobStore.SaveAsync(job);
var first = await service.ExecuteAsync(new WorkerRunRequest(job.JobId));
var second = await service.ExecuteAsync(new WorkerRunRequest(job.JobId));
Assert.Equal(first.ResultHash, second.ResultHash);
Assert.Equal(first.CompletedAt, second.CompletedAt);
}
}