about summary refs log tree commit diff
path: root/nixpkgs/nixos/tests
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/tests')
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix9
-rw-r--r--nixpkgs/nixos/tests/anki-sync-server.nix71
-rw-r--r--nixpkgs/nixos/tests/centrifugo.nix80
-rw-r--r--nixpkgs/nixos/tests/containers-ip.nix5
-rw-r--r--nixpkgs/nixos/tests/convos.nix1
-rw-r--r--nixpkgs/nixos/tests/deepin.nix6
-rw-r--r--nixpkgs/nixos/tests/dublin-traceroute.nix63
-rw-r--r--nixpkgs/nixos/tests/eris-server.nix2
-rw-r--r--nixpkgs/nixos/tests/geoserver.nix24
-rw-r--r--nixpkgs/nixos/tests/gnome-extensions.nix151
-rw-r--r--nixpkgs/nixos/tests/gnome-xorg.nix16
-rw-r--r--nixpkgs/nixos/tests/gnome.nix14
-rw-r--r--nixpkgs/nixos/tests/gvisor.nix36
-rw-r--r--nixpkgs/nixos/tests/incus/container.nix28
-rw-r--r--nixpkgs/nixos/tests/jitsi-meet.nix26
-rw-r--r--nixpkgs/nixos/tests/kafka.nix85
-rw-r--r--nixpkgs/nixos/tests/lanraragi.nix8
-rw-r--r--nixpkgs/nixos/tests/libvirtd.nix2
-rw-r--r--nixpkgs/nixos/tests/lxd/ui.nix33
-rw-r--r--nixpkgs/nixos/tests/matrix/synapse.nix44
-rw-r--r--nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix12
-rw-r--r--nixpkgs/nixos/tests/nixops/default.nix6
-rw-r--r--nixpkgs/nixos/tests/seatd.nix51
-rw-r--r--nixpkgs/nixos/tests/sonic-server.nix22
-rw-r--r--nixpkgs/nixos/tests/sudo-rs.nix6
-rw-r--r--nixpkgs/nixos/tests/systemd-initrd-luks-unl0kr.nix75
-rw-r--r--nixpkgs/nixos/tests/systemd-timesyncd.nix15
-rw-r--r--nixpkgs/nixos/tests/telegraf.nix1
-rw-r--r--nixpkgs/nixos/tests/terminal-emulators.nix2
-rw-r--r--nixpkgs/nixos/tests/tomcat.nix1
-rw-r--r--nixpkgs/nixos/tests/web-servers/stargazer.nix2
-rw-r--r--nixpkgs/nixos/tests/xscreensaver.nix64
-rw-r--r--nixpkgs/nixos/tests/zfs.nix10
33 files changed, 837 insertions, 134 deletions
diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index 367e3da29336..1ed0f760c9a2 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/nixos/tests/all-tests.nix
@@ -120,6 +120,7 @@ in {
   amazon-ssm-agent = handleTest ./amazon-ssm-agent.nix {};
   amd-sev = runTest ./amd-sev.nix;
   anbox = runTest ./anbox.nix;
+  anki-sync-server = handleTest ./anki-sync-server.nix {};
   anuko-time-tracker = handleTest ./anuko-time-tracker.nix {};
   apcupsd = handleTest ./apcupsd.nix {};
   apfs = runTest ./apfs.nix;
@@ -174,6 +175,7 @@ in {
   cassandra_3_0 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_0; };
   cassandra_3_11 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_3_11; };
   cassandra_4 = handleTest ./cassandra.nix { testPackage = pkgs.cassandra_4; };
+  centrifugo = runTest ./centrifugo.nix;
   ceph-multi-node = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-multi-node.nix {};
   ceph-single-node = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-single-node.nix {};
   ceph-single-node-bluestore = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./ceph-single-node-bluestore.nix {};
@@ -252,6 +254,7 @@ in {
   domination = handleTest ./domination.nix {};
   dovecot = handleTest ./dovecot.nix {};
   drbd = handleTest ./drbd.nix {};
+  dublin-traceroute = handleTest ./dublin-traceroute.nix {};
   earlyoom = handleTestOn ["x86_64-linux"] ./earlyoom.nix {};
   early-mount-options = handleTest ./early-mount-options.nix {};
   ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
@@ -320,6 +323,7 @@ in {
   mimir = handleTest ./mimir.nix {};
   garage = handleTest ./garage {};
   gemstash = handleTest ./gemstash.nix {};
+  geoserver = runTest ./geoserver.nix;
   gerrit = handleTest ./gerrit.nix {};
   geth = handleTest ./geth.nix {};
   ghostunnel = handleTest ./ghostunnel.nix {};
@@ -331,6 +335,7 @@ in {
   gitolite-fcgiwrap = handleTest ./gitolite-fcgiwrap.nix {};
   glusterfs = handleTest ./glusterfs.nix {};
   gnome = handleTest ./gnome.nix {};
+  gnome-extensions = handleTest ./gnome-extensions.nix {};
   gnome-flashback = handleTest ./gnome-flashback.nix {};
   gnome-xorg = handleTest ./gnome-xorg.nix {};
   gnupg = handleTest ./gnupg.nix {};
@@ -740,6 +745,7 @@ in {
   sddm = handleTest ./sddm.nix {};
   seafile = handleTest ./seafile.nix {};
   searx = handleTest ./searx.nix {};
+  seatd = handleTest ./seatd.nix {};
   service-runner = handleTest ./service-runner.nix {};
   sftpgo = runTest ./sftpgo.nix;
   sfxr-qt = handleTest ./sfxr-qt.nix {};
@@ -762,6 +768,7 @@ in {
   sogo = handleTest ./sogo.nix {};
   solanum = handleTest ./solanum.nix {};
   sonarr = handleTest ./sonarr.nix {};
+  sonic-server = handleTest ./sonic-server.nix {};
   sourcehut = handleTest ./sourcehut.nix {};
   spacecookie = handleTest ./spacecookie.nix {};
   spark = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./spark {};
@@ -808,6 +815,7 @@ in {
   systemd-initrd-luks-empty-passphrase = handleTest ./initrd-luks-empty-passphrase.nix { systemdStage1 = true; };
   systemd-initrd-luks-password = handleTest ./systemd-initrd-luks-password.nix {};
   systemd-initrd-luks-tpm2 = handleTest ./systemd-initrd-luks-tpm2.nix {};
+  systemd-initrd-luks-unl0kr = handleTest ./systemd-initrd-luks-unl0kr.nix {};
   systemd-initrd-modprobe = handleTest ./systemd-initrd-modprobe.nix {};
   systemd-initrd-shutdown = handleTest ./systemd-shutdown.nix { systemdStage1 = true; };
   systemd-initrd-simple = handleTest ./systemd-initrd-simple.nix {};
@@ -924,6 +932,7 @@ in {
   xmonad-xdg-autostart = handleTest ./xmonad-xdg-autostart.nix {};
   xpadneo = handleTest ./xpadneo.nix {};
   xrdp = handleTest ./xrdp.nix {};
+  xscreensaver = handleTest ./xscreensaver.nix {};
   xss-lock = handleTest ./xss-lock.nix {};
   xterm = handleTest ./xterm.nix {};
   xxh = handleTest ./xxh.nix {};
diff --git a/nixpkgs/nixos/tests/anki-sync-server.nix b/nixpkgs/nixos/tests/anki-sync-server.nix
new file mode 100644
index 000000000000..7d08cc9cb878
--- /dev/null
+++ b/nixpkgs/nixos/tests/anki-sync-server.nix
@@ -0,0 +1,71 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+  let
+    ankiSyncTest = pkgs.writeScript "anki-sync-test.py" ''
+      #!${pkgs.python3}/bin/python
+
+      import sys
+
+      # get site paths from anki itself
+      from runpy import run_path
+      run_path("${pkgs.anki}/bin/.anki-wrapped")
+      import anki
+
+      col = anki.collection.Collection('test_collection')
+      endpoint = 'http://localhost:27701'
+
+      # Sanity check: verify bad login fails
+      try:
+         col.sync_login('baduser', 'badpass', endpoint)
+         print("bad user login worked?!")
+         sys.exit(1)
+      except anki.errors.SyncError:
+          pass
+
+      # test logging in to users
+      col.sync_login('user', 'password', endpoint)
+      col.sync_login('passfileuser', 'passfilepassword', endpoint)
+
+      # Test actual sync. login apparently doesn't remember the endpoint...
+      login = col.sync_login('user', 'password', endpoint)
+      login.endpoint = endpoint
+      sync = col.sync_collection(login, False)
+      assert sync.required == sync.NO_CHANGES
+      # TODO: create an archive with server content including a test card
+      # and check we got it?
+    '';
+    testPasswordFile = pkgs.writeText "anki-password" "passfilepassword";
+  in
+  {
+  name = "anki-sync-server";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ martinetd ];
+  };
+
+  nodes.machine = { pkgs, ...}: {
+    services.anki-sync-server = {
+      enable = true;
+      users = [
+        { username = "user";
+          password = "password";
+        }
+        { username = "passfileuser";
+          passwordFile = testPasswordFile;
+        }
+      ];
+    };
+  };
+
+
+  testScript =
+    ''
+      start_all()
+
+      with subtest("Server starts successfully"):
+          # service won't start without users
+          machine.wait_for_unit("anki-sync-server.service")
+          machine.wait_for_open_port(27701)
+
+      with subtest("Can sync"):
+          machine.succeed("${ankiSyncTest}")
+    '';
+})
diff --git a/nixpkgs/nixos/tests/centrifugo.nix b/nixpkgs/nixos/tests/centrifugo.nix
new file mode 100644
index 000000000000..45c2904f5585
--- /dev/null
+++ b/nixpkgs/nixos/tests/centrifugo.nix
@@ -0,0 +1,80 @@
+let
+  redisPort = 6379;
+  centrifugoPort = 8080;
+  nodes = [
+    "centrifugo1"
+    "centrifugo2"
+    "centrifugo3"
+  ];
+in
+{ lib, ... }: {
+  name = "centrifugo";
+  meta.maintainers = [ lib.maintainers.tie ];
+
+  nodes = lib.listToAttrs (lib.imap0
+    (index: name: {
+      inherit name;
+      value = { config, ... }: {
+        services.centrifugo = {
+          enable = true;
+          settings = {
+            inherit name;
+            port = centrifugoPort;
+            # See https://centrifugal.dev/docs/server/engines#redis-sharding
+            engine = "redis";
+            # Connect to local Redis shard via Unix socket.
+            redis_address =
+              let
+                otherNodes = lib.take index nodes ++ lib.drop (index + 1) nodes;
+              in
+              map (name: "${name}:${toString redisPort}") otherNodes ++ [
+                "unix://${config.services.redis.servers.centrifugo.unixSocket}"
+              ];
+            usage_stats_disable = true;
+            api_insecure = true;
+          };
+          extraGroups = [
+            config.services.redis.servers.centrifugo.user
+          ];
+        };
+        services.redis.servers.centrifugo = {
+          enable = true;
+          bind = null; # all interfaces
+          port = redisPort;
+          openFirewall = true;
+          settings.protected-mode = false;
+        };
+      };
+    })
+    nodes);
+
+  testScript = ''
+    import json
+
+    redisPort = ${toString redisPort}
+    centrifugoPort = ${toString centrifugoPort}
+
+    start_all()
+
+    for machine in machines:
+      machine.wait_for_unit("redis-centrifugo.service")
+      machine.wait_for_open_port(redisPort)
+
+    for machine in machines:
+      machine.wait_for_unit("centrifugo.service")
+      machine.wait_for_open_port(centrifugoPort)
+
+    # See https://centrifugal.dev/docs/server/server_api#info
+    def list_nodes(machine):
+      curl = "curl --fail-with-body --silent"
+      body = "{}"
+      resp = json.loads(machine.succeed(f"{curl} -d '{body}' http://localhost:{centrifugoPort}/api/info"))
+      return resp["result"]["nodes"]
+    machineNames = {m.name for m in machines}
+    for machine in machines:
+      nodes = list_nodes(machine)
+      assert len(nodes) == len(machines)
+      nodeNames = {n['name'] for n in nodes}
+      assert machineNames == nodeNames
+  '';
+}
diff --git a/nixpkgs/nixos/tests/containers-ip.nix b/nixpkgs/nixos/tests/containers-ip.nix
index ecead5c22f75..ecff99a3f0c2 100644
--- a/nixpkgs/nixos/tests/containers-ip.nix
+++ b/nixpkgs/nixos/tests/containers-ip.nix
@@ -19,10 +19,7 @@ in import ./make-test-python.nix ({ pkgs, lib, ... }: {
 
   nodes.machine =
     { pkgs, ... }: {
-      imports = [ ../modules/installer/cd-dvd/channel.nix ];
-      virtualisation = {
-        writableStore = true;
-      };
+      virtualisation.writableStore = true;
 
       containers.webserver4 = webserverFor "10.231.136.1" "10.231.136.2";
       containers.webserver6 = webserverFor "fc00::2" "fc00::1";
diff --git a/nixpkgs/nixos/tests/convos.nix b/nixpkgs/nixos/tests/convos.nix
index 8fe5892da9e5..06d8d30fcb14 100644
--- a/nixpkgs/nixos/tests/convos.nix
+++ b/nixpkgs/nixos/tests/convos.nix
@@ -22,7 +22,6 @@ in
   testScript = ''
     machine.wait_for_unit("convos")
     machine.wait_for_open_port(${toString port})
-    machine.succeed("journalctl -u convos | grep -q 'application available at.*${toString port}'")
     machine.succeed("curl -f http://localhost:${toString port}/")
   '';
 })
diff --git a/nixpkgs/nixos/tests/deepin.nix b/nixpkgs/nixos/tests/deepin.nix
index 7b2e2430f31c..d3ce79a535c1 100644
--- a/nixpkgs/nixos/tests/deepin.nix
+++ b/nixpkgs/nixos/tests/deepin.nix
@@ -36,12 +36,6 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
       with subtest("Check that logging in has given the user ownership of devices"):
           machine.succeed("getfacl -p /dev/snd/timer | grep -q ${user.name}")
 
-      with subtest("Check if DDE wm chooser actually start"):
-          machine.wait_until_succeeds("pgrep -f dde-wm-chooser")
-          machine.wait_for_window("dde-wm-chooser")
-          machine.execute("pkill dde-wm-chooser")
-
-
       with subtest("Check if Deepin session components actually start"):
           machine.wait_until_succeeds("pgrep -f dde-session-daemon")
           machine.wait_for_window("dde-session-daemon")
diff --git a/nixpkgs/nixos/tests/dublin-traceroute.nix b/nixpkgs/nixos/tests/dublin-traceroute.nix
new file mode 100644
index 000000000000..b359b7fcdd6f
--- /dev/null
+++ b/nixpkgs/nixos/tests/dublin-traceroute.nix
@@ -0,0 +1,63 @@
+# This is a simple distributed test involving a topology with two
+# separate virtual networks - the "inside" and the "outside" - with a
+# client on the inside network, a server on the outside network, and a
+# router connected to both that performs Network Address Translation
+# for the client.
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+  let
+    routerBase =
+      lib.mkMerge [
+        { virtualisation.vlans = [ 2 1 ];
+          networking.nftables.enable = true;
+          networking.nat.internalIPs = [ "192.168.1.0/24" ];
+          networking.nat.externalInterface = "eth1";
+        }
+      ];
+  in
+  {
+    name = "dublin-traceroute";
+    meta = with pkgs.lib.maintainers; {
+      maintainers = [ baloo ];
+    };
+
+    nodes.client = { nodes, ... }: {
+      imports = [ ./common/user-account.nix ];
+      virtualisation.vlans = [ 1 ];
+
+      networking.defaultGateway =
+        (builtins.head nodes.router.networking.interfaces.eth2.ipv4.addresses).address;
+      networking.nftables.enable = true;
+
+      programs.dublin-traceroute.enable = true;
+    };
+
+    nodes.router = { ... }: {
+      virtualisation.vlans = [ 2 1 ];
+      networking.nftables.enable = true;
+      networking.nat.internalIPs = [ "192.168.1.0/24" ];
+      networking.nat.externalInterface = "eth1";
+      networking.nat.enable = true;
+    };
+
+    nodes.server = { ... }: {
+      virtualisation.vlans = [ 2 ];
+      networking.firewall.enable = false;
+      services.httpd.enable = true;
+      services.httpd.adminAddr = "foo@example.org";
+      services.vsftpd.enable = true;
+      services.vsftpd.anonymousUser = true;
+    };
+
+    testScript = ''
+      client.start()
+      router.start()
+      server.start()
+
+      server.wait_for_unit("network.target")
+      router.wait_for_unit("network.target")
+      client.wait_for_unit("network.target")
+
+      # Make sure we can trace from an unprivileged user
+      client.succeed("sudo -u alice dublin-traceroute server")
+    '';
+  })
diff --git a/nixpkgs/nixos/tests/eris-server.nix b/nixpkgs/nixos/tests/eris-server.nix
index a50db3afebf5..b9d2b57401e0 100644
--- a/nixpkgs/nixos/tests/eris-server.nix
+++ b/nixpkgs/nixos/tests/eris-server.nix
@@ -3,7 +3,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
   meta.maintainers = with lib.maintainers; [ ehmry ];
 
   nodes.server = {
-    environment.systemPackages = [ pkgs.eris-go pkgs.nim.pkgs.eris ];
+    environment.systemPackages = [ pkgs.eris-go pkgs.eriscmd ];
     services.eris-server = {
       enable = true;
       decode = true;
diff --git a/nixpkgs/nixos/tests/geoserver.nix b/nixpkgs/nixos/tests/geoserver.nix
new file mode 100644
index 000000000000..7e5507a296ea
--- /dev/null
+++ b/nixpkgs/nixos/tests/geoserver.nix
@@ -0,0 +1,24 @@
+{ pkgs, lib, ... }: {
+
+  name = "geoserver";
+  meta = {
+    maintainers = with lib; [ teams.geospatial.members ];
+  };
+
+  nodes = {
+    machine = { pkgs, ... }: {
+      virtualisation.diskSize = 2 * 1024;
+
+      environment.systemPackages = [ pkgs.geoserver ];
+    };
+  };
+
+  testScript = ''
+    start_all()
+
+    machine.execute("${pkgs.geoserver}/bin/geoserver-startup > /dev/null 2>&1 &")
+    machine.wait_until_succeeds("curl --fail --connect-timeout 2 http://localhost:8080/geoserver", timeout=60)
+
+    machine.succeed("curl --fail --connect-timeout 2 http://localhost:8080/geoserver/ows?service=WMS&version=1.3.0&request=GetCapabilities")
+  '';
+}
diff --git a/nixpkgs/nixos/tests/gnome-extensions.nix b/nixpkgs/nixos/tests/gnome-extensions.nix
new file mode 100644
index 000000000000..2faff9a4a80d
--- /dev/null
+++ b/nixpkgs/nixos/tests/gnome-extensions.nix
@@ -0,0 +1,151 @@
+import ./make-test-python.nix (
+{ pkgs, lib, ...}:
+{
+  name = "gnome-extensions";
+  meta.maintainers = [ lib.maintainers.piegames ];
+
+  nodes.machine =
+    { pkgs, ... }:
+    {
+      imports = [ ./common/user-account.nix ];
+
+      # Install all extensions
+      environment.systemPackages = lib.filter (e: e ? extensionUuid) (lib.attrValues pkgs.gnomeExtensions);
+
+      # Some extensions are broken, but that's kind of the point of a testing VM
+      nixpkgs.config.allowBroken = true;
+      # There are some aliases which throw exceptions; ignore them.
+      # Also prevent duplicate extensions under different names.
+      nixpkgs.config.allowAliases = false;
+
+      # Configure GDM
+      services.xserver.enable = true;
+      services.xserver.displayManager = {
+        gdm = {
+          enable = true;
+          debug = true;
+          wayland = true;
+        };
+        autoLogin = {
+          enable = true;
+          user = "alice";
+        };
+      };
+
+      # Configure Gnome
+      services.xserver.desktopManager.gnome.enable = true;
+      services.xserver.desktopManager.gnome.debug = true;
+
+      systemd.user.services = {
+        "org.gnome.Shell@wayland" = {
+          serviceConfig = {
+            ExecStart = [
+              # Clear the list before overriding it.
+              ""
+              # Eval API is now internal so Shell needs to run in unsafe mode.
+              # TODO: improve test driver so that it supports openqa-like manipulation
+              # that would allow us to drop this mess.
+              "${pkgs.gnome.gnome-shell}/bin/gnome-shell --unsafe-mode"
+            ];
+          };
+        };
+      };
+
+    };
+
+  testScript = { nodes, ... }: let
+    # Keep line widths somewhat manageable
+    user = nodes.machine.users.users.alice;
+    uid = toString user.uid;
+    bus = "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${uid}/bus";
+    # Run a command in the appropriate user environment
+    run = command: "su - ${user.name} -c '${bus} ${command}'";
+
+    # Call javascript in gnome shell, returns a tuple (success, output), where
+    # `success` is true if the dbus call was successful and output is what the
+    # javascript evaluates to.
+    eval = command: run "gdbus call --session -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval ${command}";
+
+    # False when startup is done
+    startingUp = eval "Main.layoutManager._startingUp";
+
+    # Extensions to keep always enabled together
+    # Those are extensions that are usually always on for many users, and that we expect to work
+    # well together with most others without conflicts
+    alwaysOnExtensions = map (name: pkgs.gnomeExtensions.${name}.extensionUuid) [
+      "applications-menu"
+      "user-themes"
+    ];
+
+    # Extensions to enable and disable individually
+    # Extensions like dash-to-dock and dash-to-panel cannot be enabled at the same time.
+    testExtensions = map (name: pkgs.gnomeExtensions.${name}.extensionUuid) [
+      "appindicator"
+      "dash-to-dock"
+      "dash-to-panel"
+      "ddterm"
+      "emoji-selector"
+      "gsconnect"
+      "system-monitor"
+      "desktop-icons-ng-ding"
+      "workspace-indicator"
+      "vitals"
+    ];
+  in
+  ''
+    with subtest("Login to GNOME with GDM"):
+        # wait for gdm to start
+        machine.wait_for_unit("display-manager.service")
+        # wait for the wayland server
+        machine.wait_for_file("/run/user/${uid}/wayland-0")
+        # wait for alice to be logged in
+        machine.wait_for_unit("default.target", "${user.name}")
+        # check that logging in has given the user ownership of devices
+        assert "alice" in machine.succeed("getfacl -p /dev/snd/timer")
+
+    with subtest("Wait for GNOME Shell"):
+        # correct output should be (true, 'false')
+        machine.wait_until_succeeds(
+            "${startingUp} | grep -q 'true,..false'"
+        )
+
+        # Close the Activities view so that Shell can correctly track the focused window.
+        machine.send_key("esc")
+        # # Disable extension version validation (only use for manual testing)
+        # machine.succeed(
+        #   "${run "gsettings set org.gnome.shell disable-extension-version-validation true"}"
+        # )
+
+    # Assert that some extension is in a specific state
+    def checkState(target, extension):
+        state = machine.succeed(
+            f"${run "gnome-extensions info {extension}"} | grep '^  State: .*$'"
+        )
+        assert target in state, f"{state} instead of {target}"
+
+    def checkExtension(extension, disable):
+        with subtest(f"Enable extension '{extension}'"):
+            # Check that the extension is properly initialized; skip out of date ones
+            state = machine.succeed(
+                f"${run "gnome-extensions info {extension}"} | grep '^  State: .*$'"
+            )
+            if "OUT OF DATE" in state:
+                machine.log(f"Extension {extension} will be skipped because out of date")
+                return
+
+            assert "INITIALIZED" in state, f"{state} instead of INITIALIZED"
+
+            # Enable and optionally disable
+
+            machine.succeed(f"${run "gnome-extensions enable {extension}"}")
+            checkState("ENABLED", extension)
+
+            if disable:
+                machine.succeed(f"${run "gnome-extensions disable {extension}"}")
+                checkState("DISABLED", extension)
+    ''
+    + lib.concatLines (map (e: ''checkExtension("${e}", False)'') alwaysOnExtensions)
+    + lib.concatLines (map (e: ''checkExtension("${e}", True)'') testExtensions)
+  ;
+}
+)
diff --git a/nixpkgs/nixos/tests/gnome-xorg.nix b/nixpkgs/nixos/tests/gnome-xorg.nix
index 7762fff5c3a2..6ca700edcac3 100644
--- a/nixpkgs/nixos/tests/gnome-xorg.nix
+++ b/nixpkgs/nixos/tests/gnome-xorg.nix
@@ -5,7 +5,7 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
   };
 
   nodes.machine = { nodes, ... }: let
-    user = nodes.machine.config.users.users.alice;
+    user = nodes.machine.users.users.alice;
   in
 
     { imports = [ ./common/user-account.nix ];
@@ -43,28 +43,28 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
     };
 
   testScript = { nodes, ... }: let
-    user = nodes.machine.config.users.users.alice;
+    user = nodes.machine.users.users.alice;
     uid = toString user.uid;
     bus = "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${uid}/bus";
     xauthority = "/run/user/${uid}/gdm/Xauthority";
     display = "DISPLAY=:0.0";
     env = "${bus} XAUTHORITY=${xauthority} ${display}";
-    gdbus = "${env} gdbus";
-    su = command: "su - ${user.name} -c '${env} ${command}'";
+    # Run a command in the appropriate user environment
+    run = command: "su - ${user.name} -c '${bus} ${command}'";
 
     # Call javascript in gnome shell, returns a tuple (success, output), where
     # `success` is true if the dbus call was successful and output is what the
     # javascript evaluates to.
-    eval = "call --session -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval";
+    eval = command: run "gdbus call --session -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval ${command}";
 
     # False when startup is done
-    startingUp = su "${gdbus} ${eval} Main.layoutManager._startingUp";
+    startingUp = eval "Main.layoutManager._startingUp";
 
     # Start Console
-    launchConsole = su "${bus} gapplication launch org.gnome.Console";
+    launchConsole = run "gapplication launch org.gnome.Console";
 
     # Hopefully Console's wm class
-    wmClass = su "${gdbus} ${eval} global.display.focus_window.wm_class";
+    wmClass = eval "global.display.focus_window.wm_class";
   in ''
       with subtest("Login to GNOME Xorg with GDM"):
           machine.wait_for_x()
diff --git a/nixpkgs/nixos/tests/gnome.nix b/nixpkgs/nixos/tests/gnome.nix
index 448a3350240c..91182790cb24 100644
--- a/nixpkgs/nixos/tests/gnome.nix
+++ b/nixpkgs/nixos/tests/gnome.nix
@@ -40,25 +40,25 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
 
   testScript = { nodes, ... }: let
     # Keep line widths somewhat manageable
-    user = nodes.machine.config.users.users.alice;
+    user = nodes.machine.users.users.alice;
     uid = toString user.uid;
     bus = "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${uid}/bus";
-    gdbus = "${bus} gdbus";
-    su = command: "su - ${user.name} -c '${command}'";
+    # Run a command in the appropriate user environment
+    run = command: "su - ${user.name} -c '${bus} ${command}'";
 
     # Call javascript in gnome shell, returns a tuple (success, output), where
     # `success` is true if the dbus call was successful and output is what the
     # javascript evaluates to.
-    eval = "call --session -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval";
+    eval = command: run "gdbus call --session -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval ${command}";
 
     # False when startup is done
-    startingUp = su "${gdbus} ${eval} Main.layoutManager._startingUp";
+    startingUp = eval "Main.layoutManager._startingUp";
 
     # Start Console
-    launchConsole = su "${bus} gapplication launch org.gnome.Console";
+    launchConsole = run "gapplication launch org.gnome.Console";
 
     # Hopefully Console's wm class
-    wmClass = su "${gdbus} ${eval} global.display.focus_window.wm_class";
+    wmClass = eval "global.display.focus_window.wm_class";
   in ''
       with subtest("Login to GNOME with GDM"):
           # wait for gdm to start
diff --git a/nixpkgs/nixos/tests/gvisor.nix b/nixpkgs/nixos/tests/gvisor.nix
index 77ff29341bed..7f130b709fc9 100644
--- a/nixpkgs/nixos/tests/gvisor.nix
+++ b/nixpkgs/nixos/tests/gvisor.nix
@@ -1,6 +1,6 @@
 # This test runs a container through gvisor and checks if simple container starts
 
-import ./make-test-python.nix ({ pkgs, ...} : {
+import ./make-test-python.nix ({ pkgs, ... }: {
   name = "gvisor";
   meta = with pkgs.lib.maintainers; {
     maintainers = [ andrew-d ];
@@ -9,21 +9,21 @@ import ./make-test-python.nix ({ pkgs, ...} : {
   nodes = {
     gvisor =
       { pkgs, ... }:
-        {
-          virtualisation.docker = {
-            enable = true;
-            extraOptions = "--add-runtime runsc=${pkgs.gvisor}/bin/runsc";
-          };
+      {
+        virtualisation.docker = {
+          enable = true;
+          extraOptions = "--add-runtime runsc=${pkgs.gvisor}/bin/runsc";
+        };
 
-          networking = {
-            dhcpcd.enable = false;
-            defaultGateway = "192.168.1.1";
-            interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [
-              { address = "192.168.1.2"; prefixLength = 24; }
-            ];
-          };
+        networking = {
+          dhcpcd.enable = false;
+          defaultGateway = "192.168.1.1";
+          interfaces.eth1.ipv4.addresses = pkgs.lib.mkOverride 0 [
+            { address = "192.168.1.2"; prefixLength = 24; }
+          ];
         };
-    };
+      };
+  };
 
   testScript = ''
     start_all()
@@ -31,13 +31,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
     gvisor.wait_for_unit("network.target")
     gvisor.wait_for_unit("sockets.target")
 
-    # Start by verifying that gvisor itself works
-    output = gvisor.succeed(
-        "${pkgs.gvisor}/bin/runsc -alsologtostderr do ${pkgs.coreutils}/bin/echo hello world"
-    )
-    assert output.strip() == "hello world"
-
-    # Also test the Docker runtime
+    # Test the Docker runtime
     gvisor.succeed("tar cv --files-from /dev/null | docker import - scratchimg")
     gvisor.succeed(
         "docker run -d --name=sleeping --runtime=runsc -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
diff --git a/nixpkgs/nixos/tests/incus/container.nix b/nixpkgs/nixos/tests/incus/container.nix
index 79b9e2fbabdc..49a22c08aad1 100644
--- a/nixpkgs/nixos/tests/incus/container.nix
+++ b/nixpkgs/nixos/tests/incus/container.nix
@@ -73,5 +73,33 @@ in
         meminfo = machine.succeed("incus exec container grep -- MemTotal /proc/meminfo").strip()
         meminfo_bytes = " ".join(meminfo.split(' ')[-2:])
         assert meminfo_bytes == "125000 kB", f"Wrong amount of memory reported from /proc/meminfo, want: '125000 kB', got: '{meminfo_bytes}'"
+
+    with subtest("lxc-container generator configures plain container"):
+        machine.execute("incus delete --force container")
+        machine.succeed("incus launch nixos container")
+        with machine.nested("Waiting for instance to start and be usable"):
+          retry(instance_is_up)
+
+        machine.succeed("incus exec container test -- -e /run/systemd/system/service.d/zzz-lxc-service.conf")
+
+    with subtest("lxc-container generator configures nested container"):
+        machine.execute("incus delete --force container")
+        machine.succeed("incus launch nixos container --config security.nesting=true")
+        with machine.nested("Waiting for instance to start and be usable"):
+          retry(instance_is_up)
+
+        machine.fail("incus exec container test -- -e /run/systemd/system/service.d/zzz-lxc-service.conf")
+        target = machine.succeed("incus exec container readlink -- -f /run/systemd/system/systemd-binfmt.service").strip()
+        assert target == "/dev/null", "lxc generator did not correctly mask /run/systemd/system/systemd-binfmt.service"
+
+    with subtest("lxc-container generator configures privileged container"):
+        machine.execute("incus delete --force container")
+        machine.succeed("incus launch nixos container --config security.privileged=true")
+        with machine.nested("Waiting for instance to start and be usable"):
+          retry(instance_is_up)
+        # give generator an extra second to run
+        machine.sleep(1)
+
+        machine.succeed("incus exec container test -- -e /run/systemd/system/service.d/zzz-lxc-service.conf")
   '';
 })
diff --git a/nixpkgs/nixos/tests/jitsi-meet.nix b/nixpkgs/nixos/tests/jitsi-meet.nix
index c39cd19e1f0a..fc6654f2c076 100644
--- a/nixpkgs/nixos/tests/jitsi-meet.nix
+++ b/nixpkgs/nixos/tests/jitsi-meet.nix
@@ -24,10 +24,23 @@ import ./make-test-python.nix ({ pkgs, ... }: {
       security.acme.acceptTerms = true;
       security.acme.defaults.email = "me@example.org";
       security.acme.defaults.server = "https://example.com"; # self-signed only
+
+      specialisation.caddy = {
+        inheritParentConfig = true;
+        configuration = {
+          services.jitsi-meet = {
+            caddy.enable = true;
+            nginx.enable = false;
+          };
+          services.caddy.virtualHosts.${config.services.jitsi-meet.hostName}.extraConfig = ''
+            tls internal
+          '';
+        };
+      };
     };
   };
 
-  testScript = ''
+  testScript = { nodes, ... }: ''
     server.wait_for_unit("jitsi-videobridge2.service")
     server.wait_for_unit("jicofo.service")
     server.wait_for_unit("nginx.service")
@@ -41,6 +54,15 @@ import ./make-test-python.nix ({ pkgs, ... }: {
     )
 
     client.wait_for_unit("network.target")
-    assert "<title>Jitsi Meet</title>" in client.succeed("curl -sSfkL http://server/")
+
+    def client_curl():
+        assert "<title>Jitsi Meet</title>" in client.succeed("curl -sSfkL http://server/")
+
+    client_curl()
+
+    with subtest("Testing backup service"):
+        server.succeed("${nodes.server.system.build.toplevel}/specialisation/caddy/bin/switch-to-configuration test")
+        server.wait_for_unit("caddy.service")
+        client_curl()
   '';
 })
diff --git a/nixpkgs/nixos/tests/kafka.nix b/nixpkgs/nixos/tests/kafka.nix
index 864253fd8c73..f4f9827ab7b5 100644
--- a/nixpkgs/nixos/tests/kafka.nix
+++ b/nixpkgs/nixos/tests/kafka.nix
@@ -6,13 +6,62 @@
 with pkgs.lib;
 
 let
-  makeKafkaTest = name: kafkaPackage: (import ./make-test-python.nix ({
+  makeKafkaTest = name: { kafkaPackage, mode ? "zookeeper" }: (import ./make-test-python.nix ({
     inherit name;
     meta = with pkgs.lib.maintainers; {
       maintainers = [ nequissimus ];
     };
 
     nodes = {
+      kafka = { ... }: {
+        services.apache-kafka = mkMerge [
+          ({
+            enable = true;
+            package = kafkaPackage;
+            settings = {
+              "offsets.topic.replication.factor" = 1;
+              "log.dirs" = [
+                "/var/lib/kafka/logdir1"
+                "/var/lib/kafka/logdir2"
+              ];
+            };
+          })
+          (mkIf (mode == "zookeeper") {
+            settings = {
+              "zookeeper.session.timeout.ms" = 600000;
+              "zookeeper.connect" = [ "zookeeper1:2181" ];
+            };
+          })
+          (mkIf (mode == "kraft") {
+            clusterId = "ak2fIHr4S8WWarOF_ODD0g";
+            formatLogDirs = true;
+            settings = {
+              "node.id" = 1;
+              "process.roles" = [
+                "broker"
+                "controller"
+              ];
+              "listeners" = [
+                "PLAINTEXT://:9092"
+                "CONTROLLER://:9093"
+              ];
+              "listener.security.protocol.map" = [
+                "PLAINTEXT:PLAINTEXT"
+                "CONTROLLER:PLAINTEXT"
+              ];
+              "controller.quorum.voters" = [
+                "1@kafka:9093"
+              ];
+              "controller.listener.names" = [ "CONTROLLER" ];
+            };
+          })
+        ];
+
+        networking.firewall.allowedTCPPorts = [ 9092 9093 ];
+        # i686 tests: qemu-system-i386 can simulate max 2047MB RAM (not 2048)
+        virtualisation.memorySize = 2047;
+      };
+    } // optionalAttrs (mode == "zookeeper") {
       zookeeper1 = { ... }: {
         services.zookeeper = {
           enable = true;
@@ -20,29 +69,16 @@ let
 
         networking.firewall.allowedTCPPorts = [ 2181 ];
       };
-      kafka = { ... }: {
-        services.apache-kafka = {
-          enable = true;
-          extraProperties = ''
-            offsets.topic.replication.factor = 1
-            zookeeper.session.timeout.ms = 600000
-          '';
-          package = kafkaPackage;
-          zookeeper = "zookeeper1:2181";
-        };
-
-        networking.firewall.allowedTCPPorts = [ 9092 ];
-        # i686 tests: qemu-system-i386 can simulate max 2047MB RAM (not 2048)
-        virtualisation.memorySize = 2047;
-      };
     };
 
     testScript = ''
       start_all()
 
+      ${optionalString (mode == "zookeeper") ''
       zookeeper1.wait_for_unit("default.target")
       zookeeper1.wait_for_unit("zookeeper.service")
       zookeeper1.wait_for_open_port(2181)
+      ''}
 
       kafka.wait_for_unit("default.target")
       kafka.wait_for_unit("apache-kafka.service")
@@ -67,12 +103,13 @@ let
   }) { inherit system; });
 
 in with pkgs; {
-  kafka_2_8  = makeKafkaTest "kafka_2_8"  apacheKafka_2_8;
-  kafka_3_0  = makeKafkaTest "kafka_3_0"  apacheKafka_3_0;
-  kafka_3_1  = makeKafkaTest "kafka_3_1"  apacheKafka_3_1;
-  kafka_3_2  = makeKafkaTest "kafka_3_2"  apacheKafka_3_2;
-  kafka_3_3  = makeKafkaTest "kafka_3_3"  apacheKafka_3_3;
-  kafka_3_4  = makeKafkaTest "kafka_3_4"  apacheKafka_3_4;
-  kafka_3_5  = makeKafkaTest "kafka_3_5"  apacheKafka_3_5;
-  kafka  = makeKafkaTest "kafka"  apacheKafka;
+  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 = makeKafkaTest "kafka" { kafkaPackage = apacheKafka; };
+  kafka_kraft = makeKafkaTest "kafka_kraft" { kafkaPackage = apacheKafka; mode = "kraft"; };
 }
diff --git a/nixpkgs/nixos/tests/lanraragi.nix b/nixpkgs/nixos/tests/lanraragi.nix
index f513ac9d252b..7a4a1a489bdf 100644
--- a/nixpkgs/nixos/tests/lanraragi.nix
+++ b/nixpkgs/nixos/tests/lanraragi.nix
@@ -10,19 +10,17 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
       services.lanraragi = {
         enable = true;
         passwordFile = pkgs.writeText "lrr-test-pass" ''
-          ultra-secure-password
+          Ultra-secure-p@ssword-"with-spec1al\chars
         '';
         port = 4000;
         redis = {
           port = 4001;
           passwordFile = pkgs.writeText "redis-lrr-test-pass" ''
-            still-a-very-secure-password
+            123-redis-PASS
           '';
         };
       };
     };
-
-
   };
 
   testScript = ''
@@ -34,7 +32,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
 
     machine2.wait_for_unit("lanraragi.service")
     machine2.wait_until_succeeds("curl -f localhost:4000")
-    machine2.succeed("[ $(curl -o /dev/null -X post 'http://localhost:4000/login' --data-raw 'password=ultra-secure-password' -w '%{http_code}') -eq 302 ]")
+    machine2.succeed("[ $(curl -o /dev/null -X post 'http://localhost:4000/login' --data-raw 'password=Ultra-secure-p@ssword-\"with-spec1al\\chars' -w '%{http_code}') -eq 302 ]")
   '';
 })
 
diff --git a/nixpkgs/nixos/tests/libvirtd.nix b/nixpkgs/nixos/tests/libvirtd.nix
index 41d06cc9643f..df80dcc21a2e 100644
--- a/nixpkgs/nixos/tests/libvirtd.nix
+++ b/nixpkgs/nixos/tests/libvirtd.nix
@@ -14,10 +14,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
           libvirtd.hooks.qemu.is_working = "${pkgs.writeShellScript "testHook.sh" ''
             touch /tmp/qemu_hook_is_working
           ''}";
+          libvirtd.nss.enable = true;
         };
         boot.supportedFilesystems = [ "zfs" ];
         networking.hostId = "deadbeef"; # needed for zfs
-        networking.nameservers = [ "192.168.122.1" ];
         security.polkit.enable = true;
         environment.systemPackages = with pkgs; [ virt-manager ];
       };
diff --git a/nixpkgs/nixos/tests/lxd/ui.nix b/nixpkgs/nixos/tests/lxd/ui.nix
index 86cb30d8c2b6..ff651725ba70 100644
--- a/nixpkgs/nixos/tests/lxd/ui.nix
+++ b/nixpkgs/nixos/tests/lxd/ui.nix
@@ -11,9 +11,37 @@ import ../make-test-python.nix ({ pkgs, lib, ... }: {
       lxd.ui.enable = true;
     };
 
-    environment.systemPackages = [ pkgs.curl ];
+    environment.systemPackages =
+      let
+        seleniumScript = pkgs.writers.writePython3Bin "selenium-script"
+          {
+            libraries = with pkgs.python3Packages; [ selenium ];
+          } ''
+          from selenium import webdriver
+          from selenium.webdriver.common.by import By
+          from selenium.webdriver.firefox.options import Options
+          from selenium.webdriver.support.ui import WebDriverWait
+
+          options = Options()
+          options.add_argument("--headless")
+          service = webdriver.FirefoxService(executable_path="${lib.getExe pkgs.geckodriver}")  # noqa: E501
+
+          driver = webdriver.Firefox(options=options, service=service)
+          driver.implicitly_wait(10)
+          driver.get("https://localhost:8443/ui")
+
+          wait = WebDriverWait(driver, 60)
+
+          assert len(driver.find_elements(By.CLASS_NAME, "l-application")) > 0
+          assert len(driver.find_elements(By.CLASS_NAME, "l-navigation__drawer")) > 0
+
+          driver.close()
+        '';
+      in
+      with pkgs; [ curl firefox-unwrapped geckodriver seleniumScript ];
   };
 
+
   testScript = ''
     machine.wait_for_unit("sockets.target")
     machine.wait_for_unit("lxd.service")
@@ -31,5 +59,8 @@ import ../make-test-python.nix ({ pkgs, lib, ... }: {
 
     # Ensure the endpoint returns an HTML page with 'LXD UI' in the title
     machine.succeed("curl -kLs https://localhost:8443/ui | grep '<title>LXD UI</title>'")
+
+    # Ensure the application is actually rendered by the Javascript
+    machine.succeed("PYTHONUNBUFFERED=1 selenium-script")
   '';
 })
diff --git a/nixpkgs/nixos/tests/matrix/synapse.nix b/nixpkgs/nixos/tests/matrix/synapse.nix
index 98b077469192..8c10a575ffbd 100644
--- a/nixpkgs/nixos/tests/matrix/synapse.nix
+++ b/nixpkgs/nixos/tests/matrix/synapse.nix
@@ -1,31 +1,15 @@
 import ../make-test-python.nix ({ pkgs, ... } : let
 
-
-  runWithOpenSSL = file: cmd: pkgs.runCommand file {
-    buildInputs = [ pkgs.openssl ];
-  } cmd;
-
-
-  ca_key = runWithOpenSSL "ca-key.pem" "openssl genrsa -out $out 2048";
-  ca_pem = runWithOpenSSL "ca.pem" ''
-    openssl req \
-      -x509 -new -nodes -key ${ca_key} \
-      -days 10000 -out $out -subj "/CN=snakeoil-ca"
+  ca_key = mailerCerts.ca.key;
+  ca_pem = mailerCerts.ca.cert;
+
+  bundle = pkgs.runCommand "bundle" {
+    nativeBuildInputs = [ pkgs.minica ];
+  } ''
+    minica -ca-cert ${ca_pem} -ca-key ${ca_key} \
+      -domains localhost
+    install -Dm444 -t $out localhost/{key,cert}.pem
   '';
-  key = runWithOpenSSL "matrix_key.pem" "openssl genrsa -out $out 2048";
-  csr = runWithOpenSSL "matrix.csr" ''
-    openssl req \
-       -new -key ${key} \
-       -out $out -subj "/CN=localhost" \
-  '';
-  cert = runWithOpenSSL "matrix_cert.pem" ''
-    openssl x509 \
-      -req -in ${csr} \
-      -CA ${ca_pem} -CAkey ${ca_key} \
-      -CAcreateserial -out $out \
-      -days 365
-  '';
-
 
   mailerCerts = import ../common/acme/server/snakeoil-certs.nix;
   mailerDomain = mailerCerts.domain;
@@ -82,8 +66,8 @@ in {
             host = "localhost";
             port = config.services.redis.servers.matrix-synapse.port;
           };
-          tls_certificate_path = "${cert}";
-          tls_private_key_path = "${key}";
+          tls_certificate_path = "${bundle}/cert.pem";
+          tls_private_key_path = "${bundle}/key.pem";
           registration_shared_secret = registrationSharedSecret;
           public_baseurl = "https://example.com";
           email = {
@@ -203,8 +187,8 @@ in {
         settings = {
           inherit listeners;
           database.name = "sqlite3";
-          tls_certificate_path = "${cert}";
-          tls_private_key_path = "${key}";
+          tls_certificate_path = "${bundle}/cert.pem";
+          tls_private_key_path = "${bundle}/key.pem";
         };
       };
     };
@@ -222,7 +206,7 @@ in {
         "journalctl -u matrix-synapse.service | grep -q 'Connected to redis'"
     )
     serverpostgres.require_unit_state("postgresql.service")
-    serverpostgres.succeed("register_new_matrix_user -u ${testUser} -p ${testPassword} -a -k ${registrationSharedSecret} https://localhost:8448/")
+    serverpostgres.succeed("REQUESTS_CA_BUNDLE=${ca_pem} register_new_matrix_user -u ${testUser} -p ${testPassword} -a -k ${registrationSharedSecret} https://localhost:8448/")
     serverpostgres.succeed("obtain-token-and-register-email")
     serversqlite.wait_for_unit("matrix-synapse.service")
     serversqlite.wait_until_succeeds(
diff --git a/nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix b/nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix
index e638f2e5b861..addc898bd760 100644
--- a/nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix
+++ b/nixpkgs/nixos/tests/nextcloud/with-declarative-redis-and-secrets.nix
@@ -41,10 +41,13 @@ in {
         };
         secretFile = "/etc/nextcloud-secrets.json";
 
-        extraOptions.redis = {
-          dbindex = 0;
-          timeout = 1.5;
-          # password handled via secretfile below
+        extraOptions = {
+          allow_local_remote_servers = true;
+          redis = {
+            dbindex = 0;
+            timeout = 1.5;
+            # password handled via secretfile below
+          };
         };
         configureRedis = true;
       };
@@ -62,6 +65,7 @@ in {
 
       services.postgresql = {
         enable = true;
+        package = pkgs.postgresql_14;
       };
       systemd.services.postgresql.postStart = pkgs.lib.mkAfter ''
         password=$(cat ${passFile})
diff --git a/nixpkgs/nixos/tests/nixops/default.nix b/nixpkgs/nixos/tests/nixops/default.nix
index b8f747b2a19f..f7a26f2461c4 100644
--- a/nixpkgs/nixos/tests/nixops/default.nix
+++ b/nixpkgs/nixos/tests/nixops/default.nix
@@ -1,4 +1,6 @@
-{ pkgs, ... }:
+{ pkgs
+, testers
+, ... }:
 let
   inherit (pkgs) lib;
 
@@ -19,7 +21,7 @@ let
     passthru.override = args': testsForPackage (args // args');
   };
 
-  testLegacyNetwork = { nixopsPkg, ... }: pkgs.nixosTest ({
+  testLegacyNetwork = { nixopsPkg, ... }: testers.nixosTest ({
     name = "nixops-legacy-network";
     nodes = {
       deployer = { config, lib, nodes, pkgs, ... }: {
diff --git a/nixpkgs/nixos/tests/seatd.nix b/nixpkgs/nixos/tests/seatd.nix
new file mode 100644
index 000000000000..138a6cb1cf44
--- /dev/null
+++ b/nixpkgs/nixos/tests/seatd.nix
@@ -0,0 +1,51 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+
+let
+  seatd-test = pkgs.writeShellApplication {
+    name = "seatd-client-pid";
+    text = ''
+      journalctl -u seatd --no-pager -b | while read -r line; do
+          case "$line" in
+          *"New client connected"*)
+              line="''${line##*pid: }"
+              pid="''${line%%,*}"
+              ;;
+          *"Opened client"*)
+              echo "$pid"
+              exit
+          esac
+      done;
+    '';
+  };
+in
+{
+  name = "seatd";
+  meta.maintainers = with lib.maintainers; [ sinanmohd ];
+
+  nodes.machine = { ... }: {
+    imports = [ ./common/user-account.nix ];
+    services.getty.autologinUser = "alice";
+    users.users.alice.extraGroups = [ "seat" "wheel" ];
+
+    fonts.enableDefaultPackages = true;
+    environment.systemPackages = with pkgs; [
+      dwl
+      foot
+      seatd-test
+    ];
+
+    programs.bash.loginShellInit = ''
+      [ "$(tty)" = "/dev/tty1" ] &&
+          dwl -s 'foot touch /tmp/foot_started'
+    '';
+
+    hardware.opengl.enable = true;
+    virtualisation.qemu.options = [ "-vga none -device virtio-gpu-pci" ];
+    services.seatd.enable = true;
+  };
+
+  testScript = ''
+    machine.wait_for_file("/tmp/foot_started")
+    machine.succeed("test $(seatd-client-pid) = $(pgrep dwl)")
+  '';
+})
diff --git a/nixpkgs/nixos/tests/sonic-server.nix b/nixpkgs/nixos/tests/sonic-server.nix
new file mode 100644
index 000000000000..bb98047619b2
--- /dev/null
+++ b/nixpkgs/nixos/tests/sonic-server.nix
@@ -0,0 +1,22 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }: {
+  name = "sonic-server";
+
+  meta = {
+    maintainers = with lib.maintainers; [ anthonyroussel ];
+  };
+
+  nodes.machine = { pkgs, ... }: {
+    services.sonic-server.enable = true;
+  };
+
+  testScript = ''
+    machine.start()
+
+    machine.wait_for_unit("sonic-server.service")
+    machine.wait_for_open_port(1491)
+
+    with subtest("Check control mode"):
+      result = machine.succeed('(echo START control; sleep 1; echo PING; echo QUIT) | nc localhost 1491').splitlines()
+      assert result[2] == "PONG", f"expected 'PONG', got '{result[2]}'"
+  '';
+})
diff --git a/nixpkgs/nixos/tests/sudo-rs.nix b/nixpkgs/nixos/tests/sudo-rs.nix
index 6006863217b6..753e00686e95 100644
--- a/nixpkgs/nixos/tests/sudo-rs.nix
+++ b/nixpkgs/nixos/tests/sudo-rs.nix
@@ -22,11 +22,8 @@ in
           test5 = { isNormalUser = true; };
         };
 
-        security.sudo.enable = false;
-
         security.sudo-rs = {
           enable = true;
-          package = pkgs.sudo-rs;
           wheelNeedsPassword = false;
 
           extraRules = [
@@ -56,10 +53,7 @@ in
         noadmin = { isNormalUser = true; };
       };
 
-      security.sudo.enable = false;
-
       security.sudo-rs = {
-        package = pkgs.sudo-rs;
         enable = true;
         wheelNeedsPassword = false;
         execWheelOnly = true;
diff --git a/nixpkgs/nixos/tests/systemd-initrd-luks-unl0kr.nix b/nixpkgs/nixos/tests/systemd-initrd-luks-unl0kr.nix
new file mode 100644
index 000000000000..0658a098cfa2
--- /dev/null
+++ b/nixpkgs/nixos/tests/systemd-initrd-luks-unl0kr.nix
@@ -0,0 +1,75 @@
+import ./make-test-python.nix ({ lib, pkgs, ... }: let
+  passphrase = "secret";
+in {
+  name = "systemd-initrd-luks-unl0kr";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ tomfitzhenry ];
+  };
+
+  enableOCR = true;
+
+  nodes.machine = { pkgs, ... }: {
+    virtualisation = {
+      emptyDiskImages = [ 512 512 ];
+      useBootLoader = true;
+      mountHostNixStore = true;
+      useEFIBoot = true;
+      qemu.options = [
+        "-vga virtio"
+      ];
+    };
+    boot.loader.systemd-boot.enable = true;
+
+    boot.initrd.availableKernelModules = [
+      "evdev" # for entering pw
+      "bochs"
+    ];
+
+    environment.systemPackages = with pkgs; [ cryptsetup ];
+    boot.initrd = {
+      systemd = {
+        enable = true;
+        emergencyAccess = true;
+      };
+      unl0kr.enable = true;
+    };
+
+    specialisation.boot-luks.configuration = {
+      boot.initrd.luks.devices = lib.mkVMOverride {
+        # We have two disks and only type one password - key reuse is in place
+        cryptroot.device = "/dev/vdb";
+        cryptroot2.device = "/dev/vdc";
+      };
+      virtualisation.rootDevice = "/dev/mapper/cryptroot";
+      virtualisation.fileSystems."/".autoFormat = true;
+      # test mounting device unlocked in initrd after switching root
+      virtualisation.fileSystems."/cryptroot2".device = "/dev/mapper/cryptroot2";
+    };
+  };
+
+  testScript = ''
+    # Create encrypted volume
+    machine.wait_for_unit("multi-user.target")
+    machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
+    machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -")
+    machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen   -q               /dev/vdc cryptroot2")
+    machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2")
+
+    # Boot from the encrypted disk
+    machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf")
+    machine.succeed("sync")
+    machine.crash()
+
+    # Boot and decrypt the disk
+    machine.start()
+    machine.wait_for_text("Password required for booting")
+    machine.screenshot("prompt")
+    machine.send_chars("${passphrase}")
+    machine.screenshot("pw")
+    machine.send_chars("\n")
+    machine.wait_for_unit("multi-user.target")
+
+    assert "/dev/mapper/cryptroot on / type ext4" in machine.succeed("mount"), "/dev/mapper/cryptroot do not appear in mountpoints list"
+    assert "/dev/mapper/cryptroot2 on /cryptroot2 type ext4" in machine.succeed("mount")
+  '';
+})
diff --git a/nixpkgs/nixos/tests/systemd-timesyncd.nix b/nixpkgs/nixos/tests/systemd-timesyncd.nix
index f38d06be1516..02f49f49b8a5 100644
--- a/nixpkgs/nixos/tests/systemd-timesyncd.nix
+++ b/nixpkgs/nixos/tests/systemd-timesyncd.nix
@@ -15,13 +15,14 @@ in {
       # create the path that should be migrated by our activation script when
       # upgrading to a newer nixos version
       system.stateVersion = "19.03";
-      systemd.tmpfiles.rules = [
-        "r /var/lib/systemd/timesync -"
-        "d /var/lib/systemd -"
-        "d /var/lib/private/systemd/timesync -"
-        "L /var/lib/systemd/timesync - - - - /var/lib/private/systemd/timesync"
-        "d /var/lib/private/systemd/timesync - systemd-timesync systemd-timesync -"
-      ];
+      systemd.tmpfiles.settings.systemd-timesyncd-test = {
+        "/var/lib/systemd/timesync".R = { };
+        "/var/lib/systemd/timesync".L.argument = "/var/lib/private/systemd/timesync";
+        "/var/lib/private/systemd/timesync".d = {
+          user = "systemd-timesync";
+          group = "systemd-timesync";
+        };
+      };
     });
   };
 
diff --git a/nixpkgs/nixos/tests/telegraf.nix b/nixpkgs/nixos/tests/telegraf.nix
index c3cdb1645213..af9c5c387a5d 100644
--- a/nixpkgs/nixos/tests/telegraf.nix
+++ b/nixpkgs/nixos/tests/telegraf.nix
@@ -12,6 +12,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
     services.telegraf.extraConfig = {
       agent.interval = "1s";
       agent.flush_interval = "1s";
+      inputs.procstat = {};
       inputs.exec = {
         commands = [
           "${pkgs.runtimeShell} -c 'echo $SECRET,tag=a i=42i'"
diff --git a/nixpkgs/nixos/tests/terminal-emulators.nix b/nixpkgs/nixos/tests/terminal-emulators.nix
index b52801c898eb..2306c03c18e7 100644
--- a/nixpkgs/nixos/tests/terminal-emulators.nix
+++ b/nixpkgs/nixos/tests/terminal-emulators.nix
@@ -76,7 +76,7 @@ let tests = {
 
       rio.pkg = p: p.rio;
       rio.cmd = "rio -e $command";
-      rio.pinkValue = "#FF1261";
+      rio.colourTest = false; # the rendering is changing too much so colors change every release.
 
       roxterm.pkg = p: p.roxterm;
       roxterm.cmd = "roxterm -e $command";
diff --git a/nixpkgs/nixos/tests/tomcat.nix b/nixpkgs/nixos/tests/tomcat.nix
index a5f219e104ad..ff58ca8ac618 100644
--- a/nixpkgs/nixos/tests/tomcat.nix
+++ b/nixpkgs/nixos/tests/tomcat.nix
@@ -1,5 +1,6 @@
 import ./make-test-python.nix ({ pkgs, ... }: {
   name = "tomcat";
+  meta.maintainers = [ lib.maintainers.anthonyroussel ];
 
   nodes.machine = { pkgs, ... }: {
     services.tomcat = {
diff --git a/nixpkgs/nixos/tests/web-servers/stargazer.nix b/nixpkgs/nixos/tests/web-servers/stargazer.nix
index c522cfee5dbc..6365d6a4fff1 100644
--- a/nixpkgs/nixos/tests/web-servers/stargazer.nix
+++ b/nixpkgs/nixos/tests/web-servers/stargazer.nix
@@ -24,7 +24,7 @@
     geminiserver.wait_for_open_port(1965)
 
     with subtest("check is serving over gemini"):
-      response = geminiserver.succeed("${pkgs.gmni}/bin/gmni -j once -i -N gemini://localhost:1965")
+      response = geminiserver.succeed("${pkgs.gemget}/bin/gemget --header -o - gemini://localhost:1965")
       print(response)
       assert "Hello NixOS!" in response
   '';
diff --git a/nixpkgs/nixos/tests/xscreensaver.nix b/nixpkgs/nixos/tests/xscreensaver.nix
new file mode 100644
index 000000000000..820ddbb0e962
--- /dev/null
+++ b/nixpkgs/nixos/tests/xscreensaver.nix
@@ -0,0 +1,64 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }: {
+  name = "pass-secret-service";
+  meta.maintainers = with lib.maintainers; [ vancluever AndersonTorres ];
+
+  nodes = {
+    ok = { nodes, pkgs, ... }:
+      {
+        imports = [ ./common/x11.nix ./common/user-account.nix ];
+        test-support.displayManager.auto.user = "alice";
+        services.xscreensaver.enable = true;
+      };
+
+    empty_wrapperPrefix = { nodes, pkgs, ... }:
+      {
+        imports = [ ./common/x11.nix ./common/user-account.nix ];
+        test-support.displayManager.auto.user = "alice";
+        services.xscreensaver.enable = true;
+        nixpkgs.overlays = [
+          (self: super: {
+            xscreensaver = super.xscreensaver.override {
+              wrapperPrefix = "";
+            };
+          })
+        ];
+      };
+
+    bad_wrapperPrefix = { nodes, pkgs, ... }:
+      {
+        imports = [ ./common/x11.nix ./common/user-account.nix ];
+        test-support.displayManager.auto.user = "alice";
+        services.xscreensaver.enable = true;
+        nixpkgs.overlays = [
+          (self: super: {
+            xscreensaver = super.xscreensaver.override {
+              wrapperPrefix = "/a/bad/path";
+            };
+          })
+        ];
+      };
+  };
+
+  testScript = ''
+    ok.wait_for_x()
+    ok.wait_for_unit("xscreensaver", "alice")
+    _, output_ok = ok.systemctl("status xscreensaver", "alice")
+    assert 'To prevent the kernel from randomly unlocking' not in output_ok
+    assert 'your screen via the out-of-memory killer' not in output_ok
+    assert '"xscreensaver-auth" must be setuid root' not in output_ok
+
+    empty_wrapperPrefix.wait_for_x()
+    empty_wrapperPrefix.wait_for_unit("xscreensaver", "alice")
+    _, output_empty_wrapperPrefix = empty_wrapperPrefix.systemctl("status xscreensaver", "alice")
+    assert 'To prevent the kernel from randomly unlocking' in output_empty_wrapperPrefix
+    assert 'your screen via the out-of-memory killer' in output_empty_wrapperPrefix
+    assert '"xscreensaver-auth" must be setuid root' in output_empty_wrapperPrefix
+
+    bad_wrapperPrefix.wait_for_x()
+    bad_wrapperPrefix.wait_for_unit("xscreensaver", "alice")
+    _, output_bad_wrapperPrefix = bad_wrapperPrefix.systemctl("status xscreensaver", "alice")
+    assert 'To prevent the kernel from randomly unlocking' in output_bad_wrapperPrefix
+    assert 'your screen via the out-of-memory killer' in output_bad_wrapperPrefix
+    assert '"xscreensaver-auth" must be setuid root' in output_bad_wrapperPrefix
+  '';
+})
diff --git a/nixpkgs/nixos/tests/zfs.nix b/nixpkgs/nixos/tests/zfs.nix
index 3454fbaf78fe..ad4ea254f34d 100644
--- a/nixpkgs/nixos/tests/zfs.nix
+++ b/nixpkgs/nixos/tests/zfs.nix
@@ -13,6 +13,7 @@ let
                       else pkgs.linuxPackages
     , enableUnstable ? false
     , enableSystemdStage1 ? false
+    , zfsPackage ? if enableUnstable then pkgs.zfs else pkgs.zfsUnstable
     , extraTest ? ""
     }:
     makeTest {
@@ -21,7 +22,7 @@ let
         maintainers = [ adisbladis elvishjerricco ];
       };
 
-      nodes.machine = { pkgs, lib, ... }:
+      nodes.machine = { config, pkgs, lib, ... }:
         let
           usersharePath = "/var/lib/samba/usershares";
         in {
@@ -35,8 +36,8 @@ let
         boot.loader.efi.canTouchEfiVariables = true;
         networking.hostId = "deadbeef";
         boot.kernelPackages = kernelPackage;
+        boot.zfs.package = zfsPackage;
         boot.supportedFilesystems = [ "zfs" ];
-        boot.zfs.enableUnstable = enableUnstable;
         boot.initrd.systemd.enable = enableSystemdStage1;
 
         environment.systemPackages = [ pkgs.parted ];
@@ -193,6 +194,11 @@ let
 
 in {
 
+  # maintainer: @raitobezarius
+  series_2_1 = makeZfsTest "2.1-series" {
+    zfsPackage = pkgs.zfs_2_1;
+  };
+
   stable = makeZfsTest "stable" { };
 
   unstable = makeZfsTest "unstable" {