Add root-aware privileged CI test lane
All checks were successful
smoke / smoke (push) Successful in 29s

This commit is contained in:
Vibe Myass
2026-03-16 04:36:14 +00:00
parent 481d70ce72
commit 3b523b78df
5 changed files with 133 additions and 7 deletions

View File

@@ -4,6 +4,58 @@ namespace LibNftables.Tests;
internal static class NativeTestSupport
{
private const string PrivilegedTestsEnvironmentVariable = "LIBNFTABLES_RUN_PRIVILEGED_TESTS";
internal static bool IsRunningAsRoot()
{
if (!OperatingSystem.IsLinux())
{
return false;
}
try
{
foreach (var line in File.ReadLines("/proc/self/status"))
{
if (!line.StartsWith("Uid:", StringComparison.Ordinal))
{
continue;
}
var parts = line["Uid:".Length..]
.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
return parts.Length > 0 && parts[0] == "0";
}
}
catch
{
// If uid probing fails, keep tests conservative.
}
return false;
}
internal static bool PrivilegedTestsRequested()
{
var value = Environment.GetEnvironmentVariable(PrivilegedTestsEnvironmentVariable);
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
return value.Equals("1", StringComparison.Ordinal)
|| value.Equals("true", StringComparison.OrdinalIgnoreCase)
|| value.Equals("yes", StringComparison.OrdinalIgnoreCase);
}
internal static bool ShouldRunPrivilegedTests()
{
return PrivilegedTestsRequested()
&& IsRunningAsRoot()
&& HasCapNetAdmin();
}
internal static bool HasCapNetAdmin()
{
const int capNetAdminBit = 12;

View File

@@ -53,6 +53,7 @@ public sealed class NftContextTests
}
[Fact]
[Trait("Category", "Privileged")]
public void ValidDryRunCommand_CanExecuteAndBufferOutput()
{
if (!NativeTestSupport.TryCreateContext(out var ctx))
@@ -60,7 +61,7 @@ public sealed class NftContextTests
return;
}
if (!NativeTestSupport.HasCapNetAdmin())
if (!NativeTestSupport.ShouldRunPrivilegedTests())
{
return;
}

View File

@@ -71,6 +71,27 @@ public sealed class NftablesClientIntegrationTests
}
}
[Fact]
[Trait("Category", "Privileged")]
public void Snapshot_WithPrivilegedLane_ReturnsRuleset()
{
if (!CanCreateClient())
{
return;
}
if (!NativeTestSupport.ShouldRunPrivilegedTests())
{
return;
}
var client = new NftablesClient();
NftSnapshot snapshot = client.Snapshot();
Assert.False(string.IsNullOrWhiteSpace(snapshot.RulesetText));
}
[Fact]
public void ValidateRuleset_WithTypedSetDefinition_ReturnsValidResult()
{