Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added RuntimeFactsNdjsonReader for reading NDJSON formatted runtime facts. - Introduced IRuntimeFactsIngestionService interface and its implementation. - Enhanced Program.cs to register new services and endpoints for runtime facts. - Updated CallgraphIngestionService to include CAS URI in stored artifacts. - Created RuntimeFactsValidationException for validation errors during ingestion. - Added tests for RuntimeFactsIngestionService and RuntimeFactsNdjsonReader. - Implemented SignalsSealedModeMonitor for compliance checks in sealed mode. - Updated project dependencies for testing utilities.
101 lines
2.9 KiB
C#
101 lines
2.9 KiB
C#
using System;
|
|
using System.IO;
|
|
using FluentAssertions;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using Microsoft.Extensions.Time.Testing;
|
|
using StellaOps.Signals.Hosting;
|
|
using StellaOps.Signals.Options;
|
|
using Xunit;
|
|
|
|
namespace StellaOps.Signals.Reachability.Tests;
|
|
|
|
public sealed class SignalsSealedModeMonitorTests : IDisposable
|
|
{
|
|
private readonly string tempDir = Path.Combine(Path.GetTempPath(), $"signals-sealed-tests-{Guid.NewGuid():N}");
|
|
|
|
[Fact]
|
|
public void IsCompliant_WhenEnforcementDisabled_ReturnsTrue()
|
|
{
|
|
var options = new SignalsOptions();
|
|
options.AirGap.SealedMode.EnforcementEnabled = false;
|
|
|
|
var monitor = CreateMonitor(options);
|
|
|
|
monitor.IsCompliant(out _).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void IsCompliant_WhenEvidenceMissing_ReturnsFalse()
|
|
{
|
|
var options = CreateEnforcedOptions();
|
|
options.AirGap.SealedMode.EvidencePath = Path.Combine(tempDir, "missing.json");
|
|
|
|
var monitor = CreateMonitor(options);
|
|
|
|
monitor.IsCompliant(out var reason).Should().BeFalse();
|
|
reason.Should().Contain("not found");
|
|
}
|
|
|
|
[Fact]
|
|
public void IsCompliant_WhenEvidenceFresh_ReturnsTrue()
|
|
{
|
|
var evidencePath = CreateEvidenceFile(TimeSpan.Zero);
|
|
var options = CreateEnforcedOptions();
|
|
options.AirGap.SealedMode.EvidencePath = evidencePath;
|
|
|
|
var monitor = CreateMonitor(options);
|
|
|
|
monitor.IsCompliant(out _).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void IsCompliant_WhenEvidenceStale_ReturnsFalse()
|
|
{
|
|
var evidencePath = CreateEvidenceFile(TimeSpan.FromHours(7));
|
|
var options = CreateEnforcedOptions();
|
|
options.AirGap.SealedMode.EvidencePath = evidencePath;
|
|
|
|
var monitor = CreateMonitor(options);
|
|
|
|
monitor.IsCompliant(out _).Should().BeFalse();
|
|
}
|
|
|
|
private SignalsOptions CreateEnforcedOptions()
|
|
{
|
|
var options = new SignalsOptions();
|
|
options.AirGap.SealedMode.EnforcementEnabled = true;
|
|
options.AirGap.SealedMode.MaxEvidenceAge = TimeSpan.FromHours(6);
|
|
options.AirGap.SealedMode.CacheLifetime = TimeSpan.FromSeconds(1);
|
|
return options;
|
|
}
|
|
|
|
private string CreateEvidenceFile(TimeSpan age)
|
|
{
|
|
Directory.CreateDirectory(tempDir);
|
|
var path = Path.Combine(tempDir, $"{Guid.NewGuid():N}.json");
|
|
File.WriteAllText(path, "{}");
|
|
if (age > TimeSpan.Zero)
|
|
{
|
|
File.SetLastWriteTimeUtc(path, DateTime.UtcNow - age);
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
private SignalsSealedModeMonitor CreateMonitor(SignalsOptions options)
|
|
{
|
|
return new SignalsSealedModeMonitor(
|
|
options,
|
|
new FakeTimeProvider(DateTimeOffset.UtcNow),
|
|
NullLogger<SignalsSealedModeMonitor>.Instance);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
}
|