about summary refs log tree commit diff
path: root/nixos/tests
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/tests')
-rw-r--r--nixos/tests/acme.nix41
-rw-r--r--nixos/tests/all-tests.nix5
-rw-r--r--nixos/tests/borgbackup.nix26
-rw-r--r--nixos/tests/buildbot.nix2
-rw-r--r--nixos/tests/cgit.nix8
-rw-r--r--nixos/tests/cinnamon-wayland.nix2
-rw-r--r--nixos/tests/cinnamon.nix2
-rw-r--r--nixos/tests/curl-impersonate.nix2
-rw-r--r--nixos/tests/eintopf.nix21
-rw-r--r--nixos/tests/freshrss-extensions.nix19
-rw-r--r--nixos/tests/frp.nix2
-rw-r--r--nixos/tests/gitolite-fcgiwrap.nix11
-rw-r--r--nixos/tests/grafana/basic.nix20
-rw-r--r--nixos/tests/grafana/provision/default.nix18
-rw-r--r--nixos/tests/graylog.nix15
-rw-r--r--nixos/tests/kafka.nix9
-rw-r--r--nixos/tests/kernel-generic.nix3
-rw-r--r--nixos/tests/libvirtd.nix5
-rw-r--r--nixos/tests/limesurvey.nix6
-rw-r--r--nixos/tests/lomiri.nix35
-rw-r--r--nixos/tests/mosquitto.nix2
-rw-r--r--nixos/tests/networking/networkmanager.nix2
-rw-r--r--nixos/tests/nextcloud/default.nix2
-rw-r--r--nixos/tests/nix-required-mounts/default.nix58
-rw-r--r--nixos/tests/nix-required-mounts/ensure-path-not-present.nix13
-rw-r--r--nixos/tests/nix-required-mounts/test-require-feature.nix26
-rw-r--r--nixos/tests/nix-required-mounts/test-structured-attrs-empty.nix8
-rw-r--r--nixos/tests/nix-required-mounts/test-structured-attrs.nix18
-rw-r--r--nixos/tests/pam/pam-u2f.nix16
-rw-r--r--nixos/tests/plotinus.nix2
-rw-r--r--nixos/tests/prometheus-exporters.nix5
-rw-r--r--nixos/tests/scion/freestanding-deployment/default.nix52
-rw-r--r--nixos/tests/shiori.nix135
-rw-r--r--nixos/tests/soju.nix2
-rw-r--r--nixos/tests/systemd-confinement/default.nix2
-rw-r--r--nixos/tests/teleport.nix1
-rw-r--r--nixos/tests/terminal-emulators.nix2
-rw-r--r--nixos/tests/web-apps/mastodon/default.nix6
-rw-r--r--nixos/tests/ydotool.nix2
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):