100 lines
3.5 KiB
C#
100 lines
3.5 KiB
C#
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.");
|
|
}
|
|
}
|