nixosTests.yggdrasil: migrate to runTest

Part Of #386873
This commit is contained in:
Martin Weinelt 2025-03-14 22:59:07 +01:00
parent 8667777300
commit 04a03a5c8c
No known key found for this signature in database
GPG key ID: 87C1E9888F856759
2 changed files with 141 additions and 145 deletions

View file

@ -1300,7 +1300,7 @@ in {
xxh = handleTest ./xxh.nix {};
yabar = handleTest ./yabar.nix {};
ydotool = handleTest ./ydotool.nix {};
yggdrasil = handleTest ./yggdrasil.nix {};
yggdrasil = runTest ./yggdrasil.nix;
your_spotify = runTest ./your_spotify.nix;
zammad = runTest ./zammad.nix;
zenohd = runTest ./zenohd.nix;

View file

@ -25,173 +25,169 @@ let
danIp6 = bobPrefix + "::2";
in
import ./make-test-python.nix (
{ pkgs, ... }:
{
name = "yggdrasil";
meta = with pkgs.lib.maintainers; {
maintainers = [ gazally ];
};
{ pkgs, ... }:
{
name = "yggdrasil";
meta = with pkgs.lib.maintainers; {
maintainers = [ gazally ];
};
nodes = rec {
# Alice is listening for peerings on a specified port,
# but has multicast peering disabled. Alice has part of her
# yggdrasil config in Nix and part of it in a file.
alice =
{ ... }:
{
networking = {
interfaces.eth1.ipv4.addresses = [
{
address = "192.168.1.200";
prefixLength = 24;
}
];
firewall.allowedTCPPorts = [
80
12345
];
nodes = {
# Alice is listening for peerings on a specified port,
# but has multicast peering disabled. Alice has part of her
# yggdrasil config in Nix and part of it in a file.
alice =
{ ... }:
{
networking = {
interfaces.eth1.ipv4.addresses = [
{
address = "192.168.1.200";
prefixLength = 24;
}
];
firewall.allowedTCPPorts = [
80
12345
];
};
services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org";
services.yggdrasil = {
enable = true;
settings = {
Listen = [ "tcp://0.0.0.0:12345" ];
MulticastInterfaces = [ ];
};
services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org";
configFile = toString (
pkgs.writeTextFile {
name = "yggdrasil-alice-conf";
text = builtins.toJSON aliceKeys;
}
);
};
};
services.yggdrasil = {
enable = true;
settings = {
Listen = [ "tcp://0.0.0.0:12345" ];
MulticastInterfaces = [ ];
};
configFile = toString (
pkgs.writeTextFile {
name = "yggdrasil-alice-conf";
text = builtins.toJSON aliceKeys;
# Bob is set up to peer with Alice, and also to do local multicast
# peering. Bob's yggdrasil config is in a file.
bob =
{ ... }:
{
networking.firewall.allowedTCPPorts = [ 54321 ];
services.yggdrasil = {
enable = true;
openMulticastPort = true;
configFile = toString (
pkgs.writeTextFile {
name = "yggdrasil-bob-conf";
text = builtins.toJSON bobConfig;
}
);
};
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
networking = {
bridges.br0.interfaces = [ ];
interfaces.br0 = {
ipv6.addresses = [
{
address = bobPrefix + "::1";
prefixLength = 64;
}
);
];
};
};
# Bob is set up to peer with Alice, and also to do local multicast
# peering. Bob's yggdrasil config is in a file.
bob =
{ ... }:
{
networking.firewall.allowedTCPPorts = [ 54321 ];
services.yggdrasil = {
enable = true;
openMulticastPort = true;
configFile = toString (
pkgs.writeTextFile {
name = "yggdrasil-bob-conf";
text = builtins.toJSON bobConfig;
}
);
};
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
networking = {
bridges.br0.interfaces = [ ];
interfaces.br0 = {
ipv6.addresses = [
# dan is a node inside a container running on bob's host.
containers.dan = {
autoStart = true;
privateNetwork = true;
hostBridge = "br0";
config = {
networking.interfaces.eth0.ipv6 = {
addresses = [
{
address = bobPrefix + "::1";
address = bobPrefix + "::2";
prefixLength = 64;
}
];
};
};
# dan is a node inside a container running on bob's host.
containers.dan = {
autoStart = true;
privateNetwork = true;
hostBridge = "br0";
config =
{ config, pkgs, ... }:
{
networking.interfaces.eth0.ipv6 = {
addresses = [
{
address = bobPrefix + "::2";
prefixLength = 64;
}
];
routes = [
{
address = "200::";
prefixLength = 7;
via = bobPrefix + "::1";
}
];
};
services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org";
networking.firewall.allowedTCPPorts = [ 80 ];
};
};
};
# Carol only does local peering. Carol's yggdrasil config is all Nix.
carol =
{ ... }:
{
networking.firewall.allowedTCPPorts = [ 43210 ];
services.yggdrasil = {
enable = true;
extraArgs = [
"-loglevel"
"error"
];
denyDhcpcdInterfaces = [ "ygg0" ];
settings = {
IfTAPMode = true;
IfName = "ygg0";
MulticastInterfaces = [
routes = [
{
Port = 43210;
address = "200::";
prefixLength = 7;
via = bobPrefix + "::1";
}
];
openMulticastPort = true;
};
persistentKeys = true;
services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org";
networking.firewall.allowedTCPPorts = [ 80 ];
};
};
};
};
testScript = ''
import re
# Carol only does local peering. Carol's yggdrasil config is all Nix.
carol =
{ ... }:
{
networking.firewall.allowedTCPPorts = [ 43210 ];
services.yggdrasil = {
enable = true;
extraArgs = [
"-loglevel"
"error"
];
denyDhcpcdInterfaces = [ "ygg0" ];
settings = {
IfTAPMode = true;
IfName = "ygg0";
MulticastInterfaces = [
{
Port = 43210;
}
];
openMulticastPort = true;
};
persistentKeys = true;
};
};
};
# Give Alice a head start so she is ready when Bob calls.
alice.start()
alice.wait_for_unit("yggdrasil.service")
testScript = ''
import re
bob.start()
carol.start()
bob.wait_for_unit("default.target")
carol.wait_for_unit("yggdrasil.service")
# Give Alice a head start so she is ready when Bob calls.
alice.start()
alice.wait_for_unit("yggdrasil.service")
ip_addr_show = "ip -o -6 addr show dev ygg0 scope global"
carol.wait_until_succeeds(f"[ `{ip_addr_show} | grep -v tentative | wc -l` -ge 1 ]")
carol_ip6 = re.split(" +|/", carol.succeed(ip_addr_show))[3]
bob.start()
carol.start()
bob.wait_for_unit("default.target")
carol.wait_for_unit("yggdrasil.service")
# If Alice can talk to Carol, then Bob's outbound peering and Carol's
# local peering have succeeded and everybody is connected.
alice.wait_until_succeeds(f"ping -c 1 {carol_ip6}")
alice.succeed("ping -c 1 ${bobIp6}")
ip_addr_show = "ip -o -6 addr show dev ygg0 scope global"
carol.wait_until_succeeds(f"[ `{ip_addr_show} | grep -v tentative | wc -l` -ge 1 ]")
carol_ip6 = re.split(" +|/", carol.succeed(ip_addr_show))[3]
bob.succeed("ping -c 1 ${aliceIp6}")
bob.succeed(f"ping -c 1 {carol_ip6}")
# If Alice can talk to Carol, then Bob's outbound peering and Carol's
# local peering have succeeded and everybody is connected.
alice.wait_until_succeeds(f"ping -c 1 {carol_ip6}")
alice.succeed("ping -c 1 ${bobIp6}")
carol.succeed("ping -c 1 ${aliceIp6}")
carol.succeed("ping -c 1 ${bobIp6}")
carol.succeed("ping -c 1 ${bobPrefix}::1")
carol.succeed("ping -c 8 ${danIp6}")
bob.succeed("ping -c 1 ${aliceIp6}")
bob.succeed(f"ping -c 1 {carol_ip6}")
carol.fail("journalctl -u dhcpcd | grep ygg0")
carol.succeed("ping -c 1 ${aliceIp6}")
carol.succeed("ping -c 1 ${bobIp6}")
carol.succeed("ping -c 1 ${bobPrefix}::1")
carol.succeed("ping -c 8 ${danIp6}")
alice.wait_for_unit("httpd.service")
carol.succeed("curl --fail -g http://[${aliceIp6}]")
carol.succeed("curl --fail -g http://[${danIp6}]")
'';
}
)
carol.fail("journalctl -u dhcpcd | grep ygg0")
alice.wait_for_unit("httpd.service")
carol.succeed("curl --fail -g http://[${aliceIp6}]")
carol.succeed("curl --fail -g http://[${danIp6}]")
'';
}