save progress

This commit is contained in:
StellaOps Bot
2026-01-03 00:47:24 +02:00
parent 3f197814c5
commit ca578801fd
319 changed files with 32478 additions and 2202 deletions

View File

@@ -10,6 +10,7 @@ namespace StellaOps.AirGap.Controller.Tests;
public class AirGapStateServiceTests
{
private static readonly DateTimeOffset FixedNow = new(2025, 12, 10, 9, 0, 0, TimeSpan.Zero);
private readonly AirGapStateService _service;
private readonly InMemoryAirGapStateStore _store = new();
private readonly StalenessCalculator _calculator = new();
@@ -23,7 +24,7 @@ public class AirGapStateServiceTests
[Fact]
public async Task Seal_sets_state_and_computes_staleness()
{
var now = DateTimeOffset.UtcNow;
var now = FixedNow;
var anchor = new TimeAnchor(now.AddMinutes(-2), "roughtime", "roughtime", "fp", "digest");
var budget = new StalenessBudget(60, 120);
@@ -42,7 +43,7 @@ public class AirGapStateServiceTests
[Fact]
public async Task Unseal_clears_sealed_flag_and_updates_timestamp()
{
var now = DateTimeOffset.UtcNow;
var now = FixedNow;
await _service.SealAsync("default", "hash", TimeAnchor.Unknown, StalenessBudget.Default, now);
var later = now.AddMinutes(1);
@@ -57,7 +58,7 @@ public class AirGapStateServiceTests
[Fact]
public async Task Seal_persists_drift_baseline_seconds()
{
var now = DateTimeOffset.UtcNow;
var now = FixedNow;
var anchor = new TimeAnchor(now.AddMinutes(-5), "roughtime", "roughtime", "fp", "digest");
var budget = StalenessBudget.Default;
@@ -70,7 +71,7 @@ public class AirGapStateServiceTests
[Fact]
public async Task Seal_creates_default_content_budgets_when_not_provided()
{
var now = DateTimeOffset.UtcNow;
var now = FixedNow;
var anchor = new TimeAnchor(now.AddMinutes(-1), "roughtime", "roughtime", "fp", "digest");
var budget = new StalenessBudget(120, 240);
@@ -86,7 +87,7 @@ public class AirGapStateServiceTests
[Fact]
public async Task Seal_uses_provided_content_budgets()
{
var now = DateTimeOffset.UtcNow;
var now = FixedNow;
var anchor = new TimeAnchor(now.AddMinutes(-1), "roughtime", "roughtime", "fp", "digest");
var budget = StalenessBudget.Default;
var contentBudgets = new Dictionary<string, StalenessBudget>
@@ -106,7 +107,7 @@ public class AirGapStateServiceTests
[Fact]
public async Task GetStatus_returns_per_content_staleness()
{
var now = DateTimeOffset.UtcNow;
var now = FixedNow;
var anchor = new TimeAnchor(now.AddSeconds(-45), "roughtime", "roughtime", "fp", "digest");
var budget = StalenessBudget.Default;
var contentBudgets = new Dictionary<string, StalenessBudget>
@@ -125,4 +126,20 @@ public class AirGapStateServiceTests
Assert.False(status.ContentStaleness["vex"].IsWarning); // 45s < 60s warning
Assert.False(status.ContentStaleness["policy"].IsWarning); // 45s < 100s warning
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task Seal_rejects_invalid_content_budgets()
{
var now = FixedNow;
var anchor = new TimeAnchor(now.AddMinutes(-1), "roughtime", "roughtime", "fp", "digest");
var budget = StalenessBudget.Default;
var contentBudgets = new Dictionary<string, StalenessBudget>
{
{ "advisories", new StalenessBudget(120, 60) }
};
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() =>
_service.SealAsync("tenant-invalid", "policy", anchor, budget, now, contentBudgets));
}
}