diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index fc7ea0a75ae7..c860c8a6a782 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -190,7 +190,7 @@ in { avahi = handleTest ./avahi.nix {}; avahi-with-resolved = handleTest ./avahi.nix { networkd = true; }; ayatana-indicators = runTest ./ayatana-indicators.nix; - babeld = handleTest ./babeld.nix {}; + babeld = runTest ./babeld.nix; bazarr = handleTest ./bazarr.nix {}; bcachefs = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bcachefs.nix {}; beanstalkd = handleTest ./beanstalkd.nix {}; @@ -212,7 +212,7 @@ in { boot-stage2 = handleTest ./boot-stage2.nix {}; borgbackup = handleTest ./borgbackup.nix {}; borgmatic = handleTest ./borgmatic.nix {}; - botamusique = handleTest ./botamusique.nix {}; + botamusique = runTest ./botamusique.nix; bpf = handleTestOn ["x86_64-linux" "aarch64-linux"] ./bpf.nix {}; bpftune = handleTest ./bpftune.nix {}; breitbandmessung = handleTest ./breitbandmessung.nix {}; @@ -460,7 +460,7 @@ in { gnupg = handleTest ./gnupg.nix {}; goatcounter = handleTest ./goatcounter.nix {}; go-camo = handleTest ./go-camo.nix { }; - go-neb = handleTest ./go-neb.nix {}; + go-neb = runTest ./go-neb.nix; gobgpd = handleTest ./gobgpd.nix {}; gocd-agent = handleTest ./gocd-agent.nix {}; gocd-server = handleTest ./gocd-server.nix {}; @@ -575,7 +575,7 @@ in { kavita = handleTest ./kavita.nix {}; kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {}; kbd-update-search-paths-patch = handleTest ./kbd-update-search-paths-patch.nix {}; - kea = handleTest ./kea.nix {}; + kea = runTest ./kea.nix; keepalived = handleTest ./keepalived.nix {}; keepassxc = handleTest ./keepassxc.nix {}; kerberos = handleTest ./kerberos/default.nix {}; @@ -589,7 +589,7 @@ in { keymap = handleTest ./keymap.nix {}; kimai = handleTest ./kimai.nix {}; kmonad = runTest ./kmonad.nix; - knot = handleTest ./knot.nix {}; + knot = runTest ./knot.nix; komga = handleTest ./komga.nix {}; krb5 = discoverTests (import ./krb5); ksm = handleTest ./ksm.nix {}; @@ -903,7 +903,7 @@ in { phylactery = handleTest ./web-apps/phylactery.nix {}; pict-rs = handleTest ./pict-rs.nix {}; pingvin-share = handleTest ./pingvin-share.nix {} ; - pinnwand = handleTest ./pinnwand.nix {}; + pinnwand = runTest ./pinnwand.nix; plantuml-server = handleTest ./plantuml-server.nix {}; plasma-bigscreen = handleTest ./plasma-bigscreen.nix {}; plasma5 = handleTest ./plasma5.nix {}; @@ -1036,7 +1036,7 @@ in { slurm = handleTest ./slurm.nix {}; snmpd = handleTest ./snmpd.nix {}; smokeping = handleTest ./smokeping.nix {}; - snapcast = handleTest ./snapcast.nix {}; + snapcast = runTest ./snapcast.nix; snapper = handleTest ./snapper.nix {}; snipe-it = runTest ./web-apps/snipe-it.nix; soapui = handleTest ./soapui.nix {}; diff --git a/nixos/tests/babeld.nix b/nixos/tests/babeld.nix index 8b2ee35370a2..4f536de2a7a5 100644 --- a/nixos/tests/babeld.nix +++ b/nixos/tests/babeld.nix @@ -1,210 +1,211 @@ -import ./make-test-python.nix ( - { pkgs, lib, ... }: - { - name = "babeld"; - meta = with pkgs.lib.maintainers; { - maintainers = [ hexa ]; - }; +{ + pkgs, + ... +}: +{ + name = "babeld"; + meta = with pkgs.lib.maintainers; { + maintainers = [ hexa ]; + }; - nodes = { - client = - { pkgs, lib, ... }: - { - virtualisation.vlans = [ 10 ]; + nodes = { + client = + { lib, ... }: + { + virtualisation.vlans = [ 10 ]; - networking = { - useDHCP = false; - interfaces."eth1" = { - ipv4.addresses = lib.mkForce [ - { - address = "192.168.10.2"; - prefixLength = 24; - } - ]; - ipv4.routes = lib.mkForce [ - { - address = "0.0.0.0"; - prefixLength = 0; - via = "192.168.10.1"; - } - ]; - ipv6.addresses = lib.mkForce [ - { - address = "2001:db8:10::2"; - prefixLength = 64; - } - ]; - ipv6.routes = lib.mkForce [ - { - address = "::"; - prefixLength = 0; - via = "2001:db8:10::1"; - } - ]; - }; + networking = { + useDHCP = false; + interfaces."eth1" = { + ipv4.addresses = lib.mkForce [ + { + address = "192.168.10.2"; + prefixLength = 24; + } + ]; + ipv4.routes = lib.mkForce [ + { + address = "0.0.0.0"; + prefixLength = 0; + via = "192.168.10.1"; + } + ]; + ipv6.addresses = lib.mkForce [ + { + address = "2001:db8:10::2"; + prefixLength = 64; + } + ]; + ipv6.routes = lib.mkForce [ + { + address = "::"; + prefixLength = 0; + via = "2001:db8:10::1"; + } + ]; + }; + }; + }; + + local_router = + { lib, ... }: + { + virtualisation.vlans = [ + 10 + 20 + ]; + + networking = { + useDHCP = false; + firewall.enable = false; + + interfaces."eth1" = { + ipv4.addresses = lib.mkForce [ + { + address = "192.168.10.1"; + prefixLength = 24; + } + ]; + ipv6.addresses = lib.mkForce [ + { + address = "2001:db8:10::1"; + prefixLength = 64; + } + ]; + }; + + interfaces."eth2" = { + ipv4.addresses = lib.mkForce [ + { + address = "192.168.20.1"; + prefixLength = 24; + } + ]; + ipv6.addresses = lib.mkForce [ + { + address = "2001:db8:20::1"; + prefixLength = 64; + } + ]; }; }; - local_router = - { pkgs, lib, ... }: - { - virtualisation.vlans = [ - 10 - 20 - ]; + services.babeld = { + enable = true; + interfaces.eth2 = { + hello-interval = 1; + type = "wired"; + }; + extraConfig = '' + local-port-readwrite 33123 - networking = { - useDHCP = false; - firewall.enable = false; + import-table 254 # main + export-table 254 # main - interfaces."eth1" = { - ipv4.addresses = lib.mkForce [ - { - address = "192.168.10.1"; - prefixLength = 24; - } - ]; - ipv6.addresses = lib.mkForce [ - { - address = "2001:db8:10::1"; - prefixLength = 64; - } - ]; - }; + in ip 192.168.10.0/24 deny + in ip 192.168.20.0/24 deny + in ip 2001:db8:10::/64 deny + in ip 2001:db8:20::/64 deny - interfaces."eth2" = { - ipv4.addresses = lib.mkForce [ - { - address = "192.168.20.1"; - prefixLength = 24; - } - ]; - ipv6.addresses = lib.mkForce [ - { - address = "2001:db8:20::1"; - prefixLength = 64; - } - ]; - }; + in ip 192.168.30.0/24 allow + in ip 2001:db8:30::/64 allow + + in deny + + redistribute local proto 2 + redistribute local deny + ''; + }; + }; + remote_router = + { lib, ... }: + { + virtualisation.vlans = [ + 20 + 30 + ]; + + networking = { + useDHCP = false; + firewall.enable = false; + + interfaces."eth1" = { + ipv4.addresses = lib.mkForce [ + { + address = "192.168.20.2"; + prefixLength = 24; + } + ]; + ipv6.addresses = lib.mkForce [ + { + address = "2001:db8:20::2"; + prefixLength = 64; + } + ]; }; - services.babeld = { - enable = true; - interfaces.eth2 = { - hello-interval = 1; - type = "wired"; - }; - extraConfig = '' - local-port-readwrite 33123 - - import-table 254 # main - export-table 254 # main - - in ip 192.168.10.0/24 deny - in ip 192.168.20.0/24 deny - in ip 2001:db8:10::/64 deny - in ip 2001:db8:20::/64 deny - - in ip 192.168.30.0/24 allow - in ip 2001:db8:30::/64 allow - - in deny - - redistribute local proto 2 - redistribute local deny - ''; + interfaces."eth2" = { + ipv4.addresses = lib.mkForce [ + { + address = "192.168.30.1"; + prefixLength = 24; + } + ]; + ipv6.addresses = lib.mkForce [ + { + address = "2001:db8:30::1"; + prefixLength = 64; + } + ]; }; }; - remote_router = - { pkgs, lib, ... }: - { - virtualisation.vlans = [ - 20 - 30 - ]; - networking = { - useDHCP = false; - firewall.enable = false; - - interfaces."eth1" = { - ipv4.addresses = lib.mkForce [ - { - address = "192.168.20.2"; - prefixLength = 24; - } - ]; - ipv6.addresses = lib.mkForce [ - { - address = "2001:db8:20::2"; - prefixLength = 64; - } - ]; - }; - - interfaces."eth2" = { - ipv4.addresses = lib.mkForce [ - { - address = "192.168.30.1"; - prefixLength = 24; - } - ]; - ipv6.addresses = lib.mkForce [ - { - address = "2001:db8:30::1"; - prefixLength = 64; - } - ]; - }; + services.babeld = { + enable = true; + interfaces.eth1 = { + hello-interval = 1; + type = "wired"; }; + extraConfig = '' + local-port-readwrite 33123 - services.babeld = { - enable = true; - interfaces.eth1 = { - hello-interval = 1; - type = "wired"; - }; - extraConfig = '' - local-port-readwrite 33123 + import-table 254 # main + export-table 254 # main - import-table 254 # main - export-table 254 # main + in ip 192.168.20.0/24 deny + in ip 192.168.30.0/24 deny + in ip 2001:db8:20::/64 deny + in ip 2001:db8:30::/64 deny - in ip 192.168.20.0/24 deny - in ip 192.168.30.0/24 deny - in ip 2001:db8:20::/64 deny - in ip 2001:db8:30::/64 deny + in ip 192.168.10.0/24 allow + in ip 2001:db8:10::/64 allow - in ip 192.168.10.0/24 allow - in ip 2001:db8:10::/64 allow - - in deny - - redistribute local proto 2 - redistribute local deny - ''; - }; + in deny + redistribute local proto 2 + redistribute local deny + ''; }; - }; - testScript = '' - start_all() + }; + }; - local_router.wait_for_unit("babeld.service") - remote_router.wait_for_unit("babeld.service") + testScript = '' + start_all() - local_router.wait_until_succeeds("ip route get 192.168.30.1") - local_router.wait_until_succeeds("ip route get 2001:db8:30::1") + local_router.wait_for_unit("babeld.service") + remote_router.wait_for_unit("babeld.service") - remote_router.wait_until_succeeds("ip route get 192.168.10.1") - remote_router.wait_until_succeeds("ip route get 2001:db8:10::1") + local_router.wait_until_succeeds("ip route get 192.168.30.1") + local_router.wait_until_succeeds("ip route get 2001:db8:30::1") - client.succeed("ping -c1 192.168.30.1") - client.succeed("ping -c1 2001:db8:30::1") + remote_router.wait_until_succeeds("ip route get 192.168.10.1") + remote_router.wait_until_succeeds("ip route get 2001:db8:10::1") - remote_router.succeed("ping -c1 192.168.10.2") - remote_router.succeed("ping -c1 2001:db8:10::2") - ''; - } -) + client.succeed("ping -c1 192.168.30.1") + client.succeed("ping -c1 2001:db8:30::1") + + remote_router.succeed("ping -c1 192.168.10.2") + remote_router.succeed("ping -c1 2001:db8:10::2") + ''; +} diff --git a/nixos/tests/botamusique.nix b/nixos/tests/botamusique.nix index c87224d52a94..30a005aa49f9 100644 --- a/nixos/tests/botamusique.nix +++ b/nixos/tests/botamusique.nix @@ -1,55 +1,57 @@ -import ./make-test-python.nix ( - { pkgs, lib, ... }: +{ + pkgs, + lib, + ... +}: - { - name = "botamusique"; - meta.maintainers = with lib.maintainers; [ hexa ]; +{ + name = "botamusique"; + meta.maintainers = with lib.maintainers; [ hexa ]; - nodes = { - machine = - { config, ... }: - { - networking.extraHosts = '' - 127.0.0.1 all.api.radio-browser.info - ''; + nodes = { + machine = + { config, ... }: + { + networking.extraHosts = '' + 127.0.0.1 all.api.radio-browser.info + ''; - services.murmur = { - enable = true; - registerName = "NixOS tests"; - }; + services.murmur = { + enable = true; + registerName = "NixOS tests"; + }; - services.botamusique = { - enable = true; - settings = { - server = { - channel = "NixOS tests"; - }; - bot = { - version = false; - auto_check_update = false; - }; + services.botamusique = { + enable = true; + settings = { + server = { + channel = "NixOS tests"; + }; + bot = { + version = false; + auto_check_update = false; }; }; }; - }; + }; + }; - testScript = '' - start_all() + testScript = '' + start_all() - machine.wait_for_unit("murmur.service") - machine.wait_for_unit("botamusique.service") + machine.wait_for_unit("murmur.service") + machine.wait_for_unit("botamusique.service") - machine.sleep(10) + machine.sleep(10) - machine.wait_until_succeeds( - "journalctl -u murmur.service -e | grep -q '<1:botamusique(-1)> Authenticated'" - ) + machine.wait_until_succeeds( + "journalctl -u murmur.service -e | grep -q '<1:botamusique(-1)> Authenticated'" + ) - with subtest("Check systemd hardening"): - output = machine.execute("systemctl show botamusique.service")[1] - machine.log(output) - output = machine.execute("systemd-analyze security botamusique.service")[1] - machine.log(output) - ''; - } -) + with subtest("Check systemd hardening"): + output = machine.execute("systemctl show botamusique.service")[1] + machine.log(output) + output = machine.execute("systemd-analyze security botamusique.service")[1] + machine.log(output) + ''; +} diff --git a/nixos/tests/go-neb.nix b/nixos/tests/go-neb.nix index 38cf89c2a352..4aea2d436760 100644 --- a/nixos/tests/go-neb.nix +++ b/nixos/tests/go-neb.nix @@ -1,53 +1,54 @@ -import ./make-test-python.nix ( - { pkgs, ... }: - { - name = "go-neb"; - meta = with pkgs.lib.maintainers; { - maintainers = [ - hexa - maralorn - ]; - }; +{ + pkgs, + ... +}: +{ + name = "go-neb"; + meta = with pkgs.lib.maintainers; { + maintainers = [ + hexa + maralorn + ]; + }; - nodes = { - server = { - services.go-neb = { - enable = true; - baseUrl = "http://localhost"; - secretFile = pkgs.writeText "secrets" "ACCESS_TOKEN=changeme"; - config = { - clients = [ - { - UserId = "@test:localhost"; - AccessToken = "$ACCESS_TOKEN"; - HomeServerUrl = "http://localhost"; - Sync = false; - AutoJoinRooms = false; - DisplayName = "neverbeseen"; - } - ]; - services = [ - { - ID = "wikipedia_service"; - Type = "wikipedia"; - UserID = "@test:localhost"; - Config = { }; - } - ]; - }; + nodes = { + server = { + services.go-neb = { + enable = true; + baseUrl = "http://localhost"; + secretFile = pkgs.writeText "secrets" "ACCESS_TOKEN=changeme"; + config = { + clients = [ + { + UserId = "@test:localhost"; + AccessToken = "$ACCESS_TOKEN"; + HomeServerUrl = "http://localhost"; + Sync = false; + AutoJoinRooms = false; + DisplayName = "neverbeseen"; + } + ]; + services = [ + { + ID = "wikipedia_service"; + Type = "wikipedia"; + UserID = "@test:localhost"; + Config = { }; + } + ]; }; }; }; + }; - testScript = '' - start_all() - server.wait_for_unit("go-neb.service") - server.wait_until_succeeds("curl -fL http://localhost:4050/services/hooks/d2lraXBlZGlhX3NlcnZpY2U") - server.succeed( - "journalctl -eu go-neb -o cat | grep -q service_id=wikipedia_service", - "grep -q changeme /var/run/go-neb/config.yaml", - ) - ''; + testScript = '' + start_all() + server.wait_for_unit("go-neb.service") + server.wait_until_succeeds("curl -fL http://localhost:4050/services/hooks/d2lraXBlZGlhX3NlcnZpY2U") + server.succeed( + "journalctl -eu go-neb -o cat | grep -q service_id=wikipedia_service", + "grep -q changeme /var/run/go-neb/config.yaml", + ) + ''; - } -) +} diff --git a/nixos/tests/kea.nix b/nixos/tests/kea.nix index 90b9491039c4..bb361eba14fb 100644 --- a/nixos/tests/kea.nix +++ b/nixos/tests/kea.nix @@ -5,231 +5,233 @@ # that the nameserver can resolve the clients fqdn to the correct IP # address. -import ./make-test-python.nix ( - { pkgs, lib, ... }: - { - meta.maintainers = with lib.maintainers; [ hexa ]; +{ + pkgs, + lib, + ... +}: +{ + meta.maintainers = with lib.maintainers; [ hexa ]; - name = "kea"; + name = "kea"; - nodes = { - router = - { config, pkgs, ... }: - { - virtualisation.vlans = [ 1 ]; + nodes = { + router = + { config, pkgs, ... }: + { + virtualisation.vlans = [ 1 ]; - networking = { - useDHCP = false; - firewall.allowedUDPPorts = [ 67 ]; - }; + networking = { + useDHCP = false; + firewall.allowedUDPPorts = [ 67 ]; + }; - systemd.network = { - enable = true; - networks = { - "01-eth1" = { - name = "eth1"; - networkConfig = { - Address = "10.0.0.1/29"; - }; + systemd.network = { + enable = true; + networks = { + "01-eth1" = { + name = "eth1"; + networkConfig = { + Address = "10.0.0.1/29"; }; }; }; + }; - services.kea.dhcp4 = { - enable = true; - settings = { - valid-lifetime = 3600; - renew-timer = 900; - rebind-timer = 1800; + services.kea.dhcp4 = { + enable = true; + settings = { + valid-lifetime = 3600; + renew-timer = 900; + rebind-timer = 1800; - lease-database = { - type = "memfile"; - persist = true; - name = "/var/lib/kea/dhcp4.leases"; - }; + lease-database = { + type = "memfile"; + persist = true; + name = "/var/lib/kea/dhcp4.leases"; + }; - control-socket = { - socket-type = "unix"; - socket-name = "/run/kea/dhcp4.sock"; - }; + control-socket = { + socket-type = "unix"; + socket-name = "/run/kea/dhcp4.sock"; + }; - interfaces-config = { - dhcp-socket-type = "raw"; - interfaces = [ - "eth1" + interfaces-config = { + dhcp-socket-type = "raw"; + interfaces = [ + "eth1" + ]; + }; + + subnet4 = [ + { + id = 1; + subnet = "10.0.0.0/29"; + pools = [ + { + pool = "10.0.0.3 - 10.0.0.3"; + } ]; - }; + } + ]; - subnet4 = [ + # Enable communication between dhcp4 and a local dhcp-ddns + # instance. + # https://kea.readthedocs.io/en/kea-2.2.0/arm/dhcp4-srv.html#ddns-for-dhcpv4 + dhcp-ddns = { + enable-updates = true; + }; + + ddns-send-updates = true; + ddns-qualifying-suffix = "lan.nixos.test."; + }; + }; + + services.kea.dhcp-ddns = { + enable = true; + settings = { + forward-ddns = { + # Configure updates of a forward zone named `lan.nixos.test` + # hosted at the nameserver at 10.0.0.2 + # https://kea.readthedocs.io/en/kea-2.2.0/arm/ddns.html#adding-forward-dns-servers + ddns-domains = [ { - id = 1; - subnet = "10.0.0.0/29"; - pools = [ + name = "lan.nixos.test."; + # Use a TSIG key in production! + key-name = ""; + dns-servers = [ { - pool = "10.0.0.3 - 10.0.0.3"; + ip-address = "10.0.0.2"; + port = 53; } ]; } ]; - - # Enable communication between dhcp4 and a local dhcp-ddns - # instance. - # https://kea.readthedocs.io/en/kea-2.2.0/arm/dhcp4-srv.html#ddns-for-dhcpv4 - dhcp-ddns = { - enable-updates = true; - }; - - ddns-send-updates = true; - ddns-qualifying-suffix = "lan.nixos.test."; }; }; + }; - services.kea.dhcp-ddns = { - enable = true; - settings = { - forward-ddns = { - # Configure updates of a forward zone named `lan.nixos.test` - # hosted at the nameserver at 10.0.0.2 - # https://kea.readthedocs.io/en/kea-2.2.0/arm/ddns.html#adding-forward-dns-servers - ddns-domains = [ - { - name = "lan.nixos.test."; - # Use a TSIG key in production! - key-name = ""; - dns-servers = [ - { - ip-address = "10.0.0.2"; - port = 53; - } - ]; - } - ]; + services.kea.ctrl-agent = { + enable = true; + settings = { + http-host = "127.0.0.1"; + http-port = 8000; + control-sockets.dhcp4 = { + socket-type = "unix"; + socket-name = "/run/kea/dhcp4.sock"; + }; + }; + }; + + services.prometheus.exporters.kea = { + enable = true; + controlSocketPaths = [ + "http://127.0.0.1:8000" + ]; + }; + }; + + nameserver = + { config, pkgs, ... }: + { + virtualisation.vlans = [ 1 ]; + + networking = { + useDHCP = false; + firewall.allowedUDPPorts = [ 53 ]; + }; + + systemd.network = { + enable = true; + networks = { + "01-eth1" = { + name = "eth1"; + networkConfig = { + Address = "10.0.0.2/29"; }; }; }; + }; - services.kea.ctrl-agent = { - enable = true; - settings = { - http-host = "127.0.0.1"; - http-port = 8000; - control-sockets.dhcp4 = { - socket-type = "unix"; - socket-name = "/run/kea/dhcp4.sock"; - }; + services.resolved.enable = false; + + # Set up an authoritative nameserver, serving the `lan.nixos.test` + # zone and configure an ACL that allows dynamic updates from + # the router's ip address. + # This ACL is likely insufficient for production usage. Please + # use TSIG keys. + services.knot = + let + zone = pkgs.writeTextDir "lan.nixos.test.zone" '' + @ SOA ns.nixos.test nox.nixos.test 0 86400 7200 3600000 172800 + @ NS nameserver + nameserver A 10.0.0.3 + router A 10.0.0.1 + ''; + zonesDir = pkgs.buildEnv { + name = "knot-zones"; + paths = [ zone ]; }; - }; - - services.prometheus.exporters.kea = { + in + { enable = true; - controlSocketPaths = [ - "http://127.0.0.1:8000" + extraArgs = [ + "-v" ]; - }; - }; - - nameserver = - { config, pkgs, ... }: - { - virtualisation.vlans = [ 1 ]; - - networking = { - useDHCP = false; - firewall.allowedUDPPorts = [ 53 ]; - }; - - systemd.network = { - enable = true; - networks = { - "01-eth1" = { - name = "eth1"; - networkConfig = { - Address = "10.0.0.2/29"; - }; - }; - }; - }; - - services.resolved.enable = false; - - # Set up an authoritative nameserver, serving the `lan.nixos.test` - # zone and configure an ACL that allows dynamic updates from - # the router's ip address. - # This ACL is likely insufficient for production usage. Please - # use TSIG keys. - services.knot = - let - zone = pkgs.writeTextDir "lan.nixos.test.zone" '' - @ SOA ns.nixos.test nox.nixos.test 0 86400 7200 3600000 172800 - @ NS nameserver - nameserver A 10.0.0.3 - router A 10.0.0.1 - ''; - zonesDir = pkgs.buildEnv { - name = "knot-zones"; - paths = [ zone ]; - }; - in - { - enable = true; - extraArgs = [ - "-v" + settings = { + server.listen = [ + "0.0.0.0@53" ]; - settings = { - server.listen = [ - "0.0.0.0@53" + + log.syslog.any = "info"; + + acl.dhcp_ddns = { + address = "10.0.0.1"; + action = "update"; + }; + + template.default = { + storage = zonesDir; + zonefile-sync = "-1"; + zonefile-load = "difference-no-serial"; + journal-content = "all"; + }; + + zone."lan.nixos.test" = { + file = "lan.nixos.test.zone"; + acl = [ + "dhcp_ddns" ]; - - log.syslog.any = "info"; - - acl.dhcp_ddns = { - address = "10.0.0.1"; - action = "update"; - }; - - template.default = { - storage = zonesDir; - zonefile-sync = "-1"; - zonefile-load = "difference-no-serial"; - journal-content = "all"; - }; - - zone."lan.nixos.test" = { - file = "lan.nixos.test.zone"; - acl = [ - "dhcp_ddns" - ]; - }; }; }; - - }; - - client = - { config, pkgs, ... }: - { - virtualisation.vlans = [ 1 ]; - systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug"; - networking = { - useNetworkd = true; - useDHCP = false; - firewall.enable = false; - interfaces.eth1.useDHCP = true; }; + + }; + + client = + { config, pkgs, ... }: + { + virtualisation.vlans = [ 1 ]; + systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug"; + networking = { + useNetworkd = true; + useDHCP = false; + firewall.enable = false; + interfaces.eth1.useDHCP = true; }; - }; - testScript = - { ... }: - '' - start_all() - router.wait_for_unit("kea-dhcp4-server.service") - client.systemctl("start systemd-networkd-wait-online.service") - client.wait_for_unit("systemd-networkd-wait-online.service") - client.wait_until_succeeds("ping -c 5 10.0.0.1") - router.wait_until_succeeds("ping -c 5 10.0.0.3") - nameserver.wait_until_succeeds("kdig +short client.lan.nixos.test @10.0.0.2 | grep -q 10.0.0.3") - router.log(router.execute("curl 127.0.0.1:9547")[1]) - router.succeed("curl --no-buffer 127.0.0.1:9547 | grep -qE '^kea_dhcp4_addresses_assigned_total.*1.0$'") - ''; - } -) + }; + }; + testScript = + { ... }: + '' + start_all() + router.wait_for_unit("kea-dhcp4-server.service") + client.systemctl("start systemd-networkd-wait-online.service") + client.wait_for_unit("systemd-networkd-wait-online.service") + client.wait_until_succeeds("ping -c 5 10.0.0.1") + router.wait_until_succeeds("ping -c 5 10.0.0.3") + nameserver.wait_until_succeeds("kdig +short client.lan.nixos.test @10.0.0.2 | grep -q 10.0.0.3") + router.log(router.execute("curl 127.0.0.1:9547")[1]) + router.succeed("curl --no-buffer 127.0.0.1:9547 | grep -qE '^kea_dhcp4_addresses_assigned_total.*1.0$'") + ''; +} diff --git a/nixos/tests/knot.nix b/nixos/tests/knot.nix index 10ab1390696f..651fccc21949 100644 --- a/nixos/tests/knot.nix +++ b/nixos/tests/knot.nix @@ -1,254 +1,256 @@ -import ./make-test-python.nix ( - { pkgs, lib, ... }: - let - common = { - networking.firewall.enable = false; - networking.useDHCP = false; - }; - exampleZone = pkgs.writeTextDir "example.com.zone" '' - @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 - @ NS ns1 - @ NS ns2 - ns1 A 192.168.0.1 - ns1 AAAA fd00::1 - ns2 A 192.168.0.2 - ns2 AAAA fd00::2 - www A 192.0.2.1 - www AAAA 2001:DB8::1 - sub NS ns.example.com. - ''; - delegatedZone = pkgs.writeTextDir "sub.example.com.zone" '' - @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 - @ NS ns1.example.com. - @ NS ns2.example.com. - @ A 192.0.2.2 - @ AAAA 2001:DB8::2 - ''; +{ + pkgs, + lib, + ... +}: +let + common = { + networking.firewall.enable = false; + networking.useDHCP = false; + }; + exampleZone = pkgs.writeTextDir "example.com.zone" '' + @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 + @ NS ns1 + @ NS ns2 + ns1 A 192.168.0.1 + ns1 AAAA fd00::1 + ns2 A 192.168.0.2 + ns2 AAAA fd00::2 + www A 192.0.2.1 + www AAAA 2001:DB8::1 + sub NS ns.example.com. + ''; + delegatedZone = pkgs.writeTextDir "sub.example.com.zone" '' + @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800 + @ NS ns1.example.com. + @ NS ns2.example.com. + @ A 192.0.2.2 + @ AAAA 2001:DB8::2 + ''; - knotZonesEnv = pkgs.buildEnv { - name = "knot-zones"; - paths = [ - exampleZone - delegatedZone - ]; - }; - # DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store! - tsigFile = pkgs.writeText "tsig.conf" '' - key: - - id: xfr_key - algorithm: hmac-sha256 - secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s= - ''; - in - { - name = "knot"; - meta = with pkgs.lib.maintainers; { - maintainers = [ hexa ]; - }; + knotZonesEnv = pkgs.buildEnv { + name = "knot-zones"; + paths = [ + exampleZone + delegatedZone + ]; + }; + # DO NOT USE pkgs.writeText IN PRODUCTION. This put secrets in the nix store! + tsigFile = pkgs.writeText "tsig.conf" '' + key: + - id: xfr_key + algorithm: hmac-sha256 + secret: zOYgOgnzx3TGe5J5I/0kxd7gTcxXhLYMEq3Ek3fY37s= + ''; +in +{ + name = "knot"; + meta = with pkgs.lib.maintainers; { + maintainers = [ hexa ]; + }; - nodes = { - primary = - { lib, ... }: - { - imports = [ common ]; + nodes = { + primary = + { lib, ... }: + { + imports = [ common ]; - # trigger sched_setaffinity syscall - virtualisation.cores = 2; + # trigger sched_setaffinity syscall + virtualisation.cores = 2; - networking.interfaces.eth1 = { - ipv4.addresses = lib.mkForce [ - { - address = "192.168.0.1"; - prefixLength = 24; - } + networking.interfaces.eth1 = { + ipv4.addresses = lib.mkForce [ + { + address = "192.168.0.1"; + prefixLength = 24; + } + ]; + ipv6.addresses = lib.mkForce [ + { + address = "fd00::1"; + prefixLength = 64; + } + ]; + }; + services.knot.enable = true; + services.knot.extraArgs = [ "-v" ]; + services.knot.keyFiles = [ tsigFile ]; + services.knot.settings = { + server = { + listen = [ + "0.0.0.0@53" + "::@53" ]; - ipv6.addresses = lib.mkForce [ - { - address = "fd00::1"; - prefixLength = 64; - } + listen-quic = [ + "0.0.0.0@853" + "::@853" ]; + automatic-acl = true; }; - services.knot.enable = true; - services.knot.extraArgs = [ "-v" ]; - services.knot.keyFiles = [ tsigFile ]; - services.knot.settings = { - server = { - listen = [ - "0.0.0.0@53" - "::@53" - ]; - listen-quic = [ - "0.0.0.0@853" - "::@853" - ]; - automatic-acl = true; - }; - acl.secondary_acl = { + acl.secondary_acl = { + address = "192.168.0.2"; + key = "xfr_key"; + action = "transfer"; + }; + + remote.secondary.address = "192.168.0.2@53"; + + template.default = { + storage = knotZonesEnv; + notify = [ "secondary" ]; + acl = [ "secondary_acl" ]; + dnssec-signing = true; + # Input-only zone files + # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3 + # prevents modification of the zonefiles, since the zonefiles are immutable + zonefile-sync = -1; + zonefile-load = "difference"; + journal-content = "changes"; + }; + + zone = { + "example.com".file = "example.com.zone"; + "sub.example.com".file = "sub.example.com.zone"; + }; + + log.syslog.any = "info"; + }; + }; + + secondary = + { lib, ... }: + { + imports = [ common ]; + networking.interfaces.eth1 = { + ipv4.addresses = lib.mkForce [ + { address = "192.168.0.2"; - key = "xfr_key"; - action = "transfer"; - }; - - remote.secondary.address = "192.168.0.2@53"; - - template.default = { - storage = knotZonesEnv; - notify = [ "secondary" ]; - acl = [ "secondary_acl" ]; - dnssec-signing = true; - # Input-only zone files - # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-3 - # prevents modification of the zonefiles, since the zonefiles are immutable - zonefile-sync = -1; - zonefile-load = "difference"; - journal-content = "changes"; - }; - - zone = { - "example.com".file = "example.com.zone"; - "sub.example.com".file = "sub.example.com.zone"; - }; - - log.syslog.any = "info"; - }; + prefixLength = 24; + } + ]; + ipv6.addresses = lib.mkForce [ + { + address = "fd00::2"; + prefixLength = 64; + } + ]; }; - - secondary = - { lib, ... }: - { - imports = [ common ]; - networking.interfaces.eth1 = { - ipv4.addresses = lib.mkForce [ - { - address = "192.168.0.2"; - prefixLength = 24; - } - ]; - ipv6.addresses = lib.mkForce [ - { - address = "fd00::2"; - prefixLength = 64; - } - ]; + services.knot.enable = true; + services.knot.keyFiles = [ tsigFile ]; + services.knot.extraArgs = [ "-v" ]; + services.knot.settings = { + server = { + automatic-acl = true; }; - services.knot.enable = true; - services.knot.keyFiles = [ tsigFile ]; - services.knot.extraArgs = [ "-v" ]; - services.knot.settings = { - server = { - automatic-acl = true; - }; - xdp = { - listen = [ - "eth1" - ]; - tcp = true; - }; - - remote.primary = { - address = "192.168.0.1@53"; - key = "xfr_key"; - }; - - remote.primary-quic = { - address = "192.168.0.1@853"; - key = "xfr_key"; - quic = true; - }; - - template.default = { - # zonefileless setup - # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2 - zonefile-sync = "-1"; - zonefile-load = "none"; - journal-content = "all"; - }; - - zone = { - "example.com" = { - master = "primary"; - file = "example.com.zone"; - }; - "sub.example.com" = { - master = "primary-quic"; - file = "sub.example.com.zone"; - }; - }; - - log.syslog.any = "debug"; + xdp = { + listen = [ + "eth1" + ]; + tcp = true; }; + + remote.primary = { + address = "192.168.0.1@53"; + key = "xfr_key"; + }; + + remote.primary-quic = { + address = "192.168.0.1@853"; + key = "xfr_key"; + quic = true; + }; + + template.default = { + # zonefileless setup + # https://www.knot-dns.cz/docs/2.8/html/operation.html#example-2 + zonefile-sync = "-1"; + zonefile-load = "none"; + journal-content = "all"; + }; + + zone = { + "example.com" = { + master = "primary"; + file = "example.com.zone"; + }; + "sub.example.com" = { + master = "primary-quic"; + file = "sub.example.com.zone"; + }; + }; + + log.syslog.any = "debug"; }; - client = - { lib, nodes, ... }: - { - imports = [ common ]; - networking.interfaces.eth1 = { - ipv4.addresses = [ - { - address = "192.168.0.3"; - prefixLength = 24; - } - ]; - ipv6.addresses = [ - { - address = "fd00::3"; - prefixLength = 64; - } - ]; - }; - environment.systemPackages = [ pkgs.knot-dns ]; + }; + client = + { lib, nodes, ... }: + { + imports = [ common ]; + networking.interfaces.eth1 = { + ipv4.addresses = [ + { + address = "192.168.0.3"; + prefixLength = 24; + } + ]; + ipv6.addresses = [ + { + address = "fd00::3"; + prefixLength = 64; + } + ]; }; - }; + environment.systemPackages = [ pkgs.knot-dns ]; + }; + }; - testScript = - { nodes, ... }: - let - primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address; - primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address; + testScript = + { nodes, ... }: + let + primary4 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv4.addresses).address; + primary6 = (lib.head nodes.primary.config.networking.interfaces.eth1.ipv6.addresses).address; - secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address; - secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address; - in - '' - import re + secondary4 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv4.addresses).address; + secondary6 = (lib.head nodes.secondary.config.networking.interfaces.eth1.ipv6.addresses).address; + in + '' + import re - start_all() + start_all() - client.wait_for_unit("network.target") - primary.wait_for_unit("knot.service") - secondary.wait_for_unit("knot.service") + client.wait_for_unit("network.target") + primary.wait_for_unit("knot.service") + secondary.wait_for_unit("knot.service") - for zone in ("example.com.", "sub.example.com."): - secondary.wait_until_succeeds( - f"knotc zone-status {zone} | grep -q 'serial: 2019031302'" - ) + for zone in ("example.com.", "sub.example.com."): + secondary.wait_until_succeeds( + f"knotc zone-status {zone} | grep -q 'serial: 2019031302'" + ) - def test(host, query_type, query, pattern): - out = client.succeed(f"khost -t {query_type} {query} {host}").strip() - client.log(f"{host} replied with: {out}") - assert re.search(pattern, out), f'Did not match "{pattern}"' + def test(host, query_type, query, pattern): + out = client.succeed(f"khost -t {query_type} {query} {host}").strip() + client.log(f"{host} replied with: {out}") + assert re.search(pattern, out), f'Did not match "{pattern}"' - for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"): - with subtest(f"Interrogate {host}"): - test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.") - test(host, "A", "example.com", r"has no [^ ]+ record") - test(host, "AAAA", "example.com", r"has no [^ ]+ record") + for host in ("${primary4}", "${primary6}", "${secondary4}", "${secondary6}"): + with subtest(f"Interrogate {host}"): + test(host, "SOA", "example.com", r"start of authority.*noc\.example\.com\.") + test(host, "A", "example.com", r"has no [^ ]+ record") + test(host, "AAAA", "example.com", r"has no [^ ]+ record") - test(host, "A", "www.example.com", r"address 192.0.2.1$") - test(host, "AAAA", "www.example.com", r"address 2001:db8::1$") + test(host, "A", "www.example.com", r"address 192.0.2.1$") + test(host, "AAAA", "www.example.com", r"address 2001:db8::1$") - test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$") - test(host, "A", "sub.example.com", r"address 192.0.2.2$") - test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$") + test(host, "NS", "sub.example.com", r"nameserver is ns\d\.example\.com.$") + test(host, "A", "sub.example.com", r"address 192.0.2.2$") + test(host, "AAAA", "sub.example.com", r"address 2001:db8::2$") - test(host, "RRSIG", "www.example.com", r"RR set signature is") - test(host, "DNSKEY", "example.com", r"DNSSEC key is") + test(host, "RRSIG", "www.example.com", r"RR set signature is") + test(host, "DNSKEY", "example.com", r"DNSSEC key is") - primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'")) - ''; - } -) + primary.log(primary.succeed("systemd-analyze security knot.service | grep -v '✓'")) + ''; +} diff --git a/nixos/tests/pinnwand.nix b/nixos/tests/pinnwand.nix index 0d3d9083c6ac..e7e62ee7dacc 100644 --- a/nixos/tests/pinnwand.nix +++ b/nixos/tests/pinnwand.nix @@ -1,102 +1,103 @@ -import ./make-test-python.nix ( - { pkgs, ... }: - let - port = 8000; - baseUrl = "http://server:${toString port}"; - in - { - name = "pinnwand"; - meta = with pkgs.lib.maintainers; { - maintainers = [ hexa ]; - }; +{ + pkgs, + ... +}: +let + port = 8000; + baseUrl = "http://server:${toString port}"; +in +{ + name = "pinnwand"; + meta = with pkgs.lib.maintainers; { + maintainers = [ hexa ]; + }; - nodes = { - server = - { config, ... }: - { - networking.firewall.allowedTCPPorts = [ - port - ]; + nodes = { + server = + { config, ... }: + { + networking.firewall.allowedTCPPorts = [ + port + ]; - services.pinnwand = { - enable = true; - port = port; - }; + services.pinnwand = { + enable = true; + port = port; }; + }; - client = - { pkgs, ... }: - { - environment.systemPackages = [ - pkgs.steck + client = + { pkgs, ... }: + { + environment.systemPackages = [ + pkgs.steck - (pkgs.writers.writePython3Bin "setup-steck.py" - { - libraries = with pkgs.python3.pkgs; [ - appdirs - toml - ]; - flakeIgnore = [ - "E501" - ]; + (pkgs.writers.writePython3Bin "setup-steck.py" + { + libraries = with pkgs.python3.pkgs; [ + appdirs + toml + ]; + flakeIgnore = [ + "E501" + ]; + } + '' + import appdirs + import toml + import os + + CONFIG = { + "base": "${baseUrl}/", + "confirm": False, + "magic": True, + "ignore": True } - '' - import appdirs - import toml - import os - CONFIG = { - "base": "${baseUrl}/", - "confirm": False, - "magic": True, - "ignore": True - } + os.makedirs(appdirs.user_config_dir('steck')) + with open(os.path.join(appdirs.user_config_dir('steck'), 'steck.toml'), "w") as fd: + toml.dump(CONFIG, fd) + '' + ) + ]; + }; + }; - os.makedirs(appdirs.user_config_dir('steck')) - with open(os.path.join(appdirs.user_config_dir('steck'), 'steck.toml'), "w") as fd: - toml.dump(CONFIG, fd) - '' - ) - ]; - }; - }; + testScript = '' + start_all() - testScript = '' - start_all() + server.wait_for_unit("pinnwand.service") + client.wait_for_unit("network.target") - server.wait_for_unit("pinnwand.service") - client.wait_for_unit("network.target") + # create steck.toml config file + client.succeed("setup-steck.py") - # create steck.toml config file - client.succeed("setup-steck.py") + # wait until the server running pinnwand is reachable + client.wait_until_succeeds("ping -c1 server") - # wait until the server running pinnwand is reachable - client.wait_until_succeeds("ping -c1 server") + # make sure pinnwand is listening + server.wait_for_open_port(${toString port}) - # make sure pinnwand is listening - server.wait_for_open_port(${toString port}) + # send the contents of /etc/machine-id + response = client.succeed("steck paste /etc/machine-id") - # send the contents of /etc/machine-id - response = client.succeed("steck paste /etc/machine-id") + # parse the steck response + raw_url = None + removal_link = None + for line in response.split("\n"): + if line.startswith("View link:"): + raw_url = f"${baseUrl}/raw/{line.split('/')[-1]}" + if line.startswith("Removal link:"): + removal_link = line.split(":", 1)[1] - # parse the steck response - raw_url = None - removal_link = None - for line in response.split("\n"): - if line.startswith("View link:"): - raw_url = f"${baseUrl}/raw/{line.split('/')[-1]}" - if line.startswith("Removal link:"): - removal_link = line.split(":", 1)[1] + # check whether paste matches what we sent + client.succeed(f"curl {raw_url} > /tmp/machine-id") + client.succeed("diff /tmp/machine-id /etc/machine-id") - # check whether paste matches what we sent - client.succeed(f"curl {raw_url} > /tmp/machine-id") - client.succeed("diff /tmp/machine-id /etc/machine-id") + # remove paste and check that it's not available any more + client.succeed(f"curl {removal_link}") + client.fail(f"curl --fail {raw_url}") - # remove paste and check that it's not available any more - client.succeed(f"curl {removal_link}") - client.fail(f"curl --fail {raw_url}") - - server.log(server.execute("systemd-analyze security pinnwand | grep '✗'")[1]) - ''; - } -) + server.log(server.execute("systemd-analyze security pinnwand | grep '✗'")[1]) + ''; +} diff --git a/nixos/tests/snapcast.nix b/nixos/tests/snapcast.nix index 569a50ff39c1..2a3bf114ee70 100644 --- a/nixos/tests/snapcast.nix +++ b/nixos/tests/snapcast.nix @@ -1,93 +1,94 @@ -import ./make-test-python.nix ( - { pkgs, ... }: +{ + pkgs, + ... +}: - let - port = 10004; - tcpPort = 10005; - httpPort = 10080; - tcpStreamPort = 10006; - bufferSize = 742; - in - { - name = "snapcast"; - meta = with pkgs.lib.maintainers; { - maintainers = [ hexa ]; - }; +let + port = 10004; + tcpPort = 10005; + httpPort = 10080; + tcpStreamPort = 10006; + bufferSize = 742; +in +{ + name = "snapcast"; + meta = with pkgs.lib.maintainers; { + maintainers = [ hexa ]; + }; - nodes = { - server = { - services.snapserver = { - enable = true; - port = port; - tcp.port = tcpPort; - http.port = httpPort; - openFirewall = true; - buffer = bufferSize; - streams = { - mpd = { - type = "pipe"; - location = "/run/snapserver/mpd"; - query.mode = "create"; - }; - bluetooth = { - type = "pipe"; - location = "/run/snapserver/bluetooth"; - }; - tcp = { - type = "tcp"; - location = "127.0.0.1:${toString tcpStreamPort}"; - }; - meta = { - type = "meta"; - location = "/mpd/bluetooth/tcp"; - }; + nodes = { + server = { + services.snapserver = { + enable = true; + port = port; + tcp.port = tcpPort; + http.port = httpPort; + openFirewall = true; + buffer = bufferSize; + streams = { + mpd = { + type = "pipe"; + location = "/run/snapserver/mpd"; + query.mode = "create"; + }; + bluetooth = { + type = "pipe"; + location = "/run/snapserver/bluetooth"; + }; + tcp = { + type = "tcp"; + location = "127.0.0.1:${toString tcpStreamPort}"; + }; + meta = { + type = "meta"; + location = "/mpd/bluetooth/tcp"; }; }; - environment.systemPackages = [ pkgs.snapcast ]; - }; - client = { - environment.systemPackages = [ pkgs.snapcast ]; }; + environment.systemPackages = [ pkgs.snapcast ]; }; + client = { + environment.systemPackages = [ pkgs.snapcast ]; + }; + }; - testScript = '' - import json + testScript = '' + import json - get_rpc_version = {"id": "1", "jsonrpc": "2.0", "method": "Server.GetRPCVersion"} + get_rpc_version = {"id": "1", "jsonrpc": "2.0", "method": "Server.GetRPCVersion"} - start_all() + start_all() - server.wait_for_unit("snapserver.service") - server.wait_until_succeeds("ss -ntl | grep -q ${toString port}") - server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpPort}") - server.wait_until_succeeds("ss -ntl | grep -q ${toString httpPort}") - server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpStreamPort}") + server.wait_for_unit("snapserver.service") + server.wait_until_succeeds("ss -ntl | grep -q ${toString port}") + server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpPort}") + server.wait_until_succeeds("ss -ntl | grep -q ${toString httpPort}") + server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpStreamPort}") - with subtest("check that pipes are created"): - server.succeed("test -p /run/snapserver/mpd") - server.succeed("test -p /run/snapserver/bluetooth") + with subtest("check that pipes are created"): + server.succeed("test -p /run/snapserver/mpd") + server.succeed("test -p /run/snapserver/bluetooth") - with subtest("test tcp json-rpc"): - server.succeed(f"echo '{json.dumps(get_rpc_version)}' | nc -w 1 localhost ${toString tcpPort}") + with subtest("test tcp json-rpc"): + server.succeed(f"echo '{json.dumps(get_rpc_version)}' | nc -w 1 localhost ${toString tcpPort}") - with subtest("test http json-rpc"): - server.succeed( - "curl --fail http://localhost:${toString httpPort}/jsonrpc -d '{json.dumps(get_rpc_version)}'" - ) + with subtest("test http json-rpc"): + server.succeed( + "curl --fail http://localhost:${toString httpPort}/jsonrpc -d '{json.dumps(get_rpc_version)}'" + ) - with subtest("test a ipv6 connection"): - server.execute("systemd-run --unit=snapcast-local-client snapclient -h ::1 -p ${toString port}") - server.wait_until_succeeds( - "journalctl -o cat -u snapserver.service | grep -q 'Hello from'" - ) - server.wait_until_succeeds("journalctl -o cat -u snapcast-local-client | grep -q 'buffer: ${toString bufferSize}'") + with subtest("test a ipv6 connection"): + server.execute("systemd-run --unit=snapcast-local-client snapclient -h ::1 -p ${toString port}") + server.wait_until_succeeds( + "journalctl -o cat -u snapserver.service | grep -q 'Hello from'" + ) + server.wait_until_succeeds("journalctl -o cat -u snapcast-local-client | grep -q 'buffer: ${toString bufferSize}'") - with subtest("test a connection"): - client.execute("systemd-run --unit=snapcast-client snapclient -h server -p ${toString port}") - server.wait_until_succeeds( - "journalctl -o cat -u snapserver.service | grep -q 'Hello from'" - ) - client.wait_until_succeeds("journalctl -o cat -u snapcast-client | grep -q 'buffer: ${toString bufferSize}'") - ''; - } -) + with subtest("test a connection"): + client.execute("systemd-run --unit=snapcast-client snapclient -h server -p ${toString port}") + server.wait_until_succeeds( + "journalctl -o cat -u snapserver.service | grep -q 'Hello from'" + ) + client.wait_until_succeeds("journalctl -o cat -u snapcast-client | grep -q 'buffer: ${toString bufferSize}'") + ''; +}