using FluentAssertions; using Xunit; namespace BluejayInfraLint.Tests; [Trait("Category", "Unit")] public sealed class OpenVoxServerDurabilityTests { private static readonly string Root = FindRepoRoot(); private static readonly string RunbookPath = Path.Combine(Root, "docs", "runbooks", "openvoxserver-quadlet-durability.md"); private static readonly string SmokePath = Path.Combine(Root, "scripts", "monitoring", "openvox-recreate-smoke.sh"); [Fact] public void Runbook_DocumentsHostArtifactAndNonArgoPath() { var runbook = File.ReadAllText(RunbookPath); runbook.Should().Contain("noc1 host artifact"); runbook.Should().Contain("not an ArgoCD application"); runbook.Should().Contain("systemctl cat openvoxserver"); runbook.Should().Contain("/etc/containers/systemd/openvoxserver.container"); } [Fact] public void Runbook_DocumentsCx12LiveApplyState() { var runbook = File.ReadAllText(RunbookPath); runbook.Should().Contain("Sprint 32 Cx-12"); runbook.Should().Contain("openvoxserver-safeconfig.service"); runbook.Should().Contain("/opt/puppet/r10k-deploy.sh"); runbook.Should().Contain("HEAD == origin/master"); } [Fact] public void SmokeScript_IsExplicitlyOptIn() { var smoke = File.ReadAllText(SmokePath); smoke.Should().Contain("OPENVOX_RECREATE_SMOKE"); smoke.Should().Contain("exit 64"); smoke.IndexOf("OPENVOX_RECREATE_SMOKE", StringComparison.Ordinal) .Should().BeLessThan(smoke.IndexOf("systemctl stop openvoxserver", StringComparison.Ordinal)); } [Fact] public void SmokeScript_RequiresGeneratedSystemdUnitBeforeRemovingContainer() { var smoke = File.ReadAllText(SmokePath); smoke.Should().Contain("systemctl cat openvoxserver"); smoke.Should().Contain("refusing to remove a container without a verified systemd recreate path"); smoke.IndexOf("systemctl cat openvoxserver", StringComparison.Ordinal) .Should().BeLessThan(smoke.IndexOf("podman rm openvoxserver", StringComparison.Ordinal)); } [Fact] public void Artifacts_DoNotStoreSecretsOrPaidRunnerLabels() { var forbidden = new[] { "BEGIN OPENSSH PRIVATE KEY", "BEGIN RSA PRIVATE KEY", "ubuntu-latest", "windows-latest", "macos-latest", }; var violations = new[] { RunbookPath, SmokePath } .SelectMany(path => { var text = File.ReadAllText(path); return forbidden .Where(token => text.Contains(token, StringComparison.OrdinalIgnoreCase)) .Select(token => $"{Path.GetRelativePath(Root, path)} contains forbidden token {token}"); }) .ToList(); violations.Should().BeEmpty(); } private static string FindRepoRoot() { var current = new DirectoryInfo(AppContext.BaseDirectory); while (current is not null) { if (Directory.Exists(Path.Combine(current.FullName, "apps")) && Directory.Exists(Path.Combine(current.FullName, "scripts")) && File.Exists(Path.Combine(current.FullName, "README.md"))) { return current.FullName; } current = current.Parent; } throw new DirectoryNotFoundException("Could not find bluejay-infra root."); } }