diff options
Diffstat (limited to 'nixos/tests')
39 files changed, 458 insertions, 148 deletions
diff --git a/nixos/tests/acme.nix b/nixos/tests/acme.nix index 379496583d25d..2cba04f9d3957 100644 --- a/nixos/tests/acme.nix +++ b/nixos/tests/acme.nix @@ -200,6 +200,14 @@ in { # Tests HTTP-01 verification using Lego's built-in web server http01lego.configuration = simpleConfig; + # account hash generation with default server from <= 23.11 + http01lego_legacyAccountHash.configuration = lib.mkMerge [ + simpleConfig + { + security.acme.defaults.server = lib.mkForce null; + } + ]; + renew.configuration = lib.mkMerge [ simpleConfig { @@ -424,7 +432,7 @@ in { backoff = BackoffTracker() - def switch_to(node, name): + def switch_to(node, name, allow_fail=False): # On first switch, this will create a symlink to the current system so that we can # quickly switch between derivations root_specs = "/tmp/specialisation" @@ -438,9 +446,14 @@ in { if rc > 0: switcher_path = f"/tmp/specialisation/{name}/bin/switch-to-configuration" - node.succeed( - f"{switcher_path} test" - ) + if not allow_fail: + node.succeed( + f"{switcher_path} test" + ) + else: + node.execute( + f"{switcher_path} test" + ) # Ensures the issuer of our cert matches the chain @@ -544,7 +557,7 @@ in { check_issuer(webserver, "http.example.test", "pebble") # Perform account hash test - with subtest("Assert that account hash didn't unexpected change"): + with subtest("Assert that account hash didn't unexpectedly change"): hash = webserver.succeed("ls /var/lib/acme/.lego/accounts/") print("Account hash: " + hash) assert hash.strip() == "d590213ed52603e9128d" @@ -727,5 +740,23 @@ in { webserver.wait_for_unit(f"acme-finished-{test_domain}.target") wait_for_server() check_connection_key_bits(client, test_domain, "384") + + # Perform http-01 w/ lego test again, but using the pre-24.05 account hashing + # (see https://github.com/NixOS/nixpkgs/pull/317257) + with subtest("Check account hashing compatibility with pre-24.05 settings"): + webserver.succeed("rm -rf /var/lib/acme/.lego/accounts/*") + switch_to(webserver, "http01lego_legacyAccountHash", allow_fail=True) + # unit is failed, but in a way that this throws no exception: + try: + webserver.wait_for_unit("acme-finished-http.example.test.target") + except Exception: + # The unit is allowed – or even expected – to fail due to not being able to + # reach the actual letsencrypt server. We only use it for serialising the + # test execution, such that the account check is done after the service run + # involving the account creation has been executed at least once. + pass + hash = webserver.succeed("ls /var/lib/acme/.lego/accounts/") + print("Account hash: " + hash) + assert hash.strip() == "1ccf607d9aa280e9af00" ''; } diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index ad9025a917c38..1f6826e13b5c1 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -280,6 +280,7 @@ in { ecryptfs = handleTest ./ecryptfs.nix {}; fscrypt = handleTest ./fscrypt.nix {}; fastnetmon-advanced = runTest ./fastnetmon-advanced.nix; + eintopf = handleTest ./eintopf.nix {}; ejabberd = handleTest ./xmpp/ejabberd.nix {}; elk = handleTestOn ["x86_64-linux"] ./elk.nix {}; emacs-daemon = handleTest ./emacs-daemon.nix {}; @@ -337,6 +338,7 @@ in { freenet = handleTest ./freenet.nix {}; freeswitch = handleTest ./freeswitch.nix {}; freetube = discoverTests (import ./freetube.nix); + freshrss-extensions = handleTest ./freshrss-extensions.nix {}; freshrss-sqlite = handleTest ./freshrss-sqlite.nix {}; freshrss-pgsql = handleTest ./freshrss-pgsql.nix {}; freshrss-http-auth = handleTest ./freshrss-http-auth.nix {}; @@ -534,7 +536,7 @@ in { mailman = handleTest ./mailman.nix {}; man = handleTest ./man.nix {}; mariadb-galera = handleTest ./mysql/mariadb-galera.nix {}; - mastodon = discoverTests (import ./web-apps/mastodon { inherit handleTestOn; }); + mastodon = pkgs.recurseIntoAttrs (handleTest ./web-apps/mastodon { inherit handleTestOn; }); pixelfed = discoverTests (import ./web-apps/pixelfed { inherit handleTestOn; }); mate = handleTest ./mate.nix {}; mate-wayland = handleTest ./mate-wayland.nix {}; @@ -651,6 +653,7 @@ in { nix-config = handleTest ./nix-config.nix {}; nix-ld = handleTest ./nix-ld.nix {}; nix-misc = handleTest ./nix/misc.nix {}; + nix-required-mounts = runTest ./nix-required-mounts; nix-serve = handleTest ./nix-serve.nix {}; nix-serve-ssh = handleTest ./nix-serve-ssh.nix {}; nixops = handleTest ./nixops/default.nix {}; diff --git a/nixos/tests/borgbackup.nix b/nixos/tests/borgbackup.nix index 4160e727f047b..af7c12009c363 100644 --- a/nixos/tests/borgbackup.nix +++ b/nixos/tests/borgbackup.nix @@ -7,6 +7,8 @@ let keepFile = "important_file"; keepFileData = "important_data"; localRepo = "/root/back:up"; + # a repository on a file system which is not mounted automatically + localRepoMount = "/noAutoMount"; archiveName = "my_archive"; remoteRepo = "borg@server:."; # No need to specify path privateKey = pkgs.writeText "id_ed25519" '' @@ -42,6 +44,12 @@ in { nodes = { client = { ... }: { + virtualisation.fileSystems.${localRepoMount} = { + device = "tmpfs"; + fsType = "tmpfs"; + options = [ "noauto" ]; + }; + services.borgbackup.jobs = { local = { @@ -65,6 +73,13 @@ in { startAt = [ ]; # Do not run automatically }; + localMount = { + paths = dataDir; + repo = localRepoMount; + encryption.mode = "none"; + startAt = [ ]; + }; + remote = { paths = dataDir; repo = remoteRepo; @@ -178,6 +193,17 @@ in { "cat /mnt/borg/${dataDir}/${keepFile}" ) + with subtest("localMount"): + # the file system for the repo should not be already mounted + client.fail("mount | grep ${localRepoMount}") + # ensure trying to write to the mountpoint before the fs is mounted fails + client.succeed("chattr +i ${localRepoMount}") + borg = "borg" + client.systemctl("start --wait borgbackup-job-localMount") + client.fail("systemctl is-failed borgbackup-job-localMount") + # Make sure exactly one archive has been created + assert int(client.succeed("{} list '${localRepoMount}' | wc -l".format(borg))) > 0 + with subtest("remote"): borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519' borg" server.wait_for_unit("sshd.service") diff --git a/nixos/tests/buildbot.nix b/nixos/tests/buildbot.nix index 149d73bba09c5..0f65ac21c83d6 100644 --- a/nixos/tests/buildbot.nix +++ b/nixos/tests/buildbot.nix @@ -14,7 +14,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { "steps.ShellCommand(command=['bash', 'fakerepo.sh'])" ]; changeSource = [ - "changes.GitPoller('git://gitrepo/fakerepo.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)" + "changes.GitPoller('git://gitrepo/fakerepo.git', workdir='gitpoller-workdir', branch='master', pollInterval=300)" ]; }; networking.firewall.allowedTCPPorts = [ 8010 8011 9989 ]; diff --git a/nixos/tests/cgit.nix b/nixos/tests/cgit.nix index 6aed06adefdff..3107e7b964a3d 100644 --- a/nixos/tests/cgit.nix +++ b/nixos/tests/cgit.nix @@ -23,7 +23,7 @@ in { nginx.location = "/(c)git/"; repos = { some-repo = { - path = "/srv/git/some-repo"; + path = "/tmp/git/some-repo"; desc = "some-repo description"; }; }; @@ -50,12 +50,12 @@ in { server.fail("curl -fsS http://localhost/robots.txt") - server.succeed("${pkgs.writeShellScript "setup-cgit-test-repo" '' + server.succeed("sudo -u cgit ${pkgs.writeShellScript "setup-cgit-test-repo" '' set -e - git init --bare -b master /srv/git/some-repo + git init --bare -b master /tmp/git/some-repo git init -b master reference cd reference - git remote add origin /srv/git/some-repo + git remote add origin /tmp/git/some-repo date > date.txt git add date.txt git -c user.name=test -c user.email=test@localhost commit -m 'add date' diff --git a/nixos/tests/cinnamon-wayland.nix b/nixos/tests/cinnamon-wayland.nix index 19529d820d9c1..cba0c9f60e8db 100644 --- a/nixos/tests/cinnamon-wayland.nix +++ b/nixos/tests/cinnamon-wayland.nix @@ -14,7 +14,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { }; # For the sessionPath subtest. - services.xserver.desktopManager.cinnamon.sessionPath = [ pkgs.gnome.gpaste ]; + services.xserver.desktopManager.cinnamon.sessionPath = [ pkgs.gpaste ]; }; enableOCR = true; diff --git a/nixos/tests/cinnamon.nix b/nixos/tests/cinnamon.nix index 694308152149b..57300c3e4b16b 100644 --- a/nixos/tests/cinnamon.nix +++ b/nixos/tests/cinnamon.nix @@ -13,7 +13,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { environment.cinnamon.excludePackages = [ pkgs.gnome-text-editor ]; # For the sessionPath subtest. - services.xserver.desktopManager.cinnamon.sessionPath = [ pkgs.gnome.gpaste ]; + services.xserver.desktopManager.cinnamon.sessionPath = [ pkgs.gpaste ]; }; enableOCR = true; diff --git a/nixos/tests/curl-impersonate.nix b/nixos/tests/curl-impersonate.nix index 33b10da1dfd0f..97143951d4b0e 100644 --- a/nixos/tests/curl-impersonate.nix +++ b/nixos/tests/curl-impersonate.nix @@ -113,7 +113,7 @@ in { name = "curl-impersonate"; meta = with lib.maintainers; { - maintainers = [ lilyinstarlight ]; + maintainers = [ ]; }; nodes = { diff --git a/nixos/tests/eintopf.nix b/nixos/tests/eintopf.nix new file mode 100644 index 0000000000000..a1c05d6513041 --- /dev/null +++ b/nixos/tests/eintopf.nix @@ -0,0 +1,21 @@ +import ./make-test-python.nix ({ pkgs, ...} : { + name = "eintopf"; + meta = with pkgs.lib.maintainers; { + maintainers = [ onny ]; + }; + + nodes = { + eintopf = { config, pkgs, ... }: { + services.eintopf = { + enable = true; + }; + }; + }; + + testScript = '' + eintopf.start + eintopf.wait_for_unit("eintopf.service") + eintopf.wait_for_open_port(3333) + eintopf.succeed("curl -sSfL http://eintopf:3333 | grep 'Es sind keine Veranstaltungen eingetragen'") + ''; +}) diff --git a/nixos/tests/freshrss-extensions.nix b/nixos/tests/freshrss-extensions.nix new file mode 100644 index 0000000000000..f3e893b3b5a87 --- /dev/null +++ b/nixos/tests/freshrss-extensions.nix @@ -0,0 +1,19 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "freshrss"; + + nodes.machine = { pkgs, ... }: { + services.freshrss = { + enable = true; + baseUrl = "http://localhost"; + authType = "none"; + extensions = [ pkgs.freshrss-extensions.youtube ]; + }; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + machine.wait_for_open_port(80) + response = machine.succeed("curl -vvv -s http://127.0.0.1:80/i/?c=extension") + assert '<span class="ext_name disabled">YouTube Video Feed</span>' in response, "Extension not present in extensions page." + ''; +}) diff --git a/nixos/tests/frp.nix b/nixos/tests/frp.nix index 1f57c031a53a5..717e8718721ce 100644 --- a/nixos/tests/frp.nix +++ b/nixos/tests/frp.nix @@ -1,6 +1,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "frp"; - meta.maintainers = with lib.maintainers; [ zaldnoay janik ]; + meta.maintainers = with lib.maintainers; [ zaldnoay ]; nodes = { frps = { networking = { diff --git a/nixos/tests/gitolite-fcgiwrap.nix b/nixos/tests/gitolite-fcgiwrap.nix index abf1db37003a6..6e8dae6f72d73 100644 --- a/nixos/tests/gitolite-fcgiwrap.nix +++ b/nixos/tests/gitolite-fcgiwrap.nix @@ -24,7 +24,12 @@ import ./make-test-python.nix ( { networking.firewall.allowedTCPPorts = [ 80 ]; - services.fcgiwrap.enable = true; + services.fcgiwrap.gitolite = { + process.user = "gitolite"; + process.group = "gitolite"; + socket = { inherit (config.services.nginx) user group; }; + }; + services.gitolite = { enable = true; adminPubkey = adminPublicKey; @@ -59,7 +64,7 @@ import ./make-test-python.nix ( fastcgi_param SCRIPT_FILENAME ${pkgs.gitolite}/bin/gitolite-shell; # use Unix domain socket or inet socket - fastcgi_pass unix:/run/fcgiwrap.sock; + fastcgi_pass unix:${config.services.fcgiwrap.gitolite.socket.address}; ''; }; @@ -82,7 +87,7 @@ import ./make-test-python.nix ( server.wait_for_unit("gitolite-init.service") server.wait_for_unit("nginx.service") - server.wait_for_file("/run/fcgiwrap.sock") + server.wait_for_file("/run/fcgiwrap-gitolite.sock") client.wait_for_unit("multi-user.target") client.succeed( diff --git a/nixos/tests/grafana/basic.nix b/nixos/tests/grafana/basic.nix index dd389bc8a3d1f..fae6bd4dbbcfb 100644 --- a/nixos/tests/grafana/basic.nix +++ b/nixos/tests/grafana/basic.nix @@ -10,7 +10,7 @@ let analytics.reporting_enabled = false; server = { - http_addr = "localhost"; + http_addr = "::1"; domain = "localhost"; }; @@ -47,7 +47,7 @@ let postgresql = { services.grafana.settings.database = { - host = "127.0.0.1:5432"; + host = "[::1]:5432"; user = "grafana"; }; services.postgresql = { @@ -91,9 +91,9 @@ in { with subtest("Declarative plugins installed"): declarativePlugins.wait_for_unit("grafana.service") - declarativePlugins.wait_for_open_port(3000) + declarativePlugins.wait_for_open_port(3000, addr="::1") declarativePlugins.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/plugins | grep grafana-clock-panel" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/plugins | grep grafana-clock-panel" ) declarativePlugins.shutdown() @@ -101,10 +101,10 @@ in { sqlite.wait_for_unit("grafana.service") sqlite.wait_for_open_port(3000) print(sqlite.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users -i" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/org/users -i" )) sqlite.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/org/users | grep admin\@localhost" ) sqlite.shutdown() @@ -112,10 +112,10 @@ in { socket.wait_for_unit("grafana.service") socket.wait_for_open_port(80) print(socket.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1/api/org/users -i" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]/api/org/users -i" )) socket.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1/api/org/users | grep admin\@localhost" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]/api/org/users | grep admin\@localhost" ) socket.shutdown() @@ -125,7 +125,7 @@ in { postgresql.wait_for_open_port(3000) postgresql.wait_for_open_port(5432) postgresql.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/org/users | grep admin\@localhost" ) postgresql.shutdown() @@ -135,7 +135,7 @@ in { mysql.wait_for_open_port(3000) mysql.wait_for_open_port(3306) mysql.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/org/users | grep admin\@localhost" ) mysql.shutdown() ''; diff --git a/nixos/tests/grafana/provision/default.nix b/nixos/tests/grafana/provision/default.nix index f9dd8b2961ac7..775fae9b71baa 100644 --- a/nixos/tests/grafana/provision/default.nix +++ b/nixos/tests/grafana/provision/default.nix @@ -11,7 +11,7 @@ let analytics.reporting_enabled = false; server = { - http_addr = "localhost"; + http_addr = "::1"; domain = "localhost"; }; @@ -177,41 +177,41 @@ in { for description, machine in [nodeNix, nodeYaml, nodeYamlDir]: with subtest(f"Should start provision node: {description}"): machine.wait_for_unit("grafana.service") - machine.wait_for_open_port(3000) + machine.wait_for_open_port(3000, addr="::1") with subtest(f"Successful datasource provision with {description}"): machine.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/datasources/uid/test_datasource | grep Test\ Datasource" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/datasources/uid/test_datasource | grep Test\ Datasource" ) with subtest(f"Successful dashboard provision with {description}"): machine.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/dashboards/uid/test_dashboard | grep Test\ Dashboard" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/dashboards/uid/test_dashboard | grep Test\ Dashboard" ) with subtest(f"Successful rule provision with {description}"): machine.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/alert-rules/test_rule | grep Test\ Rule" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/alert-rules/test_rule | grep Test\ Rule" ) with subtest(f"Successful contact point provision with {description}"): machine.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/contact-points | grep Test\ Contact\ Point" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/contact-points | grep Test\ Contact\ Point" ) with subtest(f"Successful policy provision with {description}"): machine.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/policies | grep Test\ Contact\ Point" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/policies | grep Test\ Contact\ Point" ) with subtest(f"Successful template provision with {description}"): machine.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/templates | grep Test\ Template" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/templates | grep Test\ Template" ) with subtest("Successful mute timings provision with {description}"): machine.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/v1/provisioning/mute-timings | grep Test\ Mute\ Timing" + "curl -sSfN -u testadmin:snakeoilpwd http://[::1]:3000/api/v1/provisioning/mute-timings | grep Test\ Mute\ Timing" ) ''; }) diff --git a/nixos/tests/graylog.nix b/nixos/tests/graylog.nix index 3f7cc3a914390..9d19dcf028eb5 100644 --- a/nixos/tests/graylog.nix +++ b/nixos/tests/graylog.nix @@ -4,7 +4,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { nodes.machine = { pkgs, ... }: { virtualisation.memorySize = 4096; - virtualisation.diskSize = 4096; + virtualisation.diskSize = 1024 * 6; services.mongodb.enable = true; services.elasticsearch.enable = true; @@ -65,9 +65,18 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { in '' machine.start() machine.wait_for_unit("graylog.service") + + machine.wait_until_succeeds( + "journalctl -o cat -u graylog.service | grep 'Started REST API at <127.0.0.1:9000>'" + ) + machine.wait_for_open_port(9000) machine.succeed("curl -sSfL http://127.0.0.1:9000/") + machine.wait_until_succeeds( + "journalctl -o cat -u graylog.service | grep 'Graylog server up and running'" + ) + session = machine.succeed( "curl -X POST " + "-sSfL http://127.0.0.1:9000/api/system/sessions " @@ -88,6 +97,10 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { ) machine.wait_until_succeeds( + "journalctl -o cat -u graylog.service | grep -E 'Input \[GELF UDP/Demo/[[:alnum:]]{24}\] is now RUNNING'" + ) + + machine.wait_until_succeeds( "test \"$(curl -sSfL 'http://127.0.0.1:9000/api/cluster/inputstates' " + f"-u {session}:session " + "-H 'Accept: application/json' " diff --git a/nixos/tests/kafka.nix b/nixos/tests/kafka.nix index f4f9827ab7b5f..8f843e1fc37da 100644 --- a/nixos/tests/kafka.nix +++ b/nixos/tests/kafka.nix @@ -103,13 +103,8 @@ let }) { inherit system; }); in with pkgs; { - kafka_2_8 = makeKafkaTest "kafka_2_8" { kafkaPackage = apacheKafka_2_8; }; - kafka_3_0 = makeKafkaTest "kafka_3_0" { kafkaPackage = apacheKafka_3_0; }; - kafka_3_1 = makeKafkaTest "kafka_3_1" { kafkaPackage = apacheKafka_3_1; }; - kafka_3_2 = makeKafkaTest "kafka_3_2" { kafkaPackage = apacheKafka_3_2; }; - kafka_3_3 = makeKafkaTest "kafka_3_3" { kafkaPackage = apacheKafka_3_3; }; - kafka_3_4 = makeKafkaTest "kafka_3_4" { kafkaPackage = apacheKafka_3_4; }; - kafka_3_5 = makeKafkaTest "kafka_3_5" { kafkaPackage = apacheKafka_3_5; }; + kafka_3_6 = makeKafkaTest "kafka_3_6" { kafkaPackage = apacheKafka_3_6; }; + kafka_3_7 = makeKafkaTest "kafka_3_7" { kafkaPackage = apacheKafka_3_7; }; kafka = makeKafkaTest "kafka" { kafkaPackage = apacheKafka; }; kafka_kraft = makeKafkaTest "kafka_kraft" { kafkaPackage = apacheKafka; mode = "kraft"; }; } diff --git a/nixos/tests/kernel-generic.nix b/nixos/tests/kernel-generic.nix index 6a8633808702f..e22c7d735a238 100644 --- a/nixos/tests/kernel-generic.nix +++ b/nixos/tests/kernel-generic.nix @@ -47,6 +47,9 @@ in mapAttrs (_: lP: testsForLinuxPackages lP) kernels // { passthru = { inherit testsForLinuxPackages; + # Useful for development testing of all Kernel configs without building full Kernel + configfiles = mapAttrs (_: lP: lP.kernel.configfile) kernels; + testsForKernel = kernel: testsForLinuxPackages (pkgs.linuxPackagesFor kernel); }; } diff --git a/nixos/tests/libvirtd.nix b/nixos/tests/libvirtd.nix index df80dcc21a2eb..27ffaac3e62d1 100644 --- a/nixos/tests/libvirtd.nix +++ b/nixos/tests/libvirtd.nix @@ -20,6 +20,11 @@ import ./make-test-python.nix ({ pkgs, ... }: { networking.hostId = "deadbeef"; # needed for zfs security.polkit.enable = true; environment.systemPackages = with pkgs; [ virt-manager ]; + + # This adds `resolve` to the `hosts` line of /etc/nsswitch.conf; NSS modules placed after it + # will not be consulted. Therefore this tests that the libvirtd NSS modules will be + # be placed early enough for name resolution to work. + services.resolved.enable = true; }; }; diff --git a/nixos/tests/limesurvey.nix b/nixos/tests/limesurvey.nix index 9a3193991f352..87e9fe1cdc149 100644 --- a/nixos/tests/limesurvey.nix +++ b/nixos/tests/limesurvey.nix @@ -1,6 +1,6 @@ -import ./make-test-python.nix ({ pkgs, ... }: { +import ./make-test-python.nix ({ lib, pkgs, ... }: { name = "limesurvey"; - meta.maintainers = [ pkgs.lib.maintainers.aanderse ]; + meta.maintainers = [ lib.maintainers.aanderse ]; nodes.machine = { ... }: { services.limesurvey = { @@ -9,6 +9,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { hostName = "example.local"; adminAddr = "root@example.local"; }; + encryptionKeyFile = pkgs.writeText "key" (lib.strings.replicate 32 "0"); + encryptionNonceFile = pkgs.writeText "nonce" (lib.strings.replicate 24 "0"); }; # limesurvey won't work without a dot in the hostname diff --git a/nixos/tests/lomiri.nix b/nixos/tests/lomiri.nix index e9134a202cd17..912f4564ef7b2 100644 --- a/nixos/tests/lomiri.nix +++ b/nixos/tests/lomiri.nix @@ -74,6 +74,24 @@ in { inherit (alacritty) meta; }) + + # Polkit requests eventually time out. + # Keep triggering them until we signal detection success + (writeShellApplication { + name = "lpa-check"; + text = '' + while [ ! -f /tmp/lpa-checked ]; do + pkexec echo a + done + ''; + }) + # Signal detection success + (writeShellApplication { + name = "lpa-signal"; + text = '' + touch /tmp/lpa-checked + ''; + }) ]; }; @@ -201,7 +219,15 @@ in { machine.wait_for_text(r"(/build/source|hub.cpp|handler.cpp|void|virtual|const)") # awaiting log messages from content-hub machine.send_key("ctrl-c") - machine.send_key("alt-f4") + # Doing this here, since we need an in-session shell & separately starting a terminal again wastes time + with subtest("polkit agent works"): + machine.send_chars("exec lpa-check\n") + machine.wait_for_text(r"(Elevated permissions|Login)") + machine.screenshot("polkit_agent") + machine.execute("lpa-signal") + + # polkit test will quit terminal when agent request times out after OCR success + machine.wait_until_fails("pgrep -u ${user} -f lomiri-terminal-app") # We want the ability to launch applications with subtest("starter menu works"): @@ -230,7 +256,7 @@ in { # morph-browser has a separate VM test, there isn't anything new we could test here - # Keep it running, we're using it to check content-hub communication from LSS + machine.send_key("alt-f4") # LSS provides DE settings with subtest("system settings open"): @@ -282,9 +308,8 @@ in { # Testing any more would require more applications & setup, the fact that it's already being attempted is a good sign machine.send_key("esc") - machine.send_key("alt-f4") # LSS - machine.sleep(2) # focus is slow to switch to second window, closing it *really* helps with OCR afterwards - machine.send_key("alt-f4") # Morph + machine.sleep(2) # sleep a tiny bit so morph can close & the focus can return to LSS + machine.send_key("alt-f4") # The ayatana indicators are an important part of the experience, and they hold the only graphical way of exiting the session. # There's a test app we could use that also displays their contents, but it's abit inconsistent. diff --git a/nixos/tests/mosquitto.nix b/nixos/tests/mosquitto.nix index c0980b23e78fd..eca29292721fd 100644 --- a/nixos/tests/mosquitto.nix +++ b/nixos/tests/mosquitto.nix @@ -55,7 +55,7 @@ let in { name = "mosquitto"; meta = with pkgs.lib; { - maintainers = with maintainers; [ pennae peterhoeg ]; + maintainers = with maintainers; [ peterhoeg ]; }; nodes = let diff --git a/nixos/tests/networking/networkmanager.nix b/nixos/tests/networking/networkmanager.nix index e654e37d7efb7..c8c44f9320d40 100644 --- a/nixos/tests/networking/networkmanager.nix +++ b/nixos/tests/networking/networkmanager.nix @@ -166,7 +166,7 @@ let in lib.mapAttrs (lib.const (attrs: makeTest (attrs // { name = "${attrs.name}-Networking-NetworkManager"; meta = { - maintainers = with lib.maintainers; [ janik ]; + maintainers = with lib.maintainers; [ ]; }; }))) testCases diff --git a/nixos/tests/nextcloud/default.nix b/nixos/tests/nextcloud/default.nix index 33aa227d2b032..9f8b06561b074 100644 --- a/nixos/tests/nextcloud/default.nix +++ b/nixos/tests/nextcloud/default.nix @@ -109,4 +109,4 @@ let ./with-objectstore.nix ]; in -listToAttrs (concatMap genTests [ 27 28 29 ]) +listToAttrs (concatMap genTests [ 28 29 ]) diff --git a/nixos/tests/nix-required-mounts/default.nix b/nixos/tests/nix-required-mounts/default.nix new file mode 100644 index 0000000000000..60f894ce0bcc6 --- /dev/null +++ b/nixos/tests/nix-required-mounts/default.nix @@ -0,0 +1,58 @@ +{ pkgs, ... }: + +let + inherit (pkgs) lib; +in + +{ + name = "nix-required-mounts"; + meta.maintainers = with lib.maintainers; [ SomeoneSerge ]; + nodes.machine = + { config, pkgs, ... }: + { + virtualisation.writableStore = true; + system.extraDependencies = [ (pkgs.runCommand "deps" { } "mkdir $out").inputDerivation ]; + nix.nixPath = [ "nixpkgs=${../../..}" ]; + nix.settings.substituters = lib.mkForce [ ]; + nix.settings.system-features = [ "supported-feature" ]; + nix.settings.experimental-features = [ "nix-command" ]; + programs.nix-required-mounts.enable = true; + programs.nix-required-mounts.allowedPatterns.supported-feature = { + onFeatures = [ "supported-feature" ]; + paths = [ + "/supported-feature-files" + { + host = "/usr/lib/imaginary-fhs-drivers"; + guest = "/run/opengl-driver/lib"; + } + ]; + unsafeFollowSymlinks = true; + }; + users.users.person.isNormalUser = true; + systemd.tmpfiles.rules = [ + "d /supported-feature-files 0755 person users -" + "f /usr/lib/libcuda.so 0444 root root - fakeContent" + "L /usr/lib/imaginary-fhs-drivers/libcuda.so 0444 root root - /usr/lib/libcuda.so" + ]; + }; + testScript = '' + import shlex + + def person_do(cmd, succeed=True): + cmd = shlex.quote(cmd) + cmd = f"su person -l -c {cmd} &>/dev/console" + + if succeed: + return machine.succeed(cmd) + else: + return machine.fail(cmd) + + start_all() + + person_do("nix-build ${./ensure-path-not-present.nix} --argstr feature supported-feature") + person_do("nix-build ${./test-require-feature.nix} --argstr feature supported-feature") + person_do("nix-build ${./test-require-feature.nix} --argstr feature unsupported-feature", succeed=False) + person_do("nix-build ${./test-structured-attrs.nix} --argstr feature supported-feature") + person_do("nix-build ${./test-structured-attrs-empty.nix}") + ''; +} diff --git a/nixos/tests/nix-required-mounts/ensure-path-not-present.nix b/nixos/tests/nix-required-mounts/ensure-path-not-present.nix new file mode 100644 index 0000000000000..270c268fcbd9e --- /dev/null +++ b/nixos/tests/nix-required-mounts/ensure-path-not-present.nix @@ -0,0 +1,13 @@ +{ + pkgs ? import <nixpkgs> { }, + feature, +}: + +pkgs.runCommandNoCC "${feature}-not-present" { } '' + if [[ -e /${feature}-files ]]; then + echo "No ${feature} in requiredSystemFeatures, but /${feature}-files was mounted anyway" + exit 1 + else + touch $out + fi +'' diff --git a/nixos/tests/nix-required-mounts/test-require-feature.nix b/nixos/tests/nix-required-mounts/test-require-feature.nix new file mode 100644 index 0000000000000..447fd49a300aa --- /dev/null +++ b/nixos/tests/nix-required-mounts/test-require-feature.nix @@ -0,0 +1,26 @@ +{ + pkgs ? import <nixpkgs> { }, + feature, +}: + +pkgs.runCommandNoCC "${feature}-present" { requiredSystemFeatures = [ feature ]; } '' + if [[ ! -e /${feature}-files ]]; then + echo "The host declares ${feature} support, but doesn't expose /${feature}-files" >&2 + exit 1 + fi + libcudaLocation=/run/opengl-driver/lib/libcuda.so + if [[ -e "$libcudaLocation" || -h "$libcudaLocation" ]] ; then + true # we're good + else + echo "The host declares ${feature} support, but it the hook fails to handle the hostPath != guestPath cases" >&2 + exit 1 + fi + if cat "$libcudaLocation" | xargs test fakeContent = ; then + true # we're good + else + echo "The host declares ${feature} support, but it seems to fail to follow symlinks" >&2 + echo "The content of /run/opengl-driver/lib/libcuda.so is: $(cat /run/opengl-driver/lib/libcuda.so)" >&2 + exit 1 + fi + touch $out +'' diff --git a/nixos/tests/nix-required-mounts/test-structured-attrs-empty.nix b/nixos/tests/nix-required-mounts/test-structured-attrs-empty.nix new file mode 100644 index 0000000000000..86f2753309368 --- /dev/null +++ b/nixos/tests/nix-required-mounts/test-structured-attrs-empty.nix @@ -0,0 +1,8 @@ +{ + pkgs ? import <nixpkgs> { }, +}: + +pkgs.runCommandNoCC "nix-required-mounts-structured-attrs-no-features" { __structuredAttrs = true; } + '' + touch $out + '' diff --git a/nixos/tests/nix-required-mounts/test-structured-attrs.nix b/nixos/tests/nix-required-mounts/test-structured-attrs.nix new file mode 100644 index 0000000000000..874910eee7bb3 --- /dev/null +++ b/nixos/tests/nix-required-mounts/test-structured-attrs.nix @@ -0,0 +1,18 @@ +{ + pkgs ? import <nixpkgs> { }, + feature, +}: + +pkgs.runCommandNoCC "${feature}-present-structured" + { + __structuredAttrs = true; + requiredSystemFeatures = [ feature ]; + } + '' + if [[ -e /${feature}-files ]]; then + touch $out + else + echo "The host declares ${feature} support, but doesn't expose /${feature}-files" >&2 + echo "Do we fail to parse __structuredAttrs=true derivations?" >&2 + fi + '' diff --git a/nixos/tests/pam/pam-u2f.nix b/nixos/tests/pam/pam-u2f.nix index 46e307a3f125a..caa56c30bbce9 100644 --- a/nixos/tests/pam/pam-u2f.nix +++ b/nixos/tests/pam/pam-u2f.nix @@ -7,12 +7,16 @@ import ../make-test-python.nix ({ ... }: { ... }: { security.pam.u2f = { - control = "required"; - cue = true; - debug = true; enable = true; - interactive = true; - origin = "nixos-test"; + control = "required"; + settings = { + cue = true; + debug = true; + interactive = true; + origin = "nixos-test"; + # Freeform option + userpresence = 1; + }; }; }; @@ -20,7 +24,7 @@ import ../make-test-python.nix ({ ... }: '' machine.wait_for_unit("multi-user.target") machine.succeed( - 'egrep "auth required .*/lib/security/pam_u2f.so.*cue.*debug.*interactive.*origin=nixos-test" /etc/pam.d/ -R' + 'egrep "auth required .*/lib/security/pam_u2f.so.*cue.*debug.*interactive.*origin=nixos-test.*userpresence=1" /etc/pam.d/ -R' ) ''; }) diff --git a/nixos/tests/plotinus.nix b/nixos/tests/plotinus.nix index b6ebab9b01989..5c52abf9c720d 100644 --- a/nixos/tests/plotinus.nix +++ b/nixos/tests/plotinus.nix @@ -9,7 +9,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { { imports = [ ./common/x11.nix ]; programs.plotinus.enable = true; - environment.systemPackages = [ pkgs.gnome.gnome-calculator pkgs.xdotool ]; + environment.systemPackages = [ pkgs.gnome-calculator pkgs.xdotool ]; }; testScript = '' diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix index 56569c4de2c85..d9a52fa89b1c9 100644 --- a/nixos/tests/prometheus-exporters.nix +++ b/nixos/tests/prometheus-exporters.nix @@ -314,10 +314,9 @@ let tokenPath = pkgs.writeText "token" "abc123"; }; - # noop: fastly's exporter can't start without first talking to fastly - # see: https://github.com/peterbourgon/fastly-exporter/issues/87 exporterTest = '' - succeed("true"); + wait_for_unit("prometheus-fastly-exporter.service") + wait_for_open_port(9118) ''; }; diff --git a/nixos/tests/scion/freestanding-deployment/default.nix b/nixos/tests/scion/freestanding-deployment/default.nix index 0c9686fbfbadf..e060f9c312709 100644 --- a/nixos/tests/scion/freestanding-deployment/default.nix +++ b/nixos/tests/scion/freestanding-deployment/default.nix @@ -156,17 +156,51 @@ in # List of AS instances machines = [scion01, scion02, scion03, scion04, scion05] + # Functions to avoid many for loops + def start(allow_reboot=False): + for i in machines: + i.start(allow_reboot=allow_reboot) + + def wait_for_unit(service_name): + for i in machines: + i.wait_for_unit(service_name) + + def succeed(command): + for i in machines: + i.succeed(command) + + def reboot(): + for i in machines: + i.reboot() + + def crash(): + for i in machines: + i.crash() + + # Start all machines, allowing reboot for later + start(allow_reboot=True) + # Wait for scion-control.service on all instances - for i in machines: - i.wait_for_unit("scion-control.service") + wait_for_unit("scion-control.service") # Execute pingAll command on all instances - for i in machines: - i.succeed("${pingAll} >&2") - - # Restart scion-dispatcher and ping again to test robustness - for i in machines: - i.succeed("systemctl restart scion-dispatcher >&2") - i.succeed("${pingAll} >&2") + succeed("${pingAll} >&2") + + # Restart all scion services and ping again to test robustness + succeed("systemctl restart scion-* >&2") + succeed("${pingAll} >&2") + + # Reboot machines, wait for service, and ping again + reboot() + wait_for_unit("scion-control.service") + succeed("${pingAll} >&2") + + # Crash, start, wait for service, and ping again + crash() + start() + wait_for_unit("scion-control.service") + succeed("pkill -9 scion-* >&2") + wait_for_unit("scion-control.service") + succeed("${pingAll} >&2") ''; }) diff --git a/nixos/tests/shiori.nix b/nixos/tests/shiori.nix index d0f68b903f8c3..ba9b42235df28 100644 --- a/nixos/tests/shiori.nix +++ b/nixos/tests/shiori.nix @@ -1,80 +1,81 @@ -import ./make-test-python.nix ({ pkgs, lib, ...}: +import ./make-test-python.nix ({ pkgs, lib, ... }: -{ - name = "shiori"; - meta.maintainers = with lib.maintainers; [ minijackson ]; + { + name = "shiori"; + meta.maintainers = with lib.maintainers; [ minijackson ]; - nodes.machine = - { ... }: - { services.shiori.enable = true; }; + nodes.machine = { ... }: { services.shiori.enable = true; }; - testScript = let - authJSON = pkgs.writeText "auth.json" (builtins.toJSON { - username = "shiori"; - password = "gopher"; - owner = true; - }); + testScript = let + authJSON = pkgs.writeText "auth.json" (builtins.toJSON { + username = "shiori"; + password = "gopher"; + owner = true; + }); - insertBookmark = { - url = "http://example.org"; - title = "Example Bookmark"; - }; + insertBookmark = { + url = "http://example.org"; + title = "Example Bookmark"; + }; - insertBookmarkJSON = pkgs.writeText "insertBookmark.json" (builtins.toJSON insertBookmark); - in '' - import json + insertBookmarkJSON = + pkgs.writeText "insertBookmark.json" (builtins.toJSON insertBookmark); + in '' + #import json - machine.wait_for_unit("shiori.service") - machine.wait_for_open_port(8080) - machine.succeed("curl --fail http://localhost:8080/") - machine.succeed("curl --fail --location http://localhost:8080/ | grep -i shiori") + machine.wait_for_unit("shiori.service") + machine.wait_for_open_port(8080) + machine.succeed("curl --fail http://localhost:8080/") + machine.succeed("curl --fail --location http://localhost:8080/ | grep -i shiori") - with subtest("login"): - auth_json = machine.succeed( - "curl --fail --location http://localhost:8080/api/login " - "-X POST -H 'Content-Type:application/json' -d @${authJSON}" - ) - auth_ret = json.loads(auth_json) - session_id = auth_ret["session"] + # The test code below no longer works because the API authentication has changed. - with subtest("bookmarks"): - with subtest("first use no bookmarks"): - bookmarks_json = machine.succeed( - ( - "curl --fail --location http://localhost:8080/api/bookmarks " - "-H 'X-Session-Id:{}'" - ).format(session_id) - ) + #with subtest("login"): + # auth_json = machine.succeed( + # "curl --fail --location http://localhost:8080/api/login " + # "-X POST -H 'Content-Type:application/json' -d @${authJSON}" + # ) + # auth_ret = json.loads(auth_json) + # session_id = auth_ret["session"] - if json.loads(bookmarks_json)["bookmarks"] != []: - raise Exception("Shiori have a bookmark on first use") + #with subtest("bookmarks"): + # with subtest("first use no bookmarks"): + # bookmarks_json = machine.succeed( + # ( + # "curl --fail --location http://localhost:8080/api/bookmarks " + # "-H 'X-Session-Id:{}'" + # ).format(session_id) + # ) - with subtest("insert bookmark"): - machine.succeed( - ( - "curl --fail --location http://localhost:8080/api/bookmarks " - "-X POST -H 'X-Session-Id:{}' " - "-H 'Content-Type:application/json' -d @${insertBookmarkJSON}" - ).format(session_id) - ) + # if json.loads(bookmarks_json)["bookmarks"] != []: + # raise Exception("Shiori have a bookmark on first use") - with subtest("get inserted bookmark"): - bookmarks_json = machine.succeed( - ( - "curl --fail --location http://localhost:8080/api/bookmarks " - "-H 'X-Session-Id:{}'" - ).format(session_id) - ) + # with subtest("insert bookmark"): + # machine.succeed( + # ( + # "curl --fail --location http://localhost:8080/api/bookmarks " + # "-X POST -H 'X-Session-Id:{}' " + # "-H 'Content-Type:application/json' -d @${insertBookmarkJSON}" + # ).format(session_id) + # ) - bookmarks = json.loads(bookmarks_json)["bookmarks"] - if len(bookmarks) != 1: - raise Exception("Shiori didn't save the bookmark") + # with subtest("get inserted bookmark"): + # bookmarks_json = machine.succeed( + # ( + # "curl --fail --location http://localhost:8080/api/bookmarks " + # "-H 'X-Session-Id:{}'" + # ).format(session_id) + # ) - bookmark = bookmarks[0] - if ( - bookmark["url"] != "${insertBookmark.url}" - or bookmark["title"] != "${insertBookmark.title}" - ): - raise Exception("Inserted bookmark doesn't have same URL or title") - ''; -}) + # bookmarks = json.loads(bookmarks_json)["bookmarks"] + # if len(bookmarks) != 1: + # raise Exception("Shiori didn't save the bookmark") + + # bookmark = bookmarks[0] + # if ( + # bookmark["url"] != "${insertBookmark.url}" + # or bookmark["title"] != "${insertBookmark.title}" + # ): + # raise Exception("Inserted bookmark doesn't have same URL or title") + ''; + }) diff --git a/nixos/tests/soju.nix b/nixos/tests/soju.nix index 23da36f7b3aba..32d1daf43d1a3 100644 --- a/nixos/tests/soju.nix +++ b/nixos/tests/soju.nix @@ -8,7 +8,7 @@ let in { name = "soju"; - meta.maintainers = with lib.maintainers; [ Benjamin-L ]; + meta.maintainers = with lib.maintainers; [ ]; nodes.machine = { ... }: { services.soju = { diff --git a/nixos/tests/systemd-confinement/default.nix b/nixos/tests/systemd-confinement/default.nix index 15d442d476b08..4ca37b3b9126e 100644 --- a/nixos/tests/systemd-confinement/default.nix +++ b/nixos/tests/systemd-confinement/default.nix @@ -153,7 +153,7 @@ import ../make-test-python.nix { }) ''; } - ]) (lib.cartesianProductOfSets { + ]) (lib.cartesianProduct { user = [ "root" "dynamic-user" "static-user" ]; privateTmp = [ true false ]; }); diff --git a/nixos/tests/teleport.nix b/nixos/tests/teleport.nix index 3621cce0599e1..0d0b9a713065a 100644 --- a/nixos/tests/teleport.nix +++ b/nixos/tests/teleport.nix @@ -10,6 +10,7 @@ let packages = with pkgs; { "default" = teleport; "14" = teleport_14; + "15" = teleport_15; }; minimal = package: { diff --git a/nixos/tests/terminal-emulators.nix b/nixos/tests/terminal-emulators.nix index 3c1188ca88c99..3cf99fe7fc2f3 100644 --- a/nixos/tests/terminal-emulators.nix +++ b/nixos/tests/terminal-emulators.nix @@ -42,7 +42,7 @@ let tests = { germinal.pkg = p: p.germinal; - gnome-terminal.pkg = p: p.gnome.gnome-terminal; + gnome-terminal.pkg = p: p.gnome-terminal; guake.pkg = p: p.guake; guake.cmd = "SHELL=$command guake --show"; diff --git a/nixos/tests/web-apps/mastodon/default.nix b/nixos/tests/web-apps/mastodon/default.nix index 178590d13b63c..7f925b9ad4ed2 100644 --- a/nixos/tests/web-apps/mastodon/default.nix +++ b/nixos/tests/web-apps/mastodon/default.nix @@ -1,9 +1,9 @@ -{ system ? builtins.currentSystem, handleTestOn }: +{ system ? builtins.currentSystem, pkgs, handleTestOn, ... }: let supportedSystems = [ "x86_64-linux" "i686-linux" "aarch64-linux" ]; in { - standard = handleTestOn supportedSystems ./standard.nix { inherit system; }; - remote-databases = handleTestOn supportedSystems ./remote-databases.nix { inherit system; }; + standard = handleTestOn supportedSystems ./standard.nix { inherit system pkgs; }; + remote-databases = handleTestOn supportedSystems ./remote-databases.nix { inherit system pkgs; }; } diff --git a/nixos/tests/ydotool.nix b/nixos/tests/ydotool.nix index 45e3d27adeb49..7a739392aa565 100644 --- a/nixos/tests/ydotool.nix +++ b/nixos/tests/ydotool.nix @@ -9,7 +9,7 @@ let textInput = "This works."; inputBoxText = "Enter input"; inputBox = pkgs.writeShellScript "zenity-input" '' - ${lib.getExe pkgs.gnome.zenity} --entry --text '${inputBoxText}:' > /tmp/output & + ${lib.getExe pkgs.zenity} --entry --text '${inputBoxText}:' > /tmp/output & ''; asUser = '' def as_user(cmd: str): |