Files
nixos-router/tests/lib.nix
T
nilsandClaude Sonnet 5.5 c395a43a78 Add a static ULA per LAN, announced via SLAAC and RDNSS
lans.<n>.ipv6.address (a ULA /64) is assigned to the LAN, announced
with an explicit prefix (networkd only announces the delegated prefix
when prefix delegation is on) and advertised as RDNSS; Unbound listens
and answers on it. Checked at build time: valid IPv6 CIDR, /64, fc00::/7.

Covered by the onestick VM test (client SLAAC address, ping and DNS over
the ULA, RA captured on the wire), assertion cases and a unit test for
the /64 prefix helper.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 15:48:47 +01:00

181 lines
4.1 KiB
Nix

# Unit tests for modules/router/lib.nix, run at evaluation time.
{ pkgs }:
let
inherit (pkgs) lib;
r = import ../modules/router/lib.nix { inherit lib; };
inherit (r) ipv4;
ip = ipv4.parse;
inherit (r) ipv6;
failures = lib.runTests {
testPrefix64 = {
expr = map ipv6.prefix64 [
"fd2c:cdef:cde9::1/64"
"fd2c:cdef:cde9:1:2:3:4:5"
"fd00::1"
"fd12:3456:789a:bc::1/64"
"fd12::5:6"
];
expected = [
"fd2c:cdef:cde9:0::/64"
"fd2c:cdef:cde9:1::/64"
"fd00:0:0:0::/64"
"fd12:3456:789a:bc::/64"
"fd12:0:0:0::/64"
];
};
testParse = {
expr = ip "192.168.10.1";
expected = 3232238081;
};
testParseZero = {
expr = ip "0.0.0.0";
expected = 0;
};
testParseMax = {
expr = ip "255.255.255.255";
expected = 4294967295;
};
testParseBadOctet = {
expr = ip "192.168.10.256";
expected = null;
};
testParseShort = {
expr = ip "192.168.10";
expected = null;
};
testParseJunk = {
expr = ip "192.168.10.x";
expected = null;
};
testParseNetHost = {
expr = ipv4.parseNet "10.0.0.5";
expected = {
address = ip "10.0.0.5";
prefixLength = 32;
};
};
testParseNetCidr = {
expr = ipv4.parseNet "192.168.10.0/24";
expected = {
address = ip "192.168.10.0";
prefixLength = 24;
};
};
testParseNetZeroPrefix = {
expr = ipv4.parseNet "0.0.0.0/0";
expected = {
address = 0;
prefixLength = 0;
};
};
testParseNetPrefixTooLong = {
expr = ipv4.parseNet "10.0.0.0/33";
expected = null;
};
testParseNetBadAddress = {
expr = ipv4.parseNet "10.0.0.256/24";
expected = null;
};
testParseNetJunk = {
expr = ipv4.parseNet "10.0.0.0/x";
expected = null;
};
testFormatRoundTrip = {
expr = ipv4.format (ip "10.20.30.40");
expected = "10.20.30.40";
};
testFormatZero = {
expr = ipv4.format 0;
expected = "0.0.0.0";
};
testNetMask24 = {
expr = ipv4.format (ipv4.netMask 24);
expected = "255.255.255.0";
};
testNetMask20 = {
expr = ipv4.format (ipv4.netMask 20);
expected = "255.255.240.0";
};
testNetMask8 = {
expr = ipv4.format (ipv4.netMask 8);
expected = "255.0.0.0";
};
testCidr24 = {
expr = ipv4.cidr "192.168.10.77" 24;
expected = "192.168.10.0/24";
};
testCidr20 = {
expr = ipv4.cidr "172.16.37.1" 20;
expected = "172.16.32.0/20";
};
testCidr30 = {
expr = ipv4.cidr "10.0.0.6" 30;
expected = "10.0.0.4/30";
};
testInSubnetYes = {
expr = ipv4.inSubnet {
address = ip "192.168.10.1";
prefixLength = 24;
} (ip "192.168.10.200");
expected = true;
};
testInSubnetNo = {
expr = ipv4.inSubnet {
address = ip "192.168.10.1";
prefixLength = 24;
} (ip "192.168.11.1");
expected = false;
};
testOverlapNested = {
expr =
ipv4.overlaps
{
address = ip "10.0.0.1";
prefixLength = 8;
}
{
address = ip "10.1.2.3";
prefixLength = 24;
};
expected = true;
};
testOverlapSame = {
expr =
ipv4.overlaps
{
address = ip "192.168.10.1";
prefixLength = 24;
}
{
address = ip "192.168.10.9";
prefixLength = 24;
};
expected = true;
};
testOverlapDisjoint = {
expr =
ipv4.overlaps
{
address = ip "192.168.10.1";
prefixLength = 24;
}
{
address = ip "192.168.11.1";
prefixLength = 24;
};
expected = false;
};
};
in
pkgs.runCommand "router-lib-tests" { } (
if failures == [ ] then
"touch $out"
else
''
echo ${lib.escapeShellArg (lib.generators.toPretty { } failures)} >&2
exit 1
''
)