Files
libnftables-dotnet/tests/LibNftables.Tests/NftablesClientIntegrationTests.cs
Vibe Myass 3b523b78df
All checks were successful
smoke / smoke (push) Successful in 29s
Add root-aware privileged CI test lane
2026-03-16 04:36:14 +00:00

211 lines
5.5 KiB
C#

namespace LibNftables.Tests;
public sealed class NftablesClientIntegrationTests
{
[Fact]
public void Validate_InvalidRuleset_ReturnsInvalidResult()
{
if (!CanCreateClient())
{
return;
}
var client = new NftablesClient();
var request = NftApplyRequest.FromText("this is not valid nft syntax");
NftValidationResult result = client.Validate(request);
Assert.False(result.IsValid);
Assert.False(string.IsNullOrWhiteSpace(result.Diagnostics));
}
[Fact]
public async Task ValidateAsync_InvalidRuleset_ReturnsInvalidResult()
{
if (!CanCreateClient())
{
return;
}
var client = new NftablesClient();
var request = NftApplyRequest.FromText("this is not valid nft syntax");
NftValidationResult result = await client.ValidateAsync(request);
Assert.False(result.IsValid);
Assert.False(string.IsNullOrWhiteSpace(result.Diagnostics));
}
[Fact]
public void Apply_InvalidRuleset_ThrowsValidationException()
{
if (!CanCreateClient())
{
return;
}
var client = new NftablesClient();
var request = NftApplyRequest.FromText("this is not valid nft syntax");
Assert.Throws<NftValidationException>(() => client.Apply(request));
}
[Fact]
public void Snapshot_WithInsufficientPrivileges_ThrowsPermissionOrReturnsRuleset()
{
if (!CanCreateClient())
{
return;
}
var client = new NftablesClient();
try
{
NftSnapshot snapshot = client.Snapshot();
Assert.False(string.IsNullOrWhiteSpace(snapshot.RulesetText));
}
catch (NftPermissionException)
{
// Expected in unprivileged environments.
}
}
[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()
{
if (!CanCreateClient())
{
return;
}
var client = new NftablesClient();
var ruleset = new NftRuleset();
var table = new NftTable
{
Family = NftFamily.Inet,
Name = "typed_validation",
};
var set = new NftSet
{
Name = "blocked_ipv4",
Type = NftSetType.Ipv4Address,
};
set.Elements.Add(NftValue.Address(System.Net.IPAddress.Parse("10.0.0.1")));
set.Elements.Add(NftValue.Address(System.Net.IPAddress.Parse("10.0.0.2")));
table.Sets.Add(set);
var chain = new NftChain
{
Name = "input",
Type = NftChainType.Filter,
Hook = NftHook.Input,
Priority = 0,
Policy = NftChainPolicy.Drop,
};
chain.Rules.Add(new NftRule
{
SourceAddressSetName = "blocked_ipv4",
TransportProtocol = NftTransportProtocol.Tcp,
DestinationPort = NftValue.Port(22),
Verdict = NftVerdict.Accept,
});
table.Chains.Add(chain);
ruleset.Tables.Add(table);
NftValidationResult result = client.ValidateRuleset(ruleset);
Assert.True(result.IsValid);
}
[Fact]
public void ValidateAndRenderRuleset_WithTypedMapAndRule_ReturnsValidResult()
{
if (!CanCreateClient())
{
return;
}
var client = new NftablesClient();
var ruleset = new NftRuleset();
var table = new NftTable
{
Family = NftFamily.Inet,
Name = "typed_preview",
};
var set = new NftSet
{
Name = "blocked_ipv4",
Type = NftSetType.Ipv4Address,
};
set.Elements.Add(NftValue.Address(System.Net.IPAddress.Parse("10.0.0.1")));
table.Sets.Add(set);
var map = new NftMap
{
Name = "service_policy",
KeyType = NftMapType.InetService,
ValueType = NftMapType.Verdict,
};
map.Add(NftValue.Port(80), NftValue.Verdict(NftVerdict.Accept));
table.Maps.Add(map);
var chain = new NftChain
{
Name = "input",
Type = NftChainType.Filter,
Hook = NftHook.Input,
Priority = 0,
};
chain.Rules.Add(new NftRule
{
SourceAddressSetName = "blocked_ipv4",
TransportProtocol = NftTransportProtocol.Tcp,
DestinationPort = NftValue.Port(22),
Verdict = NftVerdict.Accept,
});
table.Chains.Add(chain);
ruleset.Tables.Add(table);
NftRenderedValidationResult result = client.ValidateAndRenderRuleset(ruleset);
Assert.True(result.ValidationResult.IsValid);
Assert.Contains("add map inet typed_preview service_policy", result.RenderedRulesetText, StringComparison.Ordinal);
}
private static bool CanCreateClient()
{
try
{
_ = new NftablesClient();
return true;
}
catch (NftException)
{
return false;
}
}
}