diff options
Diffstat (limited to 'nixos/tests')
66 files changed, 976 insertions, 113 deletions
diff --git a/nixos/tests/3proxy.nix b/nixos/tests/3proxy.nix index 83d39de018a39..b80b4e166d481 100644 --- a/nixos/tests/3proxy.nix +++ b/nixos/tests/3proxy.nix @@ -134,6 +134,7 @@ testScript = '' start_all() + peer0.systemctl("start network-online.target") peer0.wait_for_unit("network-online.target") peer1.wait_for_unit("3proxy.service") diff --git a/nixos/tests/acme.nix b/nixos/tests/acme.nix index e5f2d4c7934a1..272782dc2f621 100644 --- a/nixos/tests/acme.nix +++ b/nixos/tests/acme.nix @@ -522,6 +522,7 @@ in { 'curl --data \'{"host": "${caDomain}", "addresses": ["${nodes.acme.networking.primaryIPAddress}"]}\' http://${dnsServerIP nodes}:8055/add-a' ) + acme.systemctl("start network-online.target") acme.wait_for_unit("network-online.target") acme.wait_for_unit("pebble.service") diff --git a/nixos/tests/activation/etc-overlay-immutable.nix b/nixos/tests/activation/etc-overlay-immutable.nix new file mode 100644 index 0000000000000..70c3623b929c5 --- /dev/null +++ b/nixos/tests/activation/etc-overlay-immutable.nix @@ -0,0 +1,30 @@ +{ lib, ... }: { + + name = "activation-etc-overlay-immutable"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes.machine = { pkgs, ... }: { + system.etc.overlay.enable = true; + system.etc.overlay.mutable = false; + + # Prerequisites + systemd.sysusers.enable = true; + users.mutableUsers = false; + boot.initrd.systemd.enable = true; + boot.kernelPackages = pkgs.linuxPackages_latest; + + specialisation.new-generation.configuration = { + environment.etc."newgen".text = "newgen"; + }; + }; + + testScript = '' + machine.succeed("findmnt --kernel --type overlay /etc") + machine.fail("stat /etc/newgen") + + machine.succeed("/run/current-system/specialisation/new-generation/bin/switch-to-configuration switch") + + assert machine.succeed("cat /etc/newgen") == "newgen" + ''; +} diff --git a/nixos/tests/activation/etc-overlay-mutable.nix b/nixos/tests/activation/etc-overlay-mutable.nix new file mode 100644 index 0000000000000..cfe7604fceb84 --- /dev/null +++ b/nixos/tests/activation/etc-overlay-mutable.nix @@ -0,0 +1,30 @@ +{ lib, ... }: { + + name = "activation-etc-overlay-mutable"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes.machine = { pkgs, ... }: { + system.etc.overlay.enable = true; + system.etc.overlay.mutable = true; + + # Prerequisites + boot.initrd.systemd.enable = true; + boot.kernelPackages = pkgs.linuxPackages_latest; + + specialisation.new-generation.configuration = { + environment.etc."newgen".text = "newgen"; + }; + }; + + testScript = '' + machine.succeed("findmnt --kernel --type overlay /etc") + machine.fail("stat /etc/newgen") + machine.succeed("echo -n 'mutable' > /etc/mutable") + + machine.succeed("/run/current-system/specialisation/new-generation/bin/switch-to-configuration switch") + + assert machine.succeed("cat /etc/newgen") == "newgen" + assert machine.succeed("cat /etc/mutable") == "mutable" + ''; +} diff --git a/nixos/tests/activation/perlless.nix b/nixos/tests/activation/perlless.nix new file mode 100644 index 0000000000000..4d784b4542f45 --- /dev/null +++ b/nixos/tests/activation/perlless.nix @@ -0,0 +1,24 @@ +{ lib, ... }: + +{ + + name = "activation-perlless"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes.machine = { pkgs, modulesPath, ... }: { + imports = [ "${modulesPath}/profiles/perlless.nix" ]; + + boot.kernelPackages = pkgs.linuxPackages_latest; + + virtualisation.mountHostNixStore = false; + virtualisation.useNixStoreImage = true; + }; + + testScript = '' + perl_store_paths = machine.succeed("ls /nix/store | grep perl || true") + print(perl_store_paths) + assert len(perl_store_paths) == 0 + ''; + +} diff --git a/nixos/tests/adguardhome.nix b/nixos/tests/adguardhome.nix index a6f790b83f5fc..80613ce825340 100644 --- a/nixos/tests/adguardhome.nix +++ b/nixos/tests/adguardhome.nix @@ -126,6 +126,7 @@ with subtest("Testing successful DHCP start"): dhcpConf.wait_for_unit("adguardhome.service") + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") # Test IP assignment via DHCP dhcpConf.wait_until_succeeds("ping -c 5 10.0.10.100") diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 63e957eace88d..1453a3875f6e7 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -285,6 +285,9 @@ in { activation = pkgs.callPackage ../modules/system/activation/test.nix { }; activation-var = runTest ./activation/var.nix; activation-nix-channel = runTest ./activation/nix-channel.nix; + activation-etc-overlay-mutable = runTest ./activation/etc-overlay-mutable.nix; + activation-etc-overlay-immutable = runTest ./activation/etc-overlay-immutable.nix; + activation-perlless = runTest ./activation/perlless.nix; etcd = handleTestOn ["x86_64-linux"] ./etcd.nix {}; etcd-cluster = handleTestOn ["x86_64-linux"] ./etcd-cluster.nix {}; etebase-server = handleTest ./etebase-server.nix {}; @@ -569,8 +572,8 @@ in { netdata = handleTest ./netdata.nix {}; networking.networkd = handleTest ./networking.nix { networkd = true; }; networking.scripted = handleTest ./networking.nix { networkd = false; }; - netbox_3_5 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_5; }; netbox_3_6 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_6; }; + netbox_3_7 = handleTest ./web-apps/netbox.nix { netbox = pkgs.netbox_3_7; }; netbox-upgrade = handleTest ./web-apps/netbox-upgrade.nix {}; # TODO: put in networking.nix after the test becomes more complete networkingProxy = handleTest ./networking-proxy.nix {}; @@ -587,6 +590,7 @@ in { nginx-globalredirect = handleTest ./nginx-globalredirect.nix {}; nginx-http3 = handleTest ./nginx-http3.nix {}; nginx-modsecurity = handleTest ./nginx-modsecurity.nix {}; + nginx-moreheaders = handleTest ./nginx-moreheaders.nix {}; nginx-njs = handleTest ./nginx-njs.nix {}; nginx-proxyprotocol = handleTest ./nginx-proxyprotocol {}; nginx-pubhtml = handleTest ./nginx-pubhtml.nix {}; @@ -808,6 +812,7 @@ in { stunnel = handleTest ./stunnel.nix {}; sudo = handleTest ./sudo.nix {}; sudo-rs = handleTest ./sudo-rs.nix {}; + suwayomi-server = handleTest ./suwayomi-server.nix {}; swap-file-btrfs = handleTest ./swap-file-btrfs.nix {}; swap-partition = handleTest ./swap-partition.nix {}; swap-random-encryption = handleTest ./swap-random-encryption.nix {}; @@ -819,6 +824,7 @@ in { syncthing-init = handleTest ./syncthing-init.nix {}; syncthing-many-devices = handleTest ./syncthing-many-devices.nix {}; syncthing-relay = handleTest ./syncthing-relay.nix {}; + sysinit-reactivation = runTest ./sysinit-reactivation.nix; systemd = handleTest ./systemd.nix {}; systemd-analyze = handleTest ./systemd-analyze.nix {}; systemd-binfmt = handleTestOn ["x86_64-linux"] ./systemd-binfmt.nix {}; @@ -863,6 +869,8 @@ in { systemd-repart = handleTest ./systemd-repart.nix {}; systemd-shutdown = handleTest ./systemd-shutdown.nix {}; systemd-sysupdate = runTest ./systemd-sysupdate.nix; + systemd-sysusers-mutable = runTest ./systemd-sysusers-mutable.nix; + systemd-sysusers-immutable = runTest ./systemd-sysusers-immutable.nix; systemd-timesyncd = handleTest ./systemd-timesyncd.nix {}; systemd-timesyncd-nscd-dnssec = handleTest ./systemd-timesyncd-nscd-dnssec.nix {}; systemd-user-tmpfiles-rules = handleTest ./systemd-user-tmpfiles-rules.nix {}; @@ -902,6 +910,7 @@ in { trilium-server = handleTestOn ["x86_64-linux"] ./trilium-server.nix {}; tsja = handleTest ./tsja.nix {}; tsm-client-gui = handleTest ./tsm-client-gui.nix {}; + ttyd = handleTest ./web-servers/ttyd.nix {}; txredisapi = handleTest ./txredisapi.nix {}; tuptime = handleTest ./tuptime.nix {}; turbovnc-headless-server = handleTest ./turbovnc-headless-server.nix {}; @@ -941,6 +950,7 @@ in { vsftpd = handleTest ./vsftpd.nix {}; warzone2100 = handleTest ./warzone2100.nix {}; wasabibackend = handleTest ./wasabibackend.nix {}; + watchdogd = handleTest ./watchdogd.nix {}; webhook = runTest ./webhook.nix; wiki-js = handleTest ./wiki-js.nix {}; wine = handleTest ./wine.nix {}; diff --git a/nixos/tests/appliance-repart-image.nix b/nixos/tests/appliance-repart-image.nix index 3f256db846214..b18968d3b9631 100644 --- a/nixos/tests/appliance-repart-image.nix +++ b/nixos/tests/appliance-repart-image.nix @@ -8,9 +8,8 @@ let rootPartitionLabel = "root"; - bootLoaderConfigPath = "/loader/entries/nixos.conf"; - kernelPath = "/EFI/nixos/kernel.efi"; - initrdPath = "/EFI/nixos/initrd.efi"; + imageId = "nixos-appliance"; + imageVersion = "1-rc1"; in { name = "appliance-gpt-image"; @@ -29,6 +28,9 @@ in # TODO(raitobezarius): revisit this when #244907 lands boot.loader.grub.enable = false; + system.image.id = imageId; + system.image.version = imageVersion; + virtualisation.fileSystems = lib.mkForce { "/" = { device = "/dev/disk/by-partlabel/${rootPartitionLabel}"; @@ -48,19 +50,8 @@ in "/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source = "${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi"; - # TODO: create an abstraction for Boot Loader Specification (BLS) entries. - "${bootLoaderConfigPath}".source = pkgs.writeText "nixos.conf" '' - title NixOS - linux ${kernelPath} - initrd ${initrdPath} - options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} - ''; - - "${kernelPath}".source = - "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}"; - - "${initrdPath}".source = - "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; + "/EFI/Linux/${config.system.boot.loader.ukiFile}".source = + "${config.system.build.uki}/${config.system.boot.loader.ukiFile}"; }; repartConfig = { Type = "esp"; @@ -99,7 +90,7 @@ in "-f", "qcow2", "-b", - "${nodes.machine.system.build.image}/image.raw", + "${nodes.machine.system.build.image}/${nodes.machine.image.repart.imageFile}", "-F", "raw", tmp_disk_image.name, @@ -108,9 +99,11 @@ in # Set NIX_DISK_IMAGE so that the qemu script finds the right disk image. os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name + os_release = machine.succeed("cat /etc/os-release") + assert 'IMAGE_ID="${imageId}"' in os_release + assert 'IMAGE_VERSION="${imageVersion}"' in os_release + bootctl_status = machine.succeed("bootctl status") - assert "${bootLoaderConfigPath}" in bootctl_status - assert "${kernelPath}" in bootctl_status - assert "${initrdPath}" in bootctl_status + assert "Boot Loader Specification Type #2 (.efi)" in bootctl_status ''; } diff --git a/nixos/tests/ayatana-indicators.nix b/nixos/tests/ayatana-indicators.nix index bc7ff75f390f7..c9cbbda4c601d 100644 --- a/nixos/tests/ayatana-indicators.nix +++ b/nixos/tests/ayatana-indicators.nix @@ -4,7 +4,7 @@ in { name = "ayatana-indicators"; meta = { - maintainers = with lib.maintainers; [ OPNA2608 ]; + maintainers = lib.teams.lomiri.members; }; nodes.machine = { config, ... }: { @@ -27,17 +27,56 @@ in { services.ayatana-indicators = { enable = true; packages = with pkgs; [ + ayatana-indicator-datetime ayatana-indicator-messages - ]; + ] ++ (with pkgs.lomiri; [ + lomiri-indicator-network + telephony-service + ]); }; - # Services needed by some indicators + # Setup needed by some indicators + services.accounts-daemon.enable = true; # messages + + # Lomiri-ish setup for Lomiri indicators + # TODO move into a Lomiri module, once the package set is far enough for the DE to start + + networking.networkmanager.enable = true; # lomiri-network-indicator + # TODO potentially urfkill for lomiri-network-indicator? + + services.dbus.packages = with pkgs.lomiri; [ + libusermetrics + ]; + + environment.systemPackages = with pkgs.lomiri; [ + lomiri-schemas + ]; + + services.telepathy.enable = true; + + users.users.usermetrics = { + group = "usermetrics"; + home = "/var/lib/usermetrics"; + createHome = true; + isSystemUser = true; + }; + + users.groups.usermetrics = { }; }; # TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready? testScript = { nodes, ... }: let - runCommandPerIndicatorService = command: lib.strings.concatMapStringsSep "\n" command nodes.machine.systemd.user.targets."ayatana-indicators".wants; + runCommandOverServiceList = list: command: + lib.strings.concatMapStringsSep "\n" command list; + + runCommandOverAyatanaIndicators = runCommandOverServiceList + (builtins.filter + (service: !(lib.strings.hasPrefix "lomiri" service || lib.strings.hasPrefix "telephony-service" service)) + nodes.machine.systemd.user.targets."ayatana-indicators".wants); + + runCommandOverAllIndicators = runCommandOverServiceList + nodes.machine.systemd.user.targets."ayatana-indicators".wants; in '' start_all() machine.wait_for_x() @@ -50,8 +89,8 @@ in { machine.sleep(10) # Now check if all indicators were brought up successfully, and kill them for later - '' + (runCommandPerIndicatorService (service: let serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service; in '' - machine.succeed("pgrep -f ${serviceExec}") + '' + (runCommandOverAyatanaIndicators (service: let serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service; in '' + machine.succeed("pgrep -u ${user} -f ${serviceExec}") machine.succeed("pkill -f ${serviceExec}") '')) + '' @@ -65,7 +104,7 @@ in { machine.sleep(10) # Now check if all indicator services were brought up successfully - '' + runCommandPerIndicatorService (service: '' + '' + runCommandOverAllIndicators (service: '' machine.wait_for_unit("${service}", "${user}") ''); }) diff --git a/nixos/tests/babeld.nix b/nixos/tests/babeld.nix index d4df6f86d089d..e497aa5b64e15 100644 --- a/nixos/tests/babeld.nix +++ b/nixos/tests/babeld.nix @@ -120,10 +120,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { '' start_all() - client.wait_for_unit("network-online.target") - local_router.wait_for_unit("network-online.target") - remote_router.wait_for_unit("network-online.target") - local_router.wait_for_unit("babeld.service") remote_router.wait_for_unit("babeld.service") diff --git a/nixos/tests/bittorrent.nix b/nixos/tests/bittorrent.nix index 4a73fea6a09d0..473b05d4c98e8 100644 --- a/nixos/tests/bittorrent.nix +++ b/nixos/tests/bittorrent.nix @@ -115,6 +115,7 @@ in start_all() # Wait for network and miniupnpd. + router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") router.wait_for_unit("miniupnpd") @@ -129,6 +130,7 @@ in tracker.succeed("chmod 644 /tmp/test.torrent") # Start the tracker. !!! use a less crappy tracker + tracker.systemctl("start network-online.target") tracker.wait_for_unit("network-online.target") tracker.wait_for_unit("opentracker.service") tracker.wait_for_open_port(6969) @@ -140,6 +142,7 @@ in # Now we should be able to download from the client behind the NAT. tracker.wait_for_unit("httpd") + client1.systemctl("start network-online.target") client1.wait_for_unit("network-online.target") client1.succeed("transmission-remote --add http://${externalTrackerAddress}/test.torrent >&2 &") client1.wait_for_file("${download-dir}/test.tar.bz2") @@ -152,6 +155,7 @@ in # Now download from the second client. This can only succeed if # the first client created a NAT hole in the router. + client2.systemctl("start network-online.target") client2.wait_for_unit("network-online.target") client2.succeed( "transmission-remote --add http://${externalTrackerAddress}/test.torrent --no-portmap --no-dht >&2 &" diff --git a/nixos/tests/buildbot.nix b/nixos/tests/buildbot.nix index 2f6926313b7cd..149d73bba09c5 100644 --- a/nixos/tests/buildbot.nix +++ b/nixos/tests/buildbot.nix @@ -71,6 +71,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { gitrepo.wait_for_unit("multi-user.target") with subtest("Repo is accessible via git daemon"): + bbmaster.systemctl("start network-online.target") bbmaster.wait_for_unit("network-online.target") bbmaster.succeed("rm -rfv /tmp/fakerepo") bbmaster.succeed("git clone git://gitrepo/fakerepo /tmp/fakerepo") @@ -78,6 +79,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { with subtest("Master service and worker successfully connect"): bbmaster.wait_for_unit("buildbot-master.service") bbmaster.wait_until_succeeds("curl --fail -s --head http://bbmaster:8010") + bbworker.systemctl("start network-online.target") bbworker.wait_for_unit("network-online.target") bbworker.succeed("nc -z bbmaster 8010") bbworker.succeed("nc -z bbmaster 9989") diff --git a/nixos/tests/ceph-multi-node.nix b/nixos/tests/ceph-multi-node.nix index 556546beee764..b1352a4bc8f4e 100644 --- a/nixos/tests/ceph-multi-node.nix +++ b/nixos/tests/ceph-multi-node.nix @@ -185,6 +185,14 @@ let monA.succeed( "ceph osd pool create multi-node-test 32 32", "ceph osd pool ls | grep 'multi-node-test'", + + # We need to enable an application on the pool, otherwise it will + # stay unhealthy in state POOL_APP_NOT_ENABLED. + # Creating a CephFS would do this automatically, but we haven't done that here. + # See: https://docs.ceph.com/en/reef/rados/operations/pools/#associating-a-pool-with-an-application + # We use the custom application name "nixos-test" for this. + "ceph osd pool application enable multi-node-test nixos-test", + "ceph osd pool rename multi-node-test multi-node-other-test", "ceph osd pool ls | grep 'multi-node-other-test'", ) diff --git a/nixos/tests/ceph-single-node-bluestore.nix b/nixos/tests/ceph-single-node-bluestore.nix index acaae4cf300e8..8bd1a78244a29 100644 --- a/nixos/tests/ceph-single-node-bluestore.nix +++ b/nixos/tests/ceph-single-node-bluestore.nix @@ -145,6 +145,14 @@ let monA.succeed( "ceph osd pool create single-node-test 32 32", "ceph osd pool ls | grep 'single-node-test'", + + # We need to enable an application on the pool, otherwise it will + # stay unhealthy in state POOL_APP_NOT_ENABLED. + # Creating a CephFS would do this automatically, but we haven't done that here. + # See: https://docs.ceph.com/en/reef/rados/operations/pools/#associating-a-pool-with-an-application + # We use the custom application name "nixos-test" for this. + "ceph osd pool application enable single-node-test nixos-test", + "ceph osd pool rename single-node-test single-node-other-test", "ceph osd pool ls | grep 'single-node-other-test'", ) diff --git a/nixos/tests/ceph-single-node.nix b/nixos/tests/ceph-single-node.nix index a3a4072365af8..c34ec511dc6d2 100644 --- a/nixos/tests/ceph-single-node.nix +++ b/nixos/tests/ceph-single-node.nix @@ -145,6 +145,14 @@ let monA.succeed( "ceph osd pool create single-node-test 32 32", "ceph osd pool ls | grep 'single-node-test'", + + # We need to enable an application on the pool, otherwise it will + # stay unhealthy in state POOL_APP_NOT_ENABLED. + # Creating a CephFS would do this automatically, but we haven't done that here. + # See: https://docs.ceph.com/en/reef/rados/operations/pools/#associating-a-pool-with-an-application + # We use the custom application name "nixos-test" for this. + "ceph osd pool application enable single-node-test nixos-test", + "ceph osd pool rename single-node-test single-node-other-test", "ceph osd pool ls | grep 'single-node-other-test'", ) @@ -182,19 +190,16 @@ let monA.wait_until_succeeds("ceph -s | grep 'mgr: ${cfg.monA.name}(active,'") monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'") - # This test has been commented out due to the upstream issue with pyo3 - # that has broken this dashboard - # Reference: https://www.spinics.net/lists/ceph-users/msg77812.html # Enable the dashboard and recheck health - # monA.succeed( - # "ceph mgr module enable dashboard", - # "ceph config set mgr mgr/dashboard/ssl false", - # # default is 8080 but it's better to be explicit - # "ceph config set mgr mgr/dashboard/server_port 8080", - # ) - # monA.wait_for_open_port(8080) - # monA.wait_until_succeeds("curl -q --fail http://localhost:8080") - # monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'") + monA.succeed( + "ceph mgr module enable dashboard", + "ceph config set mgr mgr/dashboard/ssl false", + # default is 8080 but it's better to be explicit + "ceph config set mgr mgr/dashboard/server_port 8080", + ) + monA.wait_for_open_port(8080) + monA.wait_until_succeeds("curl -q --fail http://localhost:8080") + monA.wait_until_succeeds("ceph -s | grep 'HEALTH_OK'") ''; in { name = "basic-single-node-ceph-cluster"; diff --git a/nixos/tests/cloud-init.nix b/nixos/tests/cloud-init.nix index 786e01add7d4b..0b4c5a55c80a6 100644 --- a/nixos/tests/cloud-init.nix +++ b/nixos/tests/cloud-init.nix @@ -73,6 +73,7 @@ in makeTest { }; testScript = '' # To wait until cloud-init terminates its run + unnamed.wait_for_unit("cloud-init-local.service") unnamed.wait_for_unit("cloud-final.service") unnamed.succeed("cat /tmp/cloudinit-write-file | grep -q 'cloudinit'") diff --git a/nixos/tests/corerad.nix b/nixos/tests/corerad.nix index b6f5d7fc6f75b..dd2bec794a1a0 100644 --- a/nixos/tests/corerad.nix +++ b/nixos/tests/corerad.nix @@ -56,6 +56,8 @@ import ./make-test-python.nix ( with subtest("Wait for CoreRAD and network ready"): # Ensure networking is online and CoreRAD is ready. + router.systemctl("start network-online.target") + client.systemctl("start network-online.target") router.wait_for_unit("network-online.target") client.wait_for_unit("network-online.target") router.wait_for_unit("corerad.service") diff --git a/nixos/tests/curl-impersonate.nix b/nixos/tests/curl-impersonate.nix index 7954e9e5584c4..33b10da1dfd0f 100644 --- a/nixos/tests/curl-impersonate.nix +++ b/nixos/tests/curl-impersonate.nix @@ -144,6 +144,8 @@ in { start_all() with subtest("Wait for network"): + web.systemctl("start network-online.target") + curl.systemctl("start network-online.target") web.wait_for_unit("network-online.target") curl.wait_for_unit("network-online.target") diff --git a/nixos/tests/dolibarr.nix b/nixos/tests/dolibarr.nix index 4fdee9e9698f5..95557d317fab9 100644 --- a/nixos/tests/dolibarr.nix +++ b/nixos/tests/dolibarr.nix @@ -1,6 +1,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "dolibarr"; - meta.maintainers = [ lib.maintainers.raitobezarius ]; + meta.maintainers = [ ]; nodes.machine = { ... }: diff --git a/nixos/tests/elk.nix b/nixos/tests/elk.nix index 900ea6320100f..b5a8cb532ae0a 100644 --- a/nixos/tests/elk.nix +++ b/nixos/tests/elk.nix @@ -1,6 +1,6 @@ # To run the test on the unfree ELK use the following command: # cd path/to/nixpkgs -# NIXPKGS_ALLOW_UNFREE=1 nix-build -A nixosTests.elk.unfree.ELK-6 +# NIXPKGS_ALLOW_UNFREE=1 nix-build -A nixosTests.elk.unfree.ELK-7 { system ? builtins.currentSystem, config ? {}, @@ -120,7 +120,7 @@ let }; elasticsearch-curator = { - enable = true; + enable = elk ? elasticsearch-curator; actionYAML = '' --- actions: @@ -246,7 +246,7 @@ let one.wait_until_succeeds( expect_hits("SuperdupercalifragilisticexpialidociousIndeed") ) - '' + '' + '' + lib.optionalString (elk ? elasticsearch-curator) '' with subtest("Elasticsearch-curator works"): one.systemctl("stop logstash") one.systemctl("start elasticsearch-curator") diff --git a/nixos/tests/ferm.nix b/nixos/tests/ferm.nix index be43877445ebf..87c67ac623479 100644 --- a/nixos/tests/ferm.nix +++ b/nixos/tests/ferm.nix @@ -55,6 +55,8 @@ import ./make-test-python.nix ({ pkgs, ...} : { '' start_all() + client.systemctl("start network-online.target") + server.systemctl("start network-online.target") client.wait_for_unit("network-online.target") server.wait_for_unit("network-online.target") server.wait_for_unit("ferm.service") diff --git a/nixos/tests/frp.nix b/nixos/tests/frp.nix index 2f5c0f8ec933b..1f57c031a53a5 100644 --- a/nixos/tests/frp.nix +++ b/nixos/tests/frp.nix @@ -18,10 +18,8 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { enable = true; role = "server"; settings = { - common = { - bind_port = 7000; - vhost_http_port = 80; - }; + bindPort = 7000; + vhostHTTPPort = 80; }; }; }; @@ -59,15 +57,16 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { enable = true; role = "client"; settings = { - common = { - server_addr = "10.0.0.1"; - server_port = 7000; - }; - web = { - type = "http"; - local_port = 80; - custom_domains = "10.0.0.1"; - }; + serverAddr = "10.0.0.1"; + serverPort = 7000; + proxies = [ + { + name = "web"; + type = "http"; + localPort = 80; + customDomains = [ "10.0.0.1" ]; + } + ]; }; }; }; diff --git a/nixos/tests/gitdaemon.nix b/nixos/tests/gitdaemon.nix index bb07b6e97b7fb..052fa902b4504 100644 --- a/nixos/tests/gitdaemon.nix +++ b/nixos/tests/gitdaemon.nix @@ -59,6 +59,9 @@ in { with subtest("git daemon starts"): server.wait_for_unit("git-daemon.service") + + server.systemctl("start network-online.target") + client.systemctl("start network-online.target") server.wait_for_unit("network-online.target") client.wait_for_unit("network-online.target") diff --git a/nixos/tests/guix/publish.nix b/nixos/tests/guix/publish.nix index a15e00b0fa981..eb56fc97478cc 100644 --- a/nixos/tests/guix/publish.nix +++ b/nixos/tests/guix/publish.nix @@ -80,6 +80,7 @@ in { # Now it's the client turn to make use of it. substitute_server = "http://server.local:${toString publishPort}" + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") response = client.succeed(f"curl {substitute_server}") assert "Guix Substitute Server" in response diff --git a/nixos/tests/haproxy.nix b/nixos/tests/haproxy.nix index 555474d7f2999..1730938737577 100644 --- a/nixos/tests/haproxy.nix +++ b/nixos/tests/haproxy.nix @@ -1,22 +1,42 @@ -import ./make-test-python.nix ({ pkgs, ...}: { +import ./make-test-python.nix ({ lib, pkgs, ...}: { name = "haproxy"; nodes = { - machine = { ... }: { - services.haproxy = { + server = { ... }: { + services.haproxy = { enable = true; config = '' + global + limited-quic + defaults + mode http timeout connect 10s + timeout client 10s + timeout server 10s + + log /dev/log local0 debug err + option logasap + option httplog + option httpslog backend http_server - mode http - server httpd [::1]:8000 + server httpd [::1]:8000 alpn http/1.1 frontend http - bind *:80 - mode http + bind :80 + bind :443 ssl strict-sni crt /etc/ssl/fullchain.pem alpn h2,http/1.1 + bind quic4@:443 ssl strict-sni crt /etc/ssl/fullchain.pem alpn h3 allow-0rtt + + http-after-response add-header alt-svc 'h3=":443"; ma=60' if { ssl_fc } + http-request use-service prometheus-exporter if { path /metrics } use_backend http_server + + frontend http-cert-auth + bind :8443 ssl strict-sni crt /etc/ssl/fullchain.pem verify required ca-file /etc/ssl/cacert.crt + bind quic4@:8443 ssl strict-sni crt /etc/ssl/fullchain.pem verify required ca-file /etc/ssl/cacert.crt alpn h3 + + use_backend http_server ''; }; services.httpd = { @@ -30,24 +50,75 @@ import ./make-test-python.nix ({ pkgs, ...}: { }]; }; }; + networking.firewall.allowedTCPPorts = [ 80 443 8443 ]; + networking.firewall.allowedUDPPorts = [ 443 8443 ]; + }; + client = { ... }: { + environment.systemPackages = [ pkgs.curlHTTP3 ]; }; }; testScript = '' + # Helpers + def cmd(command): + print(f"+{command}") + r = os.system(command) + if r != 0: + raise Exception(f"Command {command} failed with exit code {r}") + + def openssl(command): + cmd(f"${pkgs.openssl}/bin/openssl {command}") + + # Generate CA. + openssl("req -new -newkey rsa:4096 -nodes -x509 -days 7 -subj '/C=ZZ/ST=Cloud/L=Unspecified/O=NixOS/OU=Tests/CN=CA Certificate' -keyout cacert.key -out cacert.crt") + + # Generate and sign Server. + openssl("req -newkey rsa:4096 -nodes -subj '/CN=server/OU=Tests/O=NixOS' -keyout server.key -out server.csr") + openssl("x509 -req -in server.csr -out server.crt -CA cacert.crt -CAkey cacert.key -days 7") + cmd("cat server.crt server.key > fullchain.pem") + + # Generate and sign Client. + openssl("req -newkey rsa:4096 -nodes -subj '/CN=client/OU=Tests/O=NixOS' -keyout client.key -out client.csr") + openssl("x509 -req -in client.csr -out client.crt -CA cacert.crt -CAkey cacert.key -days 7") + cmd("cat client.crt client.key > client.pem") + + # Start the actual test. start_all() - machine.wait_for_unit("multi-user.target") - machine.wait_for_unit("haproxy.service") - machine.wait_for_unit("httpd.service") - assert "We are all good!" in machine.succeed("curl -fk http://localhost:80/index.txt") - assert "haproxy_process_pool_allocated_bytes" in machine.succeed( - "curl -fk http://localhost:80/metrics" - ) + server.copy_from_host("fullchain.pem", "/etc/ssl/fullchain.pem") + server.copy_from_host("cacert.crt", "/etc/ssl/cacert.crt") + server.succeed("chmod 0644 /etc/ssl/fullchain.pem /etc/ssl/cacert.crt") + + client.copy_from_host("cacert.crt", "/etc/ssl/cacert.crt") + client.copy_from_host("client.pem", "/root/client.pem") + + server.wait_for_unit("multi-user.target") + server.wait_for_unit("haproxy.service") + server.wait_for_unit("httpd.service") + + assert "We are all good!" in client.succeed("curl -f http://server/index.txt") + assert "haproxy_process_pool_allocated_bytes" in client.succeed("curl -f http://server/metrics") + + with subtest("https"): + assert "We are all good!" in client.succeed("curl -f --cacert /etc/ssl/cacert.crt https://server/index.txt") + + with subtest("https-cert-auth"): + # Client must succeed in authenticating with the right certificate. + assert "We are all good!" in client.succeed("curl -f --cacert /etc/ssl/cacert.crt --cert-type pem --cert /root/client.pem https://server:8443/index.txt") + # Client must fail without certificate. + client.fail("curl --cacert /etc/ssl/cacert.crt https://server:8443/index.txt") + + with subtest("h3"): + assert "We are all good!" in client.succeed("curl -f --http3-only --cacert /etc/ssl/cacert.crt https://server/index.txt") + + with subtest("h3-cert-auth"): + # Client must succeed in authenticating with the right certificate. + assert "We are all good!" in client.succeed("curl -f --http3-only --cacert /etc/ssl/cacert.crt --cert-type pem --cert /root/client.pem https://server:8443/index.txt") + # Client must fail without certificate. + client.fail("curl -f --http3-only --cacert /etc/ssl/cacert.crt https://server:8443/index.txt") with subtest("reload"): - machine.succeed("systemctl reload haproxy") + server.succeed("systemctl reload haproxy") # wait some time to ensure the following request hits the reloaded haproxy - machine.sleep(5) - assert "We are all good!" in machine.succeed( - "curl -fk http://localhost:80/index.txt" - ) + server.sleep(5) + assert "We are all good!" in client.succeed("curl -f http://server/index.txt") ''; }) diff --git a/nixos/tests/hostname.nix b/nixos/tests/hostname.nix index 6122e2ffeb83a..dffec956bc0b6 100644 --- a/nixos/tests/hostname.nix +++ b/nixos/tests/hostname.nix @@ -34,6 +34,7 @@ let machine = ${hostName} + machine.systemctl("start network-online.target") machine.wait_for_unit("network-online.target") # Test if NixOS computes the correct FQDN (either a FQDN or an error/null): diff --git a/nixos/tests/incus/default.nix b/nixos/tests/incus/default.nix index c88974605e306..26e8a4ac4c772 100644 --- a/nixos/tests/incus/default.nix +++ b/nixos/tests/incus/default.nix @@ -6,9 +6,8 @@ }: { container = import ./container.nix { inherit system pkgs; }; + lxd-to-incus = import ./lxd-to-incus.nix { inherit system pkgs; }; preseed = import ./preseed.nix { inherit system pkgs; }; socket-activated = import ./socket-activated.nix { inherit system pkgs; }; - virtual-machine = handleTestOn [ "x86_64-linux" ] ./virtual-machine.nix { - inherit system pkgs; - }; + virtual-machine = handleTestOn [ "x86_64-linux" ] ./virtual-machine.nix { inherit system pkgs; }; } diff --git a/nixos/tests/incus/lxd-to-incus.nix b/nixos/tests/incus/lxd-to-incus.nix new file mode 100644 index 0000000000000..67245b54e7527 --- /dev/null +++ b/nixos/tests/incus/lxd-to-incus.nix @@ -0,0 +1,112 @@ +import ../make-test-python.nix ( + + { pkgs, lib, ... }: + + let + releases = import ../../release.nix { configuration.documentation.enable = lib.mkForce false; }; + + container-image-metadata = releases.lxdContainerMeta.${pkgs.stdenv.hostPlatform.system}; + container-image-rootfs = releases.lxdContainerImage.${pkgs.stdenv.hostPlatform.system}; + in + { + name = "lxd-to-incus"; + + meta = { + maintainers = lib.teams.lxc.members; + }; + + nodes.machine = + { lib, ... }: + { + environment.systemPackages = [ pkgs.lxd-to-incus ]; + + virtualisation = { + diskSize = 6144; + cores = 2; + memorySize = 2048; + + lxd.enable = true; + lxd.preseed = { + networks = [ + { + name = "nixostestbr0"; + type = "bridge"; + config = { + "ipv4.address" = "10.0.100.1/24"; + "ipv4.nat" = "true"; + }; + } + ]; + profiles = [ + { + name = "default"; + devices = { + eth0 = { + name = "eth0"; + network = "nixostestbr0"; + type = "nic"; + }; + root = { + path = "/"; + pool = "nixostest_pool"; + size = "35GiB"; + type = "disk"; + }; + }; + } + { + name = "nixos_notdefault"; + devices = { }; + } + ]; + storage_pools = [ + { + name = "nixostest_pool"; + driver = "dir"; + } + ]; + }; + + incus.enable = true; + }; + }; + + testScript = '' + def lxd_wait_for_preseed(_) -> bool: + _, output = machine.systemctl("is-active lxd-preseed.service") + return ("inactive" in output) + + def lxd_instance_is_up(_) -> bool: + status, _ = machine.execute("lxc exec container --disable-stdin --force-interactive /run/current-system/sw/bin/true") + return status == 0 + + def incus_instance_is_up(_) -> bool: + status, _ = machine.execute("incus exec container --disable-stdin --force-interactive /run/current-system/sw/bin/true") + return status == 0 + + with machine.nested("initialize lxd and resources"): + machine.wait_for_unit("sockets.target") + machine.wait_for_unit("lxd.service") + retry(lxd_wait_for_preseed) + + machine.succeed("lxc image import ${container-image-metadata}/*/*.tar.xz ${container-image-rootfs}/*/*.tar.xz --alias nixos") + machine.succeed("lxc launch nixos container") + retry(lxd_instance_is_up) + + machine.wait_for_unit("incus.service") + + with machine.nested("run migration"): + machine.succeed("lxd-to-incus --yes") + + with machine.nested("verify resources migrated to incus"): + machine.succeed("incus config show container") + retry(incus_instance_is_up) + machine.succeed("incus exec container -- true") + machine.succeed("incus profile show default | grep nixostestbr0") + machine.succeed("incus profile show default | grep nixostest_pool") + machine.succeed("incus profile show nixos_notdefault") + machine.succeed("incus storage show nixostest_pool") + machine.succeed("incus network show nixostestbr0") + ''; + } +) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 21d5e1470d8e0..7576fae41f83b 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -158,7 +158,9 @@ let start_all() ${optionalString clevisTest '' tang.wait_for_unit("sockets.target") + tang.systemctl("start network-online.target") tang.wait_for_unit("network-online.target") + machine.systemctl("start network-online.target") machine.wait_for_unit("network-online.target") ''} machine.wait_for_unit("multi-user.target") @@ -187,6 +189,7 @@ let ${optionalString clevisTest '' with subtest("Create the Clevis secret with Tang"): + machine.systemctl("start network-online.target") machine.wait_for_unit("network-online.target") machine.succeed('echo -n password | clevis encrypt sss \'{"t": 2, "pins": {"tpm2": {}, "tang": {"url": "http://192.168.1.2"}}}\' -y > /mnt/etc/nixos/clevis-secret.jwe')''} diff --git a/nixos/tests/kanidm.nix b/nixos/tests/kanidm.nix index 3f5bca397740e..fa24d4a8a5e13 100644 --- a/nixos/tests/kanidm.nix +++ b/nixos/tests/kanidm.nix @@ -67,6 +67,7 @@ import ./make-test-python.nix ({ pkgs, ... }: '' start_all() server.wait_for_unit("kanidm.service") + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") with subtest("Test HTTP interface"): diff --git a/nixos/tests/keepalived.nix b/nixos/tests/keepalived.nix index d0bf9d4652003..ce291514591fe 100644 --- a/nixos/tests/keepalived.nix +++ b/nixos/tests/keepalived.nix @@ -1,5 +1,6 @@ -import ./make-test-python.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "keepalived"; + maintainers = [ lib.maintainers.raitobezarius ]; nodes = { node1 = { pkgs, ... }: { diff --git a/nixos/tests/lemmy.nix b/nixos/tests/lemmy.nix index de2c4938fe231..e8d747f89a9e7 100644 --- a/nixos/tests/lemmy.nix +++ b/nixos/tests/lemmy.nix @@ -59,6 +59,7 @@ in server.succeed("curl --fail localhost:${toString uiPort}") with subtest("Lemmy-UI responds through the caddy reverse proxy"): + server.systemctl("start network-online.target") server.wait_for_unit("network-online.target") server.wait_for_unit("caddy.service") server.wait_for_open_port(80) @@ -66,6 +67,7 @@ in assert "Lemmy" in body, f"String Lemmy not found in response for ${lemmyNodeName}: \n{body}" with subtest("the server is exposed externally"): + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") client.succeed("curl -v --fail ${lemmyNodeName}") diff --git a/nixos/tests/miriway.nix b/nixos/tests/miriway.nix index f12c4d5ecc41e..a0987d9fc41b6 100644 --- a/nixos/tests/miriway.nix +++ b/nixos/tests/miriway.nix @@ -31,7 +31,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { enable-x11= ctrl-alt=t:foot --maximized - ctrl-alt=a:env WINIT_UNIX_BACKEND=x11 WAYLAND_DISPLAY=invalid alacritty --option window.startup_mode=maximized + ctrl-alt=a:env WINIT_UNIX_BACKEND=x11 WAYLAND_DISPLAY= alacritty --option window.startup_mode=\"maximized\" shell-component=dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix index 768d0cfa2238c..6bd89902eedb3 100644 --- a/nixos/tests/networking.nix +++ b/nixos/tests/networking.nix @@ -130,6 +130,7 @@ let start_all() client.wait_for_unit("network.target") + router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") with subtest("Make sure DHCP server is not started"): @@ -222,6 +223,7 @@ let start_all() client.wait_for_unit("network.target") + router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") with subtest("Wait until we have an ip address on each interface"): @@ -849,6 +851,7 @@ let client.wait_for_unit("network.target") client_with_privacy.wait_for_unit("network.target") + router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") with subtest("Wait until we have an ip address"): diff --git a/nixos/tests/nfs/kerberos.nix b/nixos/tests/nfs/kerberos.nix index 1bace4058be59..5944b53319a0b 100644 --- a/nixos/tests/nfs/kerberos.nix +++ b/nixos/tests/nfs/kerberos.nix @@ -105,6 +105,7 @@ in server.wait_for_unit("rpc-gssd.service") server.wait_for_unit("rpc-svcgssd.service") + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") # add principals to client keytab diff --git a/nixos/tests/nginx-moreheaders.nix b/nixos/tests/nginx-moreheaders.nix new file mode 100644 index 0000000000000..560dcf9ce0b82 --- /dev/null +++ b/nixos/tests/nginx-moreheaders.nix @@ -0,0 +1,37 @@ +import ./make-test-python.nix { + name = "nginx-more-headers"; + + nodes = { + webserver = { pkgs, ... }: { + services.nginx = { + enable = true; + + virtualHosts.test = { + locations = { + "/".return = "200 blub"; + "/some" = { + return = "200 blub"; + extraConfig = '' + more_set_headers "Referrer-Policy: no-referrer"; + ''; + }; + }; + extraConfig = '' + more_set_headers "X-Powered-By: nixos"; + ''; + }; + }; + }; + }; + + testScript = '' + webserver.wait_for_unit("nginx") + webserver.wait_for_open_port(80) + + webserver.succeed("curl --fail --resolve test:80:127.0.0.1 --head --verbose http://test | grep -q \"X-Powered-By: nixos\"") + webserver.fail("curl --fail --resolve test:80:127.0.0.1 --head --verbose http://test | grep -q \"Referrer-Policy: no-referrer\"") + + webserver.succeed("curl --fail --resolve test:80:127.0.0.1 --head --verbose http://test/some | grep -q \"X-Powered-By: nixos\"") + webserver.succeed("curl --fail --resolve test:80:127.0.0.1 --head --verbose http://test/some | grep -q \"Referrer-Policy: no-referrer\"") + ''; +} diff --git a/nixos/tests/nixops/default.nix b/nixos/tests/nixops/default.nix index f7a26f2461c4c..6501d13a2ed36 100644 --- a/nixos/tests/nixops/default.nix +++ b/nixos/tests/nixops/default.nix @@ -1,6 +1,4 @@ -{ pkgs -, testers -, ... }: +{ pkgs, ... }: let inherit (pkgs) lib; @@ -21,7 +19,7 @@ let passthru.override = args': testsForPackage (args // args'); }; - testLegacyNetwork = { nixopsPkg, ... }: testers.nixosTest ({ + testLegacyNetwork = { nixopsPkg, ... }: pkgs.testers.nixosTest ({ name = "nixops-legacy-network"; nodes = { deployer = { config, lib, nodes, pkgs, ... }: { diff --git a/nixos/tests/ntpd-rs.nix b/nixos/tests/ntpd-rs.nix index 2901be5235208..6f3c80e87f072 100644 --- a/nixos/tests/ntpd-rs.nix +++ b/nixos/tests/ntpd-rs.nix @@ -41,9 +41,11 @@ import ./make-test-python.nix ({ lib, ... }: testScript = { nodes, ... }: '' start_all() - server.wait_for_unit('multi-user.target') - client.wait_for_unit('multi-user.target') - server.succeed('systemctl is-active ntpd-rs.service') - client.succeed('systemctl is-active ntpd-rs.service') + + for machine in (server, client): + machine.wait_for_unit('multi-user.target') + machine.succeed('systemctl is-active ntpd-rs.service') + machine.succeed('systemctl is-active ntpd-rs-metrics.service') + machine.succeed('curl http://localhost:9975/metrics | grep ntp_uptime_seconds') ''; }) diff --git a/nixos/tests/opensmtpd-rspamd.nix b/nixos/tests/opensmtpd-rspamd.nix index 19969a7b47ddd..e413a2050bd61 100644 --- a/nixos/tests/opensmtpd-rspamd.nix +++ b/nixos/tests/opensmtpd-rspamd.nix @@ -119,6 +119,7 @@ import ./make-test-python.nix { testScript = '' start_all() + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") smtp1.wait_for_unit("opensmtpd") smtp2.wait_for_unit("opensmtpd") diff --git a/nixos/tests/opensmtpd.nix b/nixos/tests/opensmtpd.nix index 17c1a569ba0d9..d32f82ed33b8c 100644 --- a/nixos/tests/opensmtpd.nix +++ b/nixos/tests/opensmtpd.nix @@ -104,6 +104,7 @@ import ./make-test-python.nix { testScript = '' start_all() + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") smtp1.wait_for_unit("opensmtpd") smtp2.wait_for_unit("opensmtpd") diff --git a/nixos/tests/openssh.nix b/nixos/tests/openssh.nix index 799497477993b..8074fd2ed4838 100644 --- a/nixos/tests/openssh.nix +++ b/nixos/tests/openssh.nix @@ -34,6 +34,19 @@ in { ]; }; + server-lazy-socket = { + virtualisation.vlans = [ 1 2 ]; + services.openssh = { + enable = true; + startWhenNeeded = true; + ports = [ 2222 ]; + listenAddresses = [ { addr = "0.0.0.0"; } ]; + }; + users.users.root.openssh.authorizedKeys.keys = [ + snakeOilPublicKey + ]; + }; + server-localhost-only = { ... }: @@ -96,7 +109,9 @@ in { }; client = - { ... }: { }; + { ... }: { + virtualisation.vlans = [ 1 2 ]; + }; }; @@ -109,6 +124,7 @@ in { server_lazy.wait_for_unit("sshd.socket", timeout=30) server_localhost_only_lazy.wait_for_unit("sshd.socket", timeout=30) + server_lazy_socket.wait_for_unit("sshd.socket", timeout=30) with subtest("manual-authkey"): client.succeed("mkdir -m 700 /root/.ssh") @@ -145,6 +161,16 @@ in { timeout=30 ) + with subtest("socket activation on a non-standard port"): + client.succeed( + "cat ${snakeOilPrivateKey} > privkey.snakeoil" + ) + client.succeed("chmod 600 privkey.snakeoil") + client.succeed( + "ssh -p 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil root@192.168.2.4 true", + timeout=30 + ) + with subtest("configured-authkey"): client.succeed( "cat ${snakeOilPrivateKey} > privkey.snakeoil" diff --git a/nixos/tests/owncast.nix b/nixos/tests/owncast.nix index debb34f5009dc..73aac4e704751 100644 --- a/nixos/tests/owncast.nix +++ b/nixos/tests/owncast.nix @@ -31,6 +31,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { testScript = '' start_all() + client.systemctl("start network-online.target") + server.systemctl("start network-online.target") client.wait_for_unit("network-online.target") server.wait_for_unit("network-online.target") server.wait_for_unit("owncast.service") diff --git a/nixos/tests/podman/default.nix b/nixos/tests/podman/default.nix index 0e1f420f2a7de..3eea45832f0a6 100644 --- a/nixos/tests/podman/default.nix +++ b/nixos/tests/podman/default.nix @@ -24,8 +24,6 @@ import ../make-test-python.nix ( virtualisation.podman.enable = true; virtualisation.podman.defaultNetwork.settings.dns_enabled = true; - - networking.firewall.allowedUDPPorts = [ 53 ]; }; docker = { pkgs, ... }: { virtualisation.podman.enable = true; diff --git a/nixos/tests/postgis.nix b/nixos/tests/postgis.nix index 09c738b938ba8..dacf4e576c071 100644 --- a/nixos/tests/postgis.nix +++ b/nixos/tests/postgis.nix @@ -24,6 +24,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { master.wait_for_unit("postgresql") master.sleep(10) # Hopefully this is long enough!! master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis;'") + master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis_raster;'") master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis_topology;'") ''; }) diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix index 53e6626c0e324..5872b02b609e1 100644 --- a/nixos/tests/prometheus-exporters.nix +++ b/nixos/tests/prometheus-exporters.nix @@ -1392,9 +1392,11 @@ let snmp = { exporterConfig = { enable = true; - configuration.default = { - version = 2; - auth.community = "public"; + configuration = { + auths.public_v2 = { + community = "public"; + version = 2; + }; }; }; exporterTest = '' diff --git a/nixos/tests/qemu-vm-restrictnetwork.nix b/nixos/tests/qemu-vm-restrictnetwork.nix index 49a105ef10767..49aefcc099bda 100644 --- a/nixos/tests/qemu-vm-restrictnetwork.nix +++ b/nixos/tests/qemu-vm-restrictnetwork.nix @@ -21,6 +21,8 @@ import ./make-test-python.nix ({ else: start_all() + unrestricted.systemctl("start network-online.target") + restricted.systemctl("start network-online.target") unrestricted.wait_for_unit("network-online.target") restricted.wait_for_unit("network-online.target") diff --git a/nixos/tests/rss2email.nix b/nixos/tests/rss2email.nix index f32326feb50fb..60b27b95fabe4 100644 --- a/nixos/tests/rss2email.nix +++ b/nixos/tests/rss2email.nix @@ -55,6 +55,7 @@ import ./make-test-python.nix { testScript = '' start_all() + server.systemctl("start network-online.target") server.wait_for_unit("network-online.target") server.wait_for_unit("opensmtpd") server.wait_for_unit("dovecot2") diff --git a/nixos/tests/ssh-audit.nix b/nixos/tests/ssh-audit.nix index bd6255b8044d9..25772aba3ea08 100644 --- a/nixos/tests/ssh-audit.nix +++ b/nixos/tests/ssh-audit.nix @@ -70,6 +70,7 @@ import ./make-test-python.nix ( ${serverName}.succeed("${pkgs.ssh-audit}/bin/ssh-audit 127.0.0.1") # Wait for client to be able to connect to the server + ${clientName}.systemctl("start network-online.target") ${clientName}.wait_for_unit("network-online.target") # Set up trusted private key diff --git a/nixos/tests/suwayomi-server.nix b/nixos/tests/suwayomi-server.nix new file mode 100644 index 0000000000000..36072028380b8 --- /dev/null +++ b/nixos/tests/suwayomi-server.nix @@ -0,0 +1,46 @@ +{ system ? builtins.currentSystem +, pkgs +, lib ? pkgs.lib +}: +let + inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest; + inherit (lib) recursiveUpdate; + + baseTestConfig = { + meta.maintainers = with lib.maintainers; [ ratcornu ]; + nodes.machine = { pkgs, ... }: { + services.suwayomi-server = { + enable = true; + settings.server.port = 1234; + }; + }; + testScript = '' + machine.wait_for_unit("suwayomi-server.service") + machine.wait_for_open_port(1234) + machine.succeed("curl --fail http://localhost:1234/") + ''; + }; +in + +{ + without-auth = makeTest (recursiveUpdate baseTestConfig { + name = "suwayomi-server-without-auth"; + }); + + with-auth = makeTest (recursiveUpdate baseTestConfig { + name = "suwayomi-server-with-auth"; + + nodes.machine = { pkgs, ... }: { + services.suwayomi-server = { + enable = true; + + settings.server = { + port = 1234; + basicAuthEnabled = true; + basicAuthUsername = "alice"; + basicAuthPasswordFile = pkgs.writeText "snakeoil-pass.txt" "pass"; + }; + }; + }; + }); +} diff --git a/nixos/tests/sysinit-reactivation.nix b/nixos/tests/sysinit-reactivation.nix new file mode 100644 index 0000000000000..1a0caecb610a3 --- /dev/null +++ b/nixos/tests/sysinit-reactivation.nix @@ -0,0 +1,107 @@ +# This runs to two scenarios but in one tests: +# - A post-sysinit service needs to be restarted AFTER tmpfiles was restarted. +# - A service needs to be restarted BEFORE tmpfiles is restarted + +{ lib, ... }: + +let + makeGeneration = generation: { + "${generation}".configuration = { + systemd.services.pre-sysinit-before-tmpfiles.environment.USER = + lib.mkForce "${generation}-tmpfiles-user"; + + systemd.services.pre-sysinit-after-tmpfiles.environment = { + NEEDED_PATH = lib.mkForce "/run/${generation}-needed-by-pre-sysinit-after-tmpfiles"; + PATH_TO_CREATE = lib.mkForce "/run/${generation}-needed-by-post-sysinit"; + }; + + systemd.services.post-sysinit.environment = { + NEEDED_PATH = lib.mkForce "/run/${generation}-needed-by-post-sysinit"; + PATH_TO_CREATE = lib.mkForce "/run/${generation}-created-by-post-sysinit"; + }; + + systemd.tmpfiles.settings.test = lib.mkForce { + "/run/${generation}-needed-by-pre-sysinit-after-tmpfiles".f.user = + "${generation}-tmpfiles-user"; + }; + }; + }; +in + +{ + + name = "sysinit-reactivation"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes.machine = { config, lib, pkgs, ... }: { + systemd.services.pre-sysinit-before-tmpfiles = { + wantedBy = [ "sysinit.target" ]; + requiredBy = [ "sysinit-reactivation.target" ]; + before = [ "systemd-tmpfiles-setup.service" "systemd-tmpfiles-resetup.service" ]; + unitConfig.DefaultDependencies = false; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + environment.USER = "tmpfiles-user"; + script = "${pkgs.shadow}/bin/useradd $USER"; + }; + + systemd.services.pre-sysinit-after-tmpfiles = { + wantedBy = [ "sysinit.target" ]; + requiredBy = [ "sysinit-reactivation.target" ]; + after = [ "systemd-tmpfiles-setup.service" "systemd-tmpfiles-resetup.service" ]; + unitConfig.DefaultDependencies = false; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + environment = { + NEEDED_PATH = "/run/needed-by-pre-sysinit-after-tmpfiles"; + PATH_TO_CREATE = "/run/needed-by-post-sysinit"; + }; + script = '' + if [[ -e $NEEDED_PATH ]]; then + touch $PATH_TO_CREATE + fi + ''; + }; + + systemd.services.post-sysinit = { + wantedBy = [ "default.target" ]; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + environment = { + NEEDED_PATH = "/run/needed-by-post-sysinit"; + PATH_TO_CREATE = "/run/created-by-post-sysinit"; + }; + script = '' + if [[ -e $NEEDED_PATH ]]; then + touch $PATH_TO_CREATE + fi + ''; + }; + + systemd.tmpfiles.settings.test = { + "/run/needed-by-pre-sysinit-after-tmpfiles".f.user = + "tmpfiles-user"; + }; + + specialisation = lib.mkMerge [ + (makeGeneration "second") + (makeGeneration "third") + ]; + }; + + testScript = { nodes, ... }: '' + def switch(generation): + toplevel = "${nodes.machine.system.build.toplevel}"; + machine.succeed(f"{toplevel}/specialisation/{generation}/bin/switch-to-configuration switch") + + machine.wait_for_unit("default.target") + machine.succeed("test -e /run/created-by-post-sysinit") + + switch("second") + machine.succeed("test -e /run/second-created-by-post-sysinit") + + switch("third") + machine.succeed("test -e /run/third-created-by-post-sysinit") + ''; +} diff --git a/nixos/tests/systemd-networkd-dhcpserver.nix b/nixos/tests/systemd-networkd-dhcpserver.nix index cf0ccb7442118..665d8b5a05291 100644 --- a/nixos/tests/systemd-networkd-dhcpserver.nix +++ b/nixos/tests/systemd-networkd-dhcpserver.nix @@ -101,6 +101,9 @@ import ./make-test-python.nix ({pkgs, ...}: { }; testScript = { ... }: '' start_all() + + router.systemctl("start network-online.target") + client.systemctl("start network-online.target") router.wait_for_unit("systemd-networkd-wait-online.service") client.wait_for_unit("systemd-networkd-wait-online.service") client.wait_until_succeeds("ping -c 5 10.0.2.1") diff --git a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix index 54f371e6c070f..1e55341657bdb 100644 --- a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix +++ b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix @@ -263,9 +263,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { }; }; }; - - # make the network-online target a requirement, we wait for it in our test script - systemd.targets.network-online.wantedBy = [ "multi-user.target" ]; }; # This is the client behind the router. We should be receiving router @@ -278,9 +275,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { useNetworkd = true; useDHCP = false; }; - - # make the network-online target a requirement, we wait for it in our test script - systemd.targets.network-online.wantedBy = [ "multi-user.target" ]; }; }; @@ -294,6 +288,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { # Since we only care about IPv6 that should not involve waiting for legacy # IP leases. client.start() + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") # the static address on the router should not be reachable @@ -312,6 +307,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { isp.wait_for_unit("multi-user.target") # wait until the uplink interface has a good status + router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") router.wait_until_succeeds("ping -6 -c1 2001:DB8::1") diff --git a/nixos/tests/systemd-nspawn.nix b/nixos/tests/systemd-nspawn.nix index 1a4251ef069e8..b86762233d183 100644 --- a/nixos/tests/systemd-nspawn.nix +++ b/nixos/tests/systemd-nspawn.nix @@ -38,6 +38,7 @@ in { start_all() server.wait_for_unit("nginx.service") + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") client.succeed("machinectl pull-raw --verify=signature http://server/testimage.raw") client.succeed( diff --git a/nixos/tests/systemd-sysusers-immutable.nix b/nixos/tests/systemd-sysusers-immutable.nix new file mode 100644 index 0000000000000..42cbf84d175e4 --- /dev/null +++ b/nixos/tests/systemd-sysusers-immutable.nix @@ -0,0 +1,64 @@ +{ lib, ... }: + +let + rootPassword = "$y$j9T$p6OI0WN7.rSfZBOijjRdR.$xUOA2MTcB48ac.9Oc5fz8cxwLv1mMqabnn333iOzSA6"; + normaloPassword = "$y$j9T$3aiOV/8CADAK22OK2QT3/0$67OKd50Z4qTaZ8c/eRWHLIM.o3ujtC1.n9ysmJfv639"; + newNormaloPassword = "mellow"; +in + +{ + + name = "activation-sysusers-immutable"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes.machine = { + systemd.sysusers.enable = true; + users.mutableUsers = false; + + # Override the empty root password set by the test instrumentation + users.users.root.hashedPasswordFile = lib.mkForce null; + users.users.root.initialHashedPassword = rootPassword; + users.users.normalo = { + isNormalUser = true; + initialHashedPassword = normaloPassword; + }; + + specialisation.new-generation.configuration = { + users.users.new-normalo = { + isNormalUser = true; + initialPassword = newNormaloPassword; + }; + }; + }; + + testScript = '' + with subtest("Users are not created with systemd-sysusers"): + machine.fail("systemctl status systemd-sysusers.service") + machine.fail("ls /etc/sysusers.d") + + with subtest("Correct mode on the password files"): + assert machine.succeed("stat -c '%a' /etc/passwd") == "644\n" + assert machine.succeed("stat -c '%a' /etc/group") == "644\n" + assert machine.succeed("stat -c '%a' /etc/shadow") == "0\n" + assert machine.succeed("stat -c '%a' /etc/gshadow") == "0\n" + + with subtest("root user has correct password"): + print(machine.succeed("getent passwd root")) + assert "${rootPassword}" in machine.succeed("getent shadow root"), "root user password is not correct" + + with subtest("normalo user is created"): + print(machine.succeed("getent passwd normalo")) + assert machine.succeed("stat -c '%U' /home/normalo") == "normalo\n" + assert "${normaloPassword}" in machine.succeed("getent shadow normalo"), "normalo user password is not correct" + + + machine.succeed("/run/current-system/specialisation/new-generation/bin/switch-to-configuration switch") + + + with subtest("new-normalo user is created after switching to new generation"): + print(machine.succeed("getent passwd new-normalo")) + print(machine.succeed("getent shadow new-normalo")) + assert machine.succeed("stat -c '%U' /home/new-normalo") == "new-normalo\n" + ''; +} diff --git a/nixos/tests/systemd-sysusers-mutable.nix b/nixos/tests/systemd-sysusers-mutable.nix new file mode 100644 index 0000000000000..e69cfe23a59a1 --- /dev/null +++ b/nixos/tests/systemd-sysusers-mutable.nix @@ -0,0 +1,71 @@ +{ lib, ... }: + +let + rootPassword = "$y$j9T$p6OI0WN7.rSfZBOijjRdR.$xUOA2MTcB48ac.9Oc5fz8cxwLv1mMqabnn333iOzSA6"; + normaloPassword = "hello"; + newNormaloPassword = "$y$j9T$p6OI0WN7.rSfZBOijjRdR.$xUOA2MTcB48ac.9Oc5fz8cxwLv1mMqabnn333iOzSA6"; +in + +{ + + name = "activation-sysusers-mutable"; + + meta.maintainers = with lib.maintainers; [ nikstur ]; + + nodes.machine = { pkgs, ... }: { + systemd.sysusers.enable = true; + users.mutableUsers = true; + + # Prerequisites + system.etc.overlay.enable = true; + boot.initrd.systemd.enable = true; + boot.kernelPackages = pkgs.linuxPackages_latest; + + # Override the empty root password set by the test instrumentation + users.users.root.hashedPasswordFile = lib.mkForce null; + users.users.root.initialHashedPassword = rootPassword; + users.users.normalo = { + isNormalUser = true; + initialPassword = normaloPassword; + }; + + specialisation.new-generation.configuration = { + users.users.new-normalo = { + isNormalUser = true; + initialHashedPassword = newNormaloPassword; + }; + }; + }; + + testScript = '' + machine.wait_for_unit("systemd-sysusers.service") + + with subtest("systemd-sysusers.service contains the credentials"): + sysusers_service = machine.succeed("systemctl cat systemd-sysusers.service") + print(sysusers_service) + assert "SetCredential=passwd.plaintext-password.normalo:${normaloPassword}" in sysusers_service + + with subtest("Correct mode on the password files"): + assert machine.succeed("stat -c '%a' /etc/passwd") == "644\n" + assert machine.succeed("stat -c '%a' /etc/group") == "644\n" + assert machine.succeed("stat -c '%a' /etc/shadow") == "0\n" + assert machine.succeed("stat -c '%a' /etc/gshadow") == "0\n" + + with subtest("root user has correct password"): + print(machine.succeed("getent passwd root")) + assert "${rootPassword}" in machine.succeed("getent shadow root"), "root user password is not correct" + + with subtest("normalo user is created"): + print(machine.succeed("getent passwd normalo")) + assert machine.succeed("stat -c '%U' /home/normalo") == "normalo\n" + + + machine.succeed("/run/current-system/specialisation/new-generation/bin/switch-to-configuration switch") + + + with subtest("new-normalo user is created after switching to new generation"): + print(machine.succeed("getent passwd new-normalo")) + assert machine.succeed("stat -c '%U' /home/new-normalo") == "new-normalo\n" + assert "${newNormaloPassword}" in machine.succeed("getent shadow new-normalo"), "new-normalo user password is not correct" + ''; +} diff --git a/nixos/tests/tayga.nix b/nixos/tests/tayga.nix index 44974f6efea83..4aade67d74d0d 100644 --- a/nixos/tests/tayga.nix +++ b/nixos/tests/tayga.nix @@ -206,6 +206,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: testScript = '' # start client and server for machine in client, server: + machine.systemctl("start network-online.target") machine.wait_for_unit("network-online.target") machine.log(machine.execute("ip addr")[1]) machine.log(machine.execute("ip route")[1]) @@ -214,6 +215,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: # test systemd-networkd and nixos-scripts based router for router in router_systemd, router_nixos: router.start() + router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") router.wait_for_unit("tayga.service") router.log(machine.execute("ip addr")[1]) diff --git a/nixos/tests/terminal-emulators.nix b/nixos/tests/terminal-emulators.nix index efaac03e19837..3c1188ca88c99 100644 --- a/nixos/tests/terminal-emulators.nix +++ b/nixos/tests/terminal-emulators.nix @@ -61,6 +61,8 @@ let tests = { konsole.pkg = p: p.plasma5Packages.konsole; + lomiri-terminal-app.pkg = p: p.lomiri.lomiri-terminal-app; + lxterminal.pkg = p: p.lxterminal; mate-terminal.pkg = p: p.mate.mate-terminal; diff --git a/nixos/tests/trafficserver.nix b/nixos/tests/trafficserver.nix index e4557c6c50e54..94d0e4dd926e9 100644 --- a/nixos/tests/trafficserver.nix +++ b/nixos/tests/trafficserver.nix @@ -104,6 +104,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { ats.wait_for_open_port(80) httpbin.wait_for_unit("httpbin") httpbin.wait_for_open_port(80) + client.systemctl("start network-online.target") client.wait_for_unit("network-online.target") with subtest("Traffic Server is running"): diff --git a/nixos/tests/ulogd/ulogd.py b/nixos/tests/ulogd/ulogd.py index d20daa4d733a2..76a8d0c6e24a3 100644 --- a/nixos/tests/ulogd/ulogd.py +++ b/nixos/tests/ulogd/ulogd.py @@ -1,5 +1,6 @@ start_all() machine.wait_for_unit("ulogd.service") +machine.systemctl("start network-online.target") machine.wait_for_unit("network-online.target") with subtest("Ulogd is running"): diff --git a/nixos/tests/upnp.nix b/nixos/tests/upnp.nix index 5e135267403bd..93bc08f752ce3 100644 --- a/nixos/tests/upnp.nix +++ b/nixos/tests/upnp.nix @@ -81,11 +81,13 @@ in start_all() # Wait for network and miniupnpd. + router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") # $router.wait_for_unit("nat") router.wait_for_unit("${if useNftables then "nftables" else "firewall"}.service") router.wait_for_unit("miniupnpd") + client1.systemctl("start network-online.target") client1.wait_for_unit("network-online.target") client1.succeed("upnpc -a ${internalClient1Address} 9000 9000 TCP") diff --git a/nixos/tests/uptermd.nix b/nixos/tests/uptermd.nix index 429e3c9dd5ff3..469aa5047c27c 100644 --- a/nixos/tests/uptermd.nix +++ b/nixos/tests/uptermd.nix @@ -28,6 +28,7 @@ in start_all() server.wait_for_unit("uptermd.service") + server.systemctl("start network-online.target") server.wait_for_unit("network-online.target") # wait for upterm port to be reachable diff --git a/nixos/tests/watchdogd.nix b/nixos/tests/watchdogd.nix new file mode 100644 index 0000000000000..663e97cbae104 --- /dev/null +++ b/nixos/tests/watchdogd.nix @@ -0,0 +1,22 @@ +import ./make-test-python.nix ({ lib, ... }: { + name = "watchdogd"; + meta.maintainers = with lib.maintainers; [ vifino ]; + + nodes.machine = { pkgs, ... }: { + virtualisation.qemu.options = [ + "-device i6300esb" # virtual watchdog timer + ]; + boot.kernelModules = [ "i6300esb" ]; + services.watchdogd.enable = true; + services.watchdogd.settings = { + supervisor.enabled = true; + }; + }; + + testScript = '' + machine.wait_for_unit("watchdogd.service") + + assert "i6300ESB" in machine.succeed("watchdogctl status") + machine.succeed("watchdogctl test") + ''; +}) diff --git a/nixos/tests/web-apps/netbox-upgrade.nix b/nixos/tests/web-apps/netbox-upgrade.nix index b5403eb678bcb..4c554e7ae613b 100644 --- a/nixos/tests/web-apps/netbox-upgrade.nix +++ b/nixos/tests/web-apps/netbox-upgrade.nix @@ -1,6 +1,6 @@ import ../make-test-python.nix ({ lib, pkgs, ... }: let - oldNetbox = pkgs.netbox_3_5; - newNetbox = pkgs.netbox_3_6; + oldNetbox = pkgs.netbox_3_6; + newNetbox = pkgs.netbox_3_7; in { name = "netbox-upgrade"; diff --git a/nixos/tests/web-servers/stargazer.nix b/nixos/tests/web-servers/stargazer.nix index 6365d6a4fff10..f56d1b8c94545 100644 --- a/nixos/tests/web-servers/stargazer.nix +++ b/nixos/tests/web-servers/stargazer.nix @@ -1,4 +1,41 @@ { pkgs, lib, ... }: +let + test_script = pkgs.stdenv.mkDerivation rec { + pname = "stargazer-test-script"; + inherit (pkgs.stargazer) version src; + buildInputs = with pkgs; [ (python3.withPackages (ps: with ps; [ cryptography ])) ]; + dontBuild = true; + doCheck = false; + installPhase = '' + mkdir -p $out/bin + cp scripts/gemini-diagnostics $out/bin/test + ''; + }; + test_env = pkgs.stdenv.mkDerivation rec { + pname = "stargazer-test-env"; + inherit (pkgs.stargazer) version src; + buildPhase = '' + cc test_data/cgi-bin/loop.c -o test_data/cgi-bin/loop + ''; + doCheck = false; + installPhase = '' + mkdir -p $out + cp -r * $out/ + ''; + }; + scgi_server = pkgs.stdenv.mkDerivation rec { + pname = "stargazer-test-scgi-server"; + inherit (pkgs.stargazer) version src; + buildInputs = with pkgs; [ python3 ]; + dontConfigure = true; + dontBuild = true; + doCheck = false; + installPhase = '' + mkdir -p $out/bin + cp scripts/scgi-server $out/bin/scgi-server + ''; + }; +in { name = "stargazer"; meta = with lib.maintainers; { maintainers = [ gaykitty ]; }; @@ -7,25 +44,84 @@ geminiserver = { pkgs, ... }: { services.stargazer = { enable = true; + connectionLogging = false; + requestTimeout = 1; routes = [ { route = "localhost"; - root = toString (pkgs.writeTextDir "index.gmi" '' - # Hello NixOS! - ''); + root = "${test_env}/test_data/test_site"; + } + { + route = "localhost=/en.gmi"; + root = "${test_env}/test_data/test_site"; + lang = "en"; + charset = "ascii"; + } + { + route = "localhost~/(.*).gemini"; + root = "${test_env}/test_data/test_site"; + rewrite = "\\1.gmi"; + lang = "en"; + charset = "ascii"; + } + { + route = "localhost=/plain.txt"; + root = "${test_env}/test_data/test_site"; + lang = "en"; + charset = "ascii"; + cert-path = "/var/lib/gemini/certs/localhost.crt"; + key-path = "/var/lib/gemini/certs/localhost.key"; + } + { + route = "localhost:/cgi-bin"; + root = "${test_env}/test_data"; + cgi = true; + cgi-timeout = 5; + } + { + route = "localhost:/scgi"; + scgi = true; + scgi-address = "127.0.0.1:1099"; + } + { + route = "localhost=/root"; + redirect = ".."; + permanent = true; + } + { + route = "localhost=/priv.gmi"; + root = "${test_env}/test_data/test_site"; + client-cert = "${test_env}/test_data/client_cert/good.crt"; + } + { + route = "example.com~(.*)"; + redirect = "gemini://localhost"; + rewrite = "\\1"; + } + { + route = "localhost:/no-exist"; + root = "./does_not_exist"; } ]; }; + systemd.services.scgi_server = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${scgi_server}/bin/scgi-server"; + }; + }; }; }; testScript = { nodes, ... }: '' + geminiserver.wait_for_unit("scgi_server") + geminiserver.wait_for_open_port(1099) geminiserver.wait_for_unit("stargazer") geminiserver.wait_for_open_port(1965) - with subtest("check is serving over gemini"): - response = geminiserver.succeed("${pkgs.gemget}/bin/gemget --header -o - gemini://localhost:1965") + with subtest("stargazer test suite"): + response = geminiserver.succeed("sh -c 'cd ${test_env}; ${test_script}/bin/test'") print(response) - assert "Hello NixOS!" in response ''; } diff --git a/nixos/tests/web-servers/ttyd.nix b/nixos/tests/web-servers/ttyd.nix new file mode 100644 index 0000000000000..d161673684b31 --- /dev/null +++ b/nixos/tests/web-servers/ttyd.nix @@ -0,0 +1,19 @@ +import ../make-test-python.nix ({ lib, pkgs, ... }: { + name = "ttyd"; + meta.maintainers = with lib.maintainers; [ stunkymonkey ]; + + nodes.machine = { pkgs, ... }: { + services.ttyd = { + enable = true; + username = "foo"; + passwordFile = pkgs.writeText "password" "bar"; + }; + }; + + testScript = '' + machine.wait_for_unit("ttyd.service") + machine.wait_for_open_port(7681) + response = machine.succeed("curl -vvv -u foo:bar -s -H 'Host: ttyd' http://127.0.0.1:7681/") + assert '<title>ttyd - Terminal</title>' in response, "Page didn't load successfully" + ''; +}) diff --git a/nixos/tests/zrepl.nix b/nixos/tests/zrepl.nix index b16c7eddc7aec..bdf11122c73f6 100644 --- a/nixos/tests/zrepl.nix +++ b/nixos/tests/zrepl.nix @@ -42,6 +42,7 @@ import ./make-test-python.nix ( start_all() with subtest("Wait for zrepl and network ready"): + host.systemctl("start network-online.target") host.wait_for_unit("network-online.target") host.wait_for_unit("zrepl.service") |