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.nix60
-rw-r--r--nixos/tests/all-tests.nix36
-rw-r--r--nixos/tests/cloud-init.nix1
-rw-r--r--nixos/tests/custom-ca.nix2
-rw-r--r--nixos/tests/domination.nix2
-rw-r--r--nixos/tests/endlessh-go.nix58
-rw-r--r--nixos/tests/grafana.nix9
-rw-r--r--nixos/tests/hydra/common.nix2
-rw-r--r--nixos/tests/installed-tests/default.nix1
-rw-r--r--nixos/tests/installed-tests/librsvg.nix9
-rw-r--r--nixos/tests/k3s/multi-node.nix25
-rw-r--r--nixos/tests/k3s/single-node.nix15
-rw-r--r--nixos/tests/karma.nix84
-rw-r--r--nixos/tests/kubernetes/base.nix4
-rw-r--r--nixos/tests/kubernetes/default.nix2
-rw-r--r--nixos/tests/kubernetes/e2e.nix40
-rw-r--r--nixos/tests/kubo.nix (renamed from nixos/tests/ipfs.nix)6
-rw-r--r--nixos/tests/ladybird.nix30
-rw-r--r--nixos/tests/matrix/mjolnir.nix1
-rw-r--r--nixos/tests/nscd.nix107
-rw-r--r--nixos/tests/oci-containers.nix2
-rw-r--r--nixos/tests/paperless.nix8
-rw-r--r--nixos/tests/pgadmin4.nix4
-rw-r--r--nixos/tests/plasma-bigscreen.nix38
-rw-r--r--nixos/tests/please.nix66
-rw-r--r--nixos/tests/printing.nix1
-rw-r--r--nixos/tests/prometheus-exporters.nix23
-rw-r--r--nixos/tests/pulseaudio.nix25
-rw-r--r--nixos/tests/resolv.nix46
-rw-r--r--nixos/tests/restic.nix4
-rw-r--r--nixos/tests/retroarch.nix4
-rw-r--r--nixos/tests/seafile.nix12
-rw-r--r--nixos/tests/spark/default.nix1
-rw-r--r--nixos/tests/sssd-ldap.nix7
-rw-r--r--nixos/tests/stratis/default.nix1
-rw-r--r--nixos/tests/stratis/encryption.nix33
-rw-r--r--nixos/tests/systemd-cryptenroll.nix1
-rw-r--r--nixos/tests/systemd-initrd-modprobe.nix17
-rw-r--r--nixos/tests/systemd-machinectl.nix3
-rw-r--r--nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix125
-rw-r--r--nixos/tests/systemd-oomd.nix55
-rw-r--r--nixos/tests/systemd.nix6
-rw-r--r--nixos/tests/tandoor-recipes.nix43
-rw-r--r--nixos/tests/terminal-emulators.nix8
-rw-r--r--nixos/tests/tmate-ssh-server.nix73
-rw-r--r--nixos/tests/tracee.nix46
-rw-r--r--nixos/tests/vengi-tools.nix4
-rw-r--r--nixos/tests/vscodium.nix6
-rw-r--r--nixos/tests/wine.nix5
-rw-r--r--nixos/tests/xpadneo.nix18
50 files changed, 946 insertions, 233 deletions
diff --git a/nixos/tests/acme.nix b/nixos/tests/acme.nix
index d3a436080ebff..d540bc6ec31bb 100644
--- a/nixos/tests/acme.nix
+++ b/nixos/tests/acme.nix
@@ -41,6 +41,16 @@
     inherit documentRoot;
   };
 
+  simpleConfig = {
+    security.acme = {
+      certs."http.example.test" = {
+        listenHTTP = ":80";
+      };
+    };
+
+    networking.firewall.allowedTCPPorts = [ 80 ];
+  };
+
   # Base specialisation config for testing general ACME features
   webserverBasicConfig = {
     services.nginx.enable = true;
@@ -173,6 +183,26 @@ in {
       services.nginx.logError = "stderr info";
 
       specialisation = {
+        # Tests HTTP-01 verification using Lego's built-in web server
+        http01lego.configuration = simpleConfig;
+
+        renew.configuration = lib.mkMerge [
+          simpleConfig
+          {
+            # Pebble provides 5 year long certs,
+            # needs to be higher than that to test renewal
+            security.acme.certs."http.example.test".validMinDays = 9999;
+          }
+        ];
+
+        # Tests that account creds can be safely changed.
+        accountchange.configuration = lib.mkMerge [
+          simpleConfig
+          {
+            security.acme.certs."http.example.test".email = "admin@example.test";
+          }
+        ];
+
         # First derivation used to test general ACME features
         general.configuration = { ... }: let
           caDomain = nodes.acme.test-support.acme.caDomain;
@@ -446,7 +476,35 @@ in {
 
       download_ca_certs(client)
 
-      # Perform general tests first
+      # Perform http-01 w/ lego test first
+      with subtest("Can request certificate with Lego's built in web server"):
+          switch_to(webserver, "http01lego")
+          webserver.wait_for_unit("acme-finished-http.example.test.target")
+          check_fullchain(webserver, "http.example.test")
+          check_issuer(webserver, "http.example.test", "pebble")
+
+      # Perform renewal test
+      with subtest("Can renew certificates when they expire"):
+          hash = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
+          switch_to(webserver, "renew")
+          webserver.wait_for_unit("acme-finished-http.example.test.target")
+          check_fullchain(webserver, "http.example.test")
+          check_issuer(webserver, "http.example.test", "pebble")
+          hash_after = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
+          assert hash != hash_after
+
+      # Perform account change test
+      with subtest("Handles email change correctly"):
+          hash = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
+          switch_to(webserver, "accountchange")
+          webserver.wait_for_unit("acme-finished-http.example.test.target")
+          check_fullchain(webserver, "http.example.test")
+          check_issuer(webserver, "http.example.test", "pebble")
+          hash_after = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
+          # Has to do a full run to register account, which creates new certs.
+          assert hash != hash_after
+
+      # Perform general tests
       switch_to(webserver, "general")
 
       with subtest("Can request certificate with HTTP-01 challenge"):
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 011d7b11b4f86..32342510f70f4 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -117,9 +117,9 @@ in {
   ceph-single-node = handleTestOn ["x86_64-linux"] ./ceph-single-node.nix {};
   ceph-single-node-bluestore = handleTestOn ["x86_64-linux"] ./ceph-single-node-bluestore.nix {};
   certmgr = handleTest ./certmgr.nix {};
-  cfssl = handleTestOn ["x86_64-linux"] ./cfssl.nix {};
+  cfssl = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cfssl.nix {};
   charliecloud = handleTest ./charliecloud.nix {};
-  chromium = (handleTestOn ["x86_64-linux"] ./chromium.nix {}).stable or {};
+  chromium = (handleTestOn ["aarch64-linux" "x86_64-linux"] ./chromium.nix {}).stable or {};
   cinnamon = handleTest ./cinnamon.nix {};
   cjdns = handleTest ./cjdns.nix {};
   clickhouse = handleTest ./clickhouse.nix {};
@@ -147,7 +147,7 @@ in {
   corerad = handleTest ./corerad.nix {};
   coturn = handleTest ./coturn.nix {};
   couchdb = handleTest ./couchdb.nix {};
-  cri-o = handleTestOn ["x86_64-linux"] ./cri-o.nix {};
+  cri-o = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cri-o.nix {};
   custom-ca = handleTest ./custom-ca.nix {};
   croc = handleTest ./croc.nix {};
   deluge = handleTest ./deluge.nix {};
@@ -160,8 +160,8 @@ in {
   dnscrypt-wrapper = handleTestOn ["x86_64-linux"] ./dnscrypt-wrapper {};
   dnsdist = handleTest ./dnsdist.nix {};
   doas = handleTest ./doas.nix {};
-  docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
-  docker-rootless = handleTestOn ["x86_64-linux"] ./docker-rootless.nix {};
+  docker = handleTestOn ["aarch64-linux" "x86_64-linux"] ./docker.nix {};
+  docker-rootless = handleTestOn ["aarch64-linux" "x86_64-linux"] ./docker-rootless.nix {};
   docker-registry = handleTest ./docker-registry.nix {};
   docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {};
   docker-tools-cross = handleTestOn ["x86_64-linux" "aarch64-linux"] ./docker-tools-cross.nix {};
@@ -180,6 +180,7 @@ in {
   ejabberd = handleTest ./xmpp/ejabberd.nix {};
   elk = handleTestOn ["x86_64-linux"] ./elk.nix {};
   emacs-daemon = handleTest ./emacs-daemon.nix {};
+  endlessh-go = handleTest ./endlessh-go.nix {};
   engelsystem = handleTest ./engelsystem.nix {};
   enlightenment = handleTest ./enlightenment.nix {};
   env = handleTest ./env.nix {};
@@ -252,7 +253,7 @@ in {
   herbstluftwm = handleTest ./herbstluftwm.nix {};
   installed-tests = pkgs.recurseIntoAttrs (handleTest ./installed-tests {});
   invidious = handleTest ./invidious.nix {};
-  oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {};
+  oci-containers = handleTestOn ["aarch64-linux" "x86_64-linux"] ./oci-containers.nix {};
   odoo = handleTest ./odoo.nix {};
   # 9pnet_virtio used to mount /nix partition doesn't support
   # hibernation. This test happens to work on x86_64-linux but
@@ -284,7 +285,6 @@ in {
   installer-systemd-stage-1 = handleTest ./installer-systemd-stage-1.nix {};
   invoiceplane = handleTest ./invoiceplane.nix {};
   iodine = handleTest ./iodine.nix {};
-  ipfs = handleTest ./ipfs.nix {};
   ipv6 = handleTest ./ipv6.nix {};
   iscsi-multipath-root = handleTest ./iscsi-multipath-root.nix {};
   iscsi-root = handleTest ./iscsi-root.nix {};
@@ -299,6 +299,7 @@ in {
   k3s = handleTest ./k3s {};
   kafka = handleTest ./kafka.nix {};
   kanidm = handleTest ./kanidm.nix {};
+  karma = handleTest ./karma.nix {};
   kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {};
   kbd-update-search-paths-patch = handleTest ./kbd-update-search-paths-patch.nix {};
   kea = handleTest ./kea.nix {};
@@ -317,6 +318,8 @@ in {
   ksm = handleTest ./ksm.nix {};
   kthxbye = handleTest ./kthxbye.nix {};
   kubernetes = handleTestOn ["x86_64-linux"] ./kubernetes {};
+  kubo = handleTest ./kubo.nix {};
+  ladybird = handleTest ./ladybird.nix {};
   languagetool = handleTest ./languagetool.nix {};
   latestKernel.login = handleTest ./login.nix { latestKernel = true; };
   leaps = handleTest ./leaps.nix {};
@@ -439,6 +442,7 @@ in {
   non-default-filesystems = handleTest ./non-default-filesystems.nix {};
   noto-fonts = handleTest ./noto-fonts.nix {};
   novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {};
+  nscd = handleTest ./nscd.nix {};
   nsd = handleTest ./nsd.nix {};
   nzbget = handleTest ./nzbget.nix {};
   nzbhydra2 = handleTest ./nzbhydra2.nix {};
@@ -484,16 +488,18 @@ in {
   phylactery = handleTest ./web-apps/phylactery.nix {};
   pict-rs = handleTest ./pict-rs.nix {};
   pinnwand = handleTest ./pinnwand.nix {};
+  plasma-bigscreen = handleTest ./plasma-bigscreen.nix {};
   plasma5 = handleTest ./plasma5.nix {};
   plasma5-systemd-start = handleTest ./plasma5-systemd-start.nix {};
   plausible = handleTest ./plausible.nix {};
+  please = handleTest ./please.nix {};
   pleroma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./pleroma.nix {};
   plikd = handleTest ./plikd.nix {};
   plotinus = handleTest ./plotinus.nix {};
   podgrab = handleTest ./podgrab.nix {};
-  podman = handleTestOn ["x86_64-linux"] ./podman/default.nix {};
-  podman-dnsname = handleTestOn ["x86_64-linux"] ./podman/dnsname.nix {};
-  podman-tls-ghostunnel = handleTestOn ["x86_64-linux"] ./podman/tls-ghostunnel.nix {};
+  podman = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/default.nix {};
+  podman-dnsname = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/dnsname.nix {};
+  podman-tls-ghostunnel = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/tls-ghostunnel.nix {};
   polaris = handleTest ./polaris.nix {};
   pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {};
   postfix = handleTest ./postfix.nix {};
@@ -528,7 +534,6 @@ in {
   rasdaemon = handleTest ./rasdaemon.nix {};
   redis = handleTest ./redis.nix {};
   redmine = handleTest ./redmine.nix {};
-  resolv = handleTest ./resolv.nix {};
   restartByActivationScript = handleTest ./restart-by-activation-script.nix {};
   restic = handleTest ./restic.nix {};
   retroarch = handleTest ./retroarch.nix {};
@@ -596,6 +601,7 @@ in {
   systemd-initrd-btrfs-raid = handleTest ./systemd-initrd-btrfs-raid.nix {};
   systemd-initrd-luks-keyfile = handleTest ./systemd-initrd-luks-keyfile.nix {};
   systemd-initrd-luks-password = handleTest ./systemd-initrd-luks-password.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 {};
   systemd-initrd-swraid = handleTest ./systemd-initrd-swraid.nix {};
@@ -611,6 +617,7 @@ in {
   systemd-shutdown = handleTest ./systemd-shutdown.nix {};
   systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
   systemd-misc = handleTest ./systemd-misc.nix {};
+  tandoor-recipes = handleTest ./tandoor-recipes.nix {};
   taskserver = handleTest ./taskserver.nix {};
   teeworlds = handleTest ./teeworlds.nix {};
   telegraf = handleTest ./telegraf.nix {};
@@ -623,12 +630,14 @@ in {
   tinc = handleTest ./tinc {};
   tinydns = handleTest ./tinydns.nix {};
   tinywl = handleTest ./tinywl.nix {};
+  tmate-ssh-server = handleTest ./tmate-ssh-server.nix { };
   tomcat = handleTest ./tomcat.nix {};
   tor = handleTest ./tor.nix {};
-  # traefik test relies on docker-containers
-  traefik = handleTestOn ["x86_64-linux"] ./traefik.nix {};
+  traefik = handleTestOn ["aarch64-linux" "x86_64-linux"] ./traefik.nix {};
   trafficserver = handleTest ./trafficserver.nix {};
   transmission = handleTest ./transmission.nix {};
+  # tracee requires bpf
+  tracee = handleTestOn ["x86_64-linux"] ./tracee.nix {};
   trezord = handleTest ./trezord.nix {};
   trickster = handleTest ./trickster.nix {};
   trilium-server = handleTestOn ["x86_64-linux"] ./trilium-server.nix {};
@@ -677,6 +686,7 @@ in {
   xfce = handleTest ./xfce.nix {};
   xmonad = handleTest ./xmonad.nix {};
   xmonad-xdg-autostart = handleTest ./xmonad-xdg-autostart.nix {};
+  xpadneo = handleTest ./xpadneo.nix {};
   xrdp = handleTest ./xrdp.nix {};
   xss-lock = handleTest ./xss-lock.nix {};
   xterm = handleTest ./xterm.nix {};
diff --git a/nixos/tests/cloud-init.nix b/nixos/tests/cloud-init.nix
index 9feb8d5c1526e..a86cd569e4215 100644
--- a/nixos/tests/cloud-init.nix
+++ b/nixos/tests/cloud-init.nix
@@ -60,6 +60,7 @@ in makeTest {
   name = "cloud-init";
   meta = with pkgs.lib.maintainers; {
     maintainers = [ lewo ];
+    broken = true; # almost always times out after spending many hours
   };
   nodes.machine = { ... }:
   {
diff --git a/nixos/tests/custom-ca.nix b/nixos/tests/custom-ca.nix
index 73e47c3c9d0d6..25a7b6fdea46e 100644
--- a/nixos/tests/custom-ca.nix
+++ b/nixos/tests/custom-ca.nix
@@ -191,5 +191,5 @@ in
   firefox = { error = "Security Risk"; };
   chromium = { error = "not private"; };
   qutebrowser = { args = "-T"; error = "Certificate error"; };
-  midori = { error = "Security"; };
+  midori = { args = "-p"; error = "Security"; };
 }
diff --git a/nixos/tests/domination.nix b/nixos/tests/domination.nix
index 09027740ab8de..409a7f3029c42 100644
--- a/nixos/tests/domination.nix
+++ b/nixos/tests/domination.nix
@@ -20,7 +20,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
       machine.wait_for_x()
       machine.execute("domination >&2 &")
       machine.wait_for_window("Menu")
-      machine.wait_for_text("New Game")
+      machine.wait_for_text(r"(New Game|Start Server|Load Game|Help Manual|Join Game|About|Play Online)")
       machine.screenshot("screen")
     '';
 })
diff --git a/nixos/tests/endlessh-go.nix b/nixos/tests/endlessh-go.nix
new file mode 100644
index 0000000000000..b261dbf1c5605
--- /dev/null
+++ b/nixos/tests/endlessh-go.nix
@@ -0,0 +1,58 @@
+import ./make-test-python.nix ({ lib, pkgs, ... }:
+{
+  name = "endlessh-go";
+  meta.maintainers = with lib.maintainers; [ azahi ];
+
+  nodes = {
+    server = { ... }: {
+      services.endlessh-go = {
+        enable = true;
+        prometheus.enable = true;
+        openFirewall = true;
+      };
+
+      specialisation = {
+        unprivileged.configuration = {
+          services.endlessh-go = {
+            port = 2222;
+            prometheus.port = 9229;
+          };
+        };
+
+        privileged.configuration = {
+          services.endlessh-go = {
+            port = 22;
+            prometheus.port = 92;
+          };
+        };
+      };
+    };
+
+    client = { pkgs, ... }: {
+      environment.systemPackages = with pkgs; [ curl netcat ];
+    };
+  };
+
+  testScript = ''
+    def activate_specialisation(name: str):
+        server.succeed(f"/run/booted-system/specialisation/{name}/bin/switch-to-configuration test >&2")
+
+    start_all()
+
+    with subtest("Unprivileged"):
+        activate_specialisation("unprivileged")
+        server.wait_for_unit("endlessh-go.service")
+        server.wait_for_open_port(2222)
+        server.wait_for_open_port(9229)
+        client.succeed("nc -dvW5 server 2222")
+        client.succeed("curl -kv server:9229/metrics")
+
+    with subtest("Privileged"):
+        activate_specialisation("privileged")
+        server.wait_for_unit("endlessh-go.service")
+        server.wait_for_open_port(22)
+        server.wait_for_open_port(92)
+        client.succeed("nc -dvW5 server 22")
+        client.succeed("curl -kv server:92/metrics")
+  '';
+})
diff --git a/nixos/tests/grafana.nix b/nixos/tests/grafana.nix
index 174d664d8772b..5364f0ca8b0b4 100644
--- a/nixos/tests/grafana.nix
+++ b/nixos/tests/grafana.nix
@@ -81,8 +81,11 @@ in {
     with subtest("Successful API query as admin user with sqlite db"):
         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"
+        ))
         sqlite.succeed(
-            "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep testadmin\@localhost"
+            "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost"
         )
         sqlite.shutdown()
 
@@ -92,7 +95,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 testadmin\@localhost"
+            "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost"
         )
         postgresql.shutdown()
 
@@ -102,7 +105,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 testadmin\@localhost"
+            "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost"
         )
         mysql.shutdown()
   '';
diff --git a/nixos/tests/hydra/common.nix b/nixos/tests/hydra/common.nix
index fdf2b2c6f6dc1..2bce03418e1ff 100644
--- a/nixos/tests/hydra/common.nix
+++ b/nixos/tests/hydra/common.nix
@@ -16,7 +16,7 @@
     createTrivialProject = pkgs.stdenv.mkDerivation {
       name = "create-trivial-project";
       dontUnpack = true;
-      buildInputs = [ pkgs.makeWrapper ];
+      nativeBuildInputs = [ pkgs.makeWrapper ];
       installPhase = "install -m755 -D ${./create-trivial-project.sh} $out/bin/create-trivial-project.sh";
       postFixup = ''
         wrapProgram "$out/bin/create-trivial-project.sh" --prefix PATH ":" ${pkgs.lib.makeBinPath [ pkgs.curl ]} --set EXPR_PATH ${trivialJob}
diff --git a/nixos/tests/installed-tests/default.nix b/nixos/tests/installed-tests/default.nix
index b2c1b43f90ee9..2e38cd389c74a 100644
--- a/nixos/tests/installed-tests/default.nix
+++ b/nixos/tests/installed-tests/default.nix
@@ -101,7 +101,6 @@ in
   json-glib = callInstalledTest ./json-glib.nix {};
   ibus = callInstalledTest ./ibus.nix {};
   libgdata = callInstalledTest ./libgdata.nix {};
-  librsvg = callInstalledTest ./librsvg.nix {};
   glib-testing = callInstalledTest ./glib-testing.nix {};
   libjcat = callInstalledTest ./libjcat.nix {};
   libxmlb = callInstalledTest ./libxmlb.nix {};
diff --git a/nixos/tests/installed-tests/librsvg.nix b/nixos/tests/installed-tests/librsvg.nix
deleted file mode 100644
index 378e7cce3ff4c..0000000000000
--- a/nixos/tests/installed-tests/librsvg.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-{ pkgs, makeInstalledTest, ... }:
-
-makeInstalledTest {
-  tested = pkgs.librsvg;
-
-  testConfig = {
-    virtualisation.memorySize = 2047;
-  };
-}
diff --git a/nixos/tests/k3s/multi-node.nix b/nixos/tests/k3s/multi-node.nix
index ae9609fbccc9f..ce7e4b6ead148 100644
--- a/nixos/tests/k3s/multi-node.nix
+++ b/nixos/tests/k3s/multi-node.nix
@@ -1,4 +1,4 @@
-import ../make-test-python.nix ({ pkgs, ... }:
+import ../make-test-python.nix ({ pkgs, lib, ... }:
   let
     imageEnv = pkgs.buildEnv {
       name = "k3s-pause-image-env";
@@ -54,7 +54,15 @@ import ../make-test-python.nix ({ pkgs, ... }:
           role = "server";
           package = pkgs.k3s;
           clusterInit = true;
-          extraFlags = "--no-deploy coredns,servicelb,traefik,local-storage,metrics-server --pause-image test.local/pause:local --node-ip 192.168.1.1";
+          extraFlags = ''
+            --disable coredns \
+            --disable local-storage \
+            --disable metrics-server \
+            --disable servicelb \
+            --disable traefik \
+            --node-ip 192.168.1.1 \
+            --pause-image test.local/pause:local
+          '';
         };
         networking.firewall.allowedTCPPorts = [ 2379 2380 6443 ];
         networking.firewall.allowedUDPPorts = [ 8472 ];
@@ -76,7 +84,15 @@ import ../make-test-python.nix ({ pkgs, ... }:
           enable = true;
           serverAddr = "https://192.168.1.1:6443";
           clusterInit = false;
-          extraFlags = "--no-deploy coredns,servicelb,traefik,local-storage,metrics-server --pause-image test.local/pause:local --node-ip 192.168.1.3";
+          extraFlags = ''
+            --disable coredns \
+            --disable local-storage \
+            --disable metrics-server \
+            --disable servicelb \
+            --disable traefik \
+            --node-ip 192.168.1.3 \
+            --pause-image test.local/pause:local
+          '';
         };
         networking.firewall.allowedTCPPorts = [ 2379 2380 6443 ];
         networking.firewall.allowedUDPPorts = [ 8472 ];
@@ -123,7 +139,8 @@ import ../make-test-python.nix ({ pkgs, ... }:
       server.wait_until_succeeds("k3s kubectl get node agent")
 
       for m in machines:
-          m.succeed("k3s check-config")
+      '' # Fix-Me: Tests fail for 'aarch64-linux' as: "CONFIG_CGROUP_FREEZER: missing (fail)"
+      + lib.optionalString (!pkgs.stdenv.isAarch64) ''m.succeed("k3s check-config")'' + ''
           m.succeed(
               "${pauseImage} | k3s ctr image import -"
           )
diff --git a/nixos/tests/k3s/single-node.nix b/nixos/tests/k3s/single-node.nix
index 27e1e455e6415..ab562500f5d21 100644
--- a/nixos/tests/k3s/single-node.nix
+++ b/nixos/tests/k3s/single-node.nix
@@ -1,4 +1,4 @@
-import ../make-test-python.nix ({ pkgs, ... }:
+import ../make-test-python.nix ({ pkgs, lib, ... }:
   let
     imageEnv = pkgs.buildEnv {
       name = "k3s-pause-image-env";
@@ -40,7 +40,15 @@ import ../make-test-python.nix ({ pkgs, ... }:
       services.k3s.role = "server";
       services.k3s.package = pkgs.k3s;
       # Slightly reduce resource usage
-      services.k3s.extraFlags = "--no-deploy coredns,servicelb,traefik,local-storage,metrics-server --pause-image test.local/pause:local";
+      services.k3s.extraFlags = ''
+        --disable coredns \
+        --disable local-storage \
+        --disable metrics-server \
+        --disable servicelb \
+        --disable traefik \
+        --pause-image \
+        test.local/pause:local
+      '';
 
       users.users = {
         noprivs = {
@@ -57,7 +65,8 @@ import ../make-test-python.nix ({ pkgs, ... }:
       machine.wait_for_unit("k3s")
       machine.succeed("k3s kubectl cluster-info")
       machine.fail("sudo -u noprivs k3s kubectl cluster-info")
-      machine.succeed("k3s check-config")
+      '' # Fix-Me: Tests fail for 'aarch64-linux' as: "CONFIG_CGROUP_FREEZER: missing (fail)"
+      + lib.optionalString (!pkgs.stdenv.isAarch64) ''machine.succeed("k3s check-config")'' + ''
 
       machine.succeed(
           "${pauseImage} | k3s ctr image import -"
diff --git a/nixos/tests/karma.nix b/nixos/tests/karma.nix
new file mode 100644
index 0000000000000..5ac2983b8aa3e
--- /dev/null
+++ b/nixos/tests/karma.nix
@@ -0,0 +1,84 @@
+import ./make-test-python.nix ({ lib, pkgs, ... }: {
+  name = "karma";
+  nodes = {
+    server = { ... }: {
+      services.prometheus.alertmanager = {
+        enable = true;
+        logLevel = "debug";
+        port = 9093;
+        openFirewall = true;
+        configuration = {
+          global = {
+            resolve_timeout = "1m";
+          };
+          route = {
+            # Root route node
+            receiver = "test";
+            group_by = ["..."];
+            continue = false;
+            group_wait = "1s";
+            group_interval="15s";
+            repeat_interval = "24h";
+          };
+          receivers = [
+            {
+              name = "test";
+              webhook_configs = [
+                {
+                  url = "http://localhost:1234";
+                  send_resolved = true;
+                  max_alerts = 0;
+                }
+              ];
+            }
+          ];
+        };
+      };
+      services.karma = {
+        enable = true;
+        openFirewall = true;
+        settings = {
+          listen = {
+            address = "0.0.0.0";
+            port = 8081;
+          };
+          alertmanager = {
+            servers = [
+              {
+                name = "alertmanager";
+                uri = "https://127.0.0.1:9093";
+              }
+            ];
+          };
+          karma.name = "test-dashboard";
+          log.config = true;
+          log.requests = true;
+          log.timestamp = true;
+        };
+      };
+    };
+  };
+
+  testScript = ''
+    start_all()
+
+    with subtest("Wait for server to come up"):
+
+      server.wait_for_unit("alertmanager.service")
+      server.wait_for_unit("karma.service")
+
+      server.sleep(5) # wait for both services to settle
+
+      server.wait_for_open_port(9093)
+      server.wait_for_open_port(8081)
+
+    with subtest("Test alertmanager readiness"):
+      server.succeed("curl -s http://127.0.0.1:9093/-/ready")
+
+      # Karma only starts serving the dashboard once it has established connectivity to all alertmanagers in its config
+      # Therefore, this will fail if karma isn't able to reach alertmanager
+      server.succeed("curl -s http://127.0.0.1:8081")
+
+    server.shutdown()
+  '';
+})
diff --git a/nixos/tests/kubernetes/base.nix b/nixos/tests/kubernetes/base.nix
index d4410beb937e6..ba7b2d9b1d2de 100644
--- a/nixos/tests/kubernetes/base.nix
+++ b/nixos/tests/kubernetes/base.nix
@@ -18,7 +18,7 @@ let
         ${master.ip}  api.${domain}
         ${concatMapStringsSep "\n" (machineName: "${machines.${machineName}.ip}  ${machineName}.${domain}") (attrNames machines)}
       '';
-      wrapKubectl = with pkgs; runCommand "wrap-kubectl" { buildInputs = [ makeWrapper ]; } ''
+      wrapKubectl = with pkgs; runCommand "wrap-kubectl" { nativeBuildInputs = [ makeWrapper ]; } ''
         mkdir -p $out/bin
         makeWrapper ${pkgs.kubernetes}/bin/kubectl $out/bin/kubectl --set KUBECONFIG "/etc/kubernetes/cluster-admin.kubeconfig"
       '';
@@ -43,7 +43,7 @@ let
                   trustedInterfaces = ["mynet"];
 
                   extraCommands = concatMapStrings  (node: ''
-                    iptables -A INPUT -s ${node.config.networking.primaryIPAddress} -j ACCEPT
+                    iptables -A INPUT -s ${node.networking.primaryIPAddress} -j ACCEPT
                   '') (attrValues nodes);
                 };
               };
diff --git a/nixos/tests/kubernetes/default.nix b/nixos/tests/kubernetes/default.nix
index 60ba482758fbe..a3de9ed115d4c 100644
--- a/nixos/tests/kubernetes/default.nix
+++ b/nixos/tests/kubernetes/default.nix
@@ -4,8 +4,6 @@
 let
   dns = import ./dns.nix { inherit system pkgs; };
   rbac = import ./rbac.nix { inherit system pkgs; };
-  # TODO kubernetes.e2e should eventually replace kubernetes.rbac when it works
-  # e2e = import ./e2e.nix { inherit system pkgs; };
 in
 {
   dns-single-node = dns.singlenode.test;
diff --git a/nixos/tests/kubernetes/e2e.nix b/nixos/tests/kubernetes/e2e.nix
deleted file mode 100644
index fb29d9cc6953f..0000000000000
--- a/nixos/tests/kubernetes/e2e.nix
+++ /dev/null
@@ -1,40 +0,0 @@
-{ system ? builtins.currentSystem, pkgs ? import ../../.. { inherit system; } }:
-with import ./base.nix { inherit system; };
-let
-  domain = "my.zyx";
-  certs = import ./certs.nix { externalDomain = domain; kubelets = ["machine1" "machine2"]; };
-  kubeconfig = pkgs.writeText "kubeconfig.json" (builtins.toJSON {
-    apiVersion = "v1";
-    kind = "Config";
-    clusters = [{
-      name = "local";
-      cluster.certificate-authority = "${certs.master}/ca.pem";
-      cluster.server = "https://api.${domain}";
-    }];
-    users = [{
-      name = "kubelet";
-      user = {
-        client-certificate = "${certs.admin}/admin.pem";
-        client-key = "${certs.admin}/admin-key.pem";
-      };
-    }];
-    contexts = [{
-      context = {
-        cluster = "local";
-        user = "kubelet";
-      };
-      current-context = "kubelet-context";
-    }];
-  });
-
-  base = {
-    name = "e2e";
-    inherit domain certs;
-    test = ''
-      $machine1->succeed("e2e.test -kubeconfig ${kubeconfig} -provider local -ginkgo.focus '\\[Conformance\\]' -ginkgo.skip '\\[Flaky\\]|\\[Serial\\]'");
-    '';
-  };
-in {
-  singlenode = mkKubernetesSingleNodeTest base;
-  multinode = mkKubernetesMultiNodeTest base;
-}
diff --git a/nixos/tests/ipfs.nix b/nixos/tests/kubo.nix
index 024822745ada5..e84a873a1a18d 100644
--- a/nixos/tests/ipfs.nix
+++ b/nixos/tests/kubo.nix
@@ -1,11 +1,11 @@
 import ./make-test-python.nix ({ pkgs, ...} : {
-  name = "ipfs";
+  name = "kubo";
   meta = with pkgs.lib.maintainers; {
     maintainers = [ mguentner ];
   };
 
   nodes.machine = { ... }: {
-    services.ipfs = {
+    services.kubo = {
       enable = true;
       # Also will add a unix domain socket socket API address, see module.
       startWhenNeeded = true;
@@ -15,7 +15,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
   };
 
   nodes.fuse = { ... }: {
-    services.ipfs = {
+    services.kubo = {
       enable = true;
       apiAddress = "/ip4/127.0.0.1/tcp/2324";
       autoMount = true;
diff --git a/nixos/tests/ladybird.nix b/nixos/tests/ladybird.nix
new file mode 100644
index 0000000000000..4e9ab9a36d137
--- /dev/null
+++ b/nixos/tests/ladybird.nix
@@ -0,0 +1,30 @@
+import ./make-test-python.nix ({ pkgs, ... }: {
+  name = "ladybird";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ fgaz ];
+  };
+
+  nodes.machine = { config, pkgs, ... }: {
+    imports = [
+      ./common/x11.nix
+    ];
+
+    services.xserver.enable = true;
+    environment.systemPackages = [
+      pkgs.ladybird
+    ];
+  };
+
+  enableOCR = true;
+
+  testScript =
+    ''
+      machine.wait_for_x()
+      machine.succeed("echo '<!DOCTYPE html><html><body><h1>Hello world</h1></body></html>' > page.html")
+      machine.execute("ladybird file://$(pwd)/page.html >&2 &")
+      machine.wait_for_window("Ladybird")
+      machine.sleep(5)
+      machine.wait_for_text("Hello world")
+      machine.screenshot("screen")
+    '';
+})
diff --git a/nixos/tests/matrix/mjolnir.nix b/nixos/tests/matrix/mjolnir.nix
index cb843e2e9e3e8..b1ac55d951cef 100644
--- a/nixos/tests/matrix/mjolnir.nix
+++ b/nixos/tests/matrix/mjolnir.nix
@@ -32,6 +32,7 @@ import ../make-test-python.nix (
     name = "mjolnir";
     meta = with pkgs.lib; {
       maintainers = teams.matrix.members;
+      broken = true; # times out after spending many hours
     };
 
     nodes = {
diff --git a/nixos/tests/nscd.nix b/nixos/tests/nscd.nix
new file mode 100644
index 0000000000000..7bb6d90c3d4e0
--- /dev/null
+++ b/nixos/tests/nscd.nix
@@ -0,0 +1,107 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+let
+  # build a getent that itself doesn't see anything in /etc/hosts and
+  # /etc/nsswitch.conf, by using libredirect to steer its own requests to
+  # /dev/null.
+  # This means is /has/ to go via nscd to actuallly resolve any of the
+  # additionally configured hosts.
+  getent' = pkgs.writeScript "getent-without-etc-hosts" ''
+    export NIX_REDIRECTS=/etc/hosts=/dev/null:/etc/nsswitch.conf=/dev/null
+    export LD_PRELOAD=${pkgs.libredirect}/lib/libredirect.so
+    exec getent $@
+  '';
+in
+{
+  name = "nscd";
+
+  nodes.machine = { pkgs, ... }: {
+    imports = [ common/user-account.nix ];
+    networking.extraHosts = ''
+      2001:db8::1 somehost.test
+      192.0.2.1 somehost.test
+    '';
+
+    specialisation = {
+      withUnscd.configuration = { ... }: {
+        services.nscd.package = pkgs.unscd;
+      };
+    };
+  };
+
+  testScript = { nodes, ... }:
+    let
+      specialisations = "${nodes.machine.system.build.toplevel}/specialisation";
+    in
+    ''
+      # Regression test for https://github.com/NixOS/nixpkgs/issues/50273
+      def test_dynamic_user():
+          with subtest("DynamicUser actually allocates a user"):
+              assert "iamatest" in machine.succeed(
+                  "systemd-run --pty --property=Type=oneshot --property=DynamicUser=yes --property=User=iamatest whoami"
+              )
+
+      # Test resolution of somehost.test with getent', to make sure we go via nscd
+      def test_host_lookups():
+          with subtest("host lookups via nscd"):
+              # ahosts
+              output = machine.succeed("${getent'} ahosts somehost.test")
+              assert "192.0.2.1" in output
+              assert "2001:db8::1" in output
+
+              # ahostsv4
+              output = machine.succeed("${getent'} ahostsv4 somehost.test")
+              assert "192.0.2.1" in output
+              assert "2001:db8::1" not in output
+
+              # ahostsv6
+              output = machine.succeed("${getent'} ahostsv6 somehost.test")
+              assert "192.0.2.1" not in output
+              assert "2001:db8::1" in output
+
+              # reverse lookups (hosts)
+              assert "somehost.test" in machine.succeed("${getent'} hosts 2001:db8::1")
+              assert "somehost.test" in machine.succeed("${getent'} hosts 192.0.2.1")
+
+      # Test host resolution via nss modules works
+      # We rely on nss-myhostname in this case, which resolves *.localhost and
+      # _gateway.
+      # We don't need to use getent' here, as non-glibc nss modules can only be
+      # discovered via nscd.
+      def test_nss_myhostname():
+          with subtest("nss-myhostname provides hostnames (ahosts)"):
+              # ahosts
+              output = machine.succeed("getent ahosts foobar.localhost")
+              assert "::1" in output
+              assert "127.0.0.1" in output
+
+              # ahostsv4
+              output = machine.succeed("getent ahostsv4 foobar.localhost")
+              assert "::1" not in output
+              assert "127.0.0.1" in output
+
+              # ahostsv6
+              output = machine.succeed("getent ahostsv6 foobar.localhost")
+              assert "::1" in output
+              assert "127.0.0.1" not in output
+
+      start_all()
+      machine.wait_for_unit("default.target")
+
+      # Test all tests with glibc-nscd.
+      test_dynamic_user()
+      test_host_lookups()
+      test_nss_myhostname()
+
+      with subtest("unscd"):
+          machine.succeed('${specialisations}/withUnscd/bin/switch-to-configuration test')
+          machine.wait_for_unit("default.target")
+
+          # known to fail, unscd doesn't load external NSS modules
+          # test_dynamic_user()
+
+          test_host_lookups()
+
+          # known to fail, unscd doesn't load external NSS modules
+          # test_nss_myhostname()
+    '';
+})
diff --git a/nixos/tests/oci-containers.nix b/nixos/tests/oci-containers.nix
index 68077e3540a5e..1bcfb276dbeea 100644
--- a/nixos/tests/oci-containers.nix
+++ b/nixos/tests/oci-containers.nix
@@ -12,7 +12,7 @@ let
     name = "oci-containers-${backend}";
 
     meta = {
-      maintainers = with lib.maintainers; [ adisbladis benley ] ++ lib.teams.serokell.members;
+      maintainers = with lib.maintainers; [ adisbladis benley mkaito ] ++ lib.teams.serokell.members;
     };
 
     nodes = {
diff --git a/nixos/tests/paperless.nix b/nixos/tests/paperless.nix
index 12883cd62c60c..b97834835c2c9 100644
--- a/nixos/tests/paperless.nix
+++ b/nixos/tests/paperless.nix
@@ -40,5 +40,13 @@ import ./make-test-python.nix ({ lib, ... }: {
         docs = json.loads(machine.succeed("curl -u admin:admin -fs localhost:28981/api/documents/"))['results']
         assert "2005-10-16" in docs[0]['created']
         assert "2005-10-16" in docs[1]['created']
+
+    # Detects gunicorn issues, see PR #190888
+    with subtest("Document metadata can be accessed"):
+        metadata = json.loads(machine.succeed("curl -u admin:admin -fs localhost:28981/api/documents/1/metadata/"))
+        assert "original_checksum" in metadata
+
+        metadata = json.loads(machine.succeed("curl -u admin:admin -fs localhost:28981/api/documents/2/metadata/"))
+        assert "original_checksum" in metadata
   '';
 })
diff --git a/nixos/tests/pgadmin4.nix b/nixos/tests/pgadmin4.nix
index f280996597722..bec2554a3f041 100644
--- a/nixos/tests/pgadmin4.nix
+++ b/nixos/tests/pgadmin4.nix
@@ -107,14 +107,12 @@ import ./make-test-python.nix ({ pkgs, lib, buildDeps ? [ ], pythonEnv ? [ ], ..
       )
 
       # Don't bother to test LDAP or kerberos authentification
-      # For now deactivate change_password API test. Current bug report at https://redmine.postgresql.org/issues/7648
-      # Password change works from the UI, if email SMTP is configured.
       with subtest("run browser test"):
           machine.succeed(
                'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \
                && python regression/runtests.py \
                --pkg browser \
-               --exclude browser.tests.test_ldap_login.LDAPLoginTestCase,browser.tests.test_ldap_login,browser.tests.test_kerberos_with_mocking,browser.tests.test_change_password'
+               --exclude browser.tests.test_ldap_login.LDAPLoginTestCase,browser.tests.test_ldap_login,browser.tests.test_kerberos_with_mocking'
           )
 
       # fontconfig is necessary for chromium to run
diff --git a/nixos/tests/plasma-bigscreen.nix b/nixos/tests/plasma-bigscreen.nix
new file mode 100644
index 0000000000000..1c61cafcbff33
--- /dev/null
+++ b/nixos/tests/plasma-bigscreen.nix
@@ -0,0 +1,38 @@
+import ./make-test-python.nix ({ pkgs, ...} :
+
+{
+  name = "plasma-bigscreen";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ ttuegel k900 ];
+  };
+
+  nodes.machine = { ... }:
+
+  {
+    imports = [ ./common/user-account.nix ];
+    services.xserver.enable = true;
+    services.xserver.displayManager.sddm.enable = true;
+    services.xserver.displayManager.defaultSession = "plasma-bigscreen-x11";
+    services.xserver.desktopManager.plasma5.bigscreen.enable = true;
+    services.xserver.displayManager.autoLogin = {
+      enable = true;
+      user = "alice";
+    };
+
+    users.users.alice.extraGroups = ["uinput"];
+  };
+
+  testScript = { nodes, ... }: let
+    user = nodes.machine.users.users.alice;
+    xdo = "${pkgs.xdotool}/bin/xdotool";
+  in ''
+    with subtest("Wait for login"):
+        start_all()
+        machine.wait_for_file("${user.home}/.Xauthority")
+        machine.succeed("xauth merge ${user.home}/.Xauthority")
+
+    with subtest("Check plasmashell started"):
+        machine.wait_until_succeeds("pgrep plasmashell")
+        machine.wait_for_window("Plasma Big Screen")
+  '';
+})
diff --git a/nixos/tests/please.nix b/nixos/tests/please.nix
new file mode 100644
index 0000000000000..2437cfe16130f
--- /dev/null
+++ b/nixos/tests/please.nix
@@ -0,0 +1,66 @@
+import ./make-test-python.nix ({ lib, ... }:
+{
+  name = "please";
+  meta.maintainers = with lib.maintainers; [ azahi ];
+
+  nodes.machine =
+    { ... }:
+    {
+      users.users = with lib; mkMerge [
+        (listToAttrs (map
+          (n: nameValuePair n { isNormalUser = true; })
+          (genList (x: "user${toString x}") 6)))
+        {
+          user0.extraGroups = [ "wheel" ];
+        }
+      ];
+
+      security.please = {
+        enable = true;
+        wheelNeedsPassword = false;
+        settings = {
+          user2_run_true_as_root = {
+            name = "user2";
+            target = "root";
+            rule = "/run/current-system/sw/bin/true";
+            require_pass = false;
+          };
+          user4_edit_etc_hosts_as_root = {
+            name = "user4";
+            type = "edit";
+            target = "root";
+            rule = "/etc/hosts";
+            editmode = 644;
+            require_pass = false;
+          };
+        };
+      };
+    };
+
+  testScript = ''
+    with subtest("root: can run anything by default"):
+        machine.succeed('please true')
+    with subtest("root: can edit anything by default"):
+        machine.succeed('EDITOR=cat pleaseedit /etc/hosts')
+
+    with subtest("user0: can run as root because it's in the wheel group"):
+        machine.succeed('su - user0 -c "please -u root true"')
+    with subtest("user1: cannot run as root because it's not in the wheel group"):
+        machine.fail('su - user1 -c "please -u root true"')
+
+    with subtest("user0: can edit as root"):
+        machine.succeed('su - user0 -c "EDITOR=cat pleaseedit /etc/hosts"')
+    with subtest("user1: cannot edit as root"):
+        machine.fail('su - user1 -c "EDITOR=cat pleaseedit /etc/hosts"')
+
+    with subtest("user2: can run 'true' as root"):
+        machine.succeed('su - user2 -c "please -u root true"')
+    with subtest("user3: cannot run 'true' as root"):
+        machine.fail('su - user3 -c "please -u root true"')
+
+    with subtest("user4: can edit /etc/hosts"):
+        machine.succeed('su - user4 -c "EDITOR=cat pleaseedit /etc/hosts"')
+    with subtest("user5: cannot edit /etc/hosts"):
+        machine.fail('su - user5 -c "EDITOR=cat pleaseedit /etc/hosts"')
+  '';
+})
diff --git a/nixos/tests/printing.nix b/nixos/tests/printing.nix
index 6338fd8d8ac10..cfebe232d92a0 100644
--- a/nixos/tests/printing.nix
+++ b/nixos/tests/printing.nix
@@ -4,6 +4,7 @@ import ./make-test-python.nix ({pkgs, ... }:
 let
   printingServer = startWhenNeeded: {
     services.printing.enable = true;
+    services.printing.stateless = true;
     services.printing.startWhenNeeded = startWhenNeeded;
     services.printing.listenAddresses = [ "*:631" ];
     services.printing.defaultShared = true;
diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix
index 596a4eafcd642..a8737eb504d98 100644
--- a/nixos/tests/prometheus-exporters.nix
+++ b/nixos/tests/prometheus-exporters.nix
@@ -374,25 +374,34 @@ let
     };
 
     kea = let
-      controlSocketPath = "/run/kea/dhcp6.sock";
+      controlSocketPathV4 = "/run/kea/dhcp4.sock";
+      controlSocketPathV6 = "/run/kea/dhcp6.sock";
     in
     {
       exporterConfig = {
         enable = true;
         controlSocketPaths = [
-          controlSocketPath
+          controlSocketPathV4
+          controlSocketPathV6
         ];
       };
       metricProvider = {
-        systemd.services.prometheus-kea-exporter.after = [ "kea-dhcp6-server.service" ];
-
         services.kea = {
+          dhcp4 = {
+            enable = true;
+            settings = {
+              control-socket = {
+                socket-type = "unix";
+                socket-name = controlSocketPathV4;
+              };
+            };
+          };
           dhcp6 = {
             enable = true;
             settings = {
               control-socket = {
                 socket-type = "unix";
-                socket-name = controlSocketPath;
+                socket-name = controlSocketPathV6;
               };
             };
           };
@@ -400,8 +409,10 @@ let
       };
 
       exporterTest = ''
+        wait_for_unit("kea-dhcp4-server.service")
         wait_for_unit("kea-dhcp6-server.service")
-        wait_for_file("${controlSocketPath}")
+        wait_for_file("${controlSocketPathV4}")
+        wait_for_file("${controlSocketPathV6}")
         wait_for_unit("prometheus-kea-exporter.service")
         wait_for_open_port(9547)
         succeed(
diff --git a/nixos/tests/pulseaudio.nix b/nixos/tests/pulseaudio.nix
index cfdc61bc6c2b8..dc8e33ccd559c 100644
--- a/nixos/tests/pulseaudio.nix
+++ b/nixos/tests/pulseaudio.nix
@@ -1,10 +1,10 @@
 let
-  mkTest = { systemWide ? false }:
+  mkTest = { systemWide ? false , fullVersion ? false }:
     import ./make-test-python.nix ({ pkgs, lib, ... }:
       let
         testFile = pkgs.fetchurl {
           url =
-            "https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3";
+            "https://file-examples.com/storage/fe5947fd2362fc197a3c2df/2017/11/file_example_MP3_700KB.mp3";
           hash = "sha256-+iggJW8s0/LfA/okfXsB550/55Q0Sq3OoIzuBrzOPJQ=";
         };
 
@@ -22,7 +22,7 @@ let
           testPlay32 = { inherit (pkgs.pkgsi686Linux) sox alsa-utils; };
         };
       in {
-        name = "pulseaudio${lib.optionalString systemWide "-systemWide"}";
+        name = "pulseaudio${lib.optionalString fullVersion "Full"}${lib.optionalString systemWide "-systemWide"}";
         meta = with pkgs.lib.maintainers; {
           maintainers = [ synthetica ] ++ pkgs.pulseaudio.meta.maintainers;
         };
@@ -35,12 +35,14 @@ let
               enable = true;
               support32Bit = true;
               inherit systemWide;
+            } // lib.optionalAttrs fullVersion {
+              package = pkgs.pulseaudioFull;
             };
 
             environment.systemPackages = [ testers.testPlay pkgs.pavucontrol ]
               ++ lib.optional pkgs.stdenv.isx86_64 testers.testPlay32;
           } // lib.optionalAttrs systemWide {
-            users.users.alice.extraGroups = [ "audio" ];
+            users.users.alice.extraGroups = [ "pulse-access" ];
             systemd.services.pulseaudio.wantedBy = [ "multi-user.target" ];
           };
 
@@ -58,14 +60,21 @@ let
           ''}
           machine.screenshot("testPlay")
 
+          ${lib.optionalString (!systemWide) ''
+            machine.send_chars("pacmd info && touch /tmp/pacmd_success\n")
+            machine.wait_for_file("/tmp/pacmd_success")
+          ''}
+
           # Pavucontrol only loads when Pulseaudio is running. If it isn't, the
-          # text "Playback" (one of the tabs) will never show.
+          # text "Dummy Output" (sound device name) will never show.
           machine.send_chars("pavucontrol\n")
-          machine.wait_for_text("Playback")
+          machine.wait_for_text("Dummy Output")
           machine.screenshot("Pavucontrol")
         '';
       });
 in builtins.mapAttrs (key: val: mkTest val) {
-  user = { systemWide = false; };
-  system = { systemWide = true; };
+  user = { systemWide = false; fullVersion = false; };
+  system = { systemWide = true; fullVersion = false; };
+  userFull = { systemWide = false; fullVersion = true; };
+  systemFull = { systemWide = true; fullVersion = true; };
 }
diff --git a/nixos/tests/resolv.nix b/nixos/tests/resolv.nix
deleted file mode 100644
index f0aa7e42aaf35..0000000000000
--- a/nixos/tests/resolv.nix
+++ /dev/null
@@ -1,46 +0,0 @@
-# Test whether DNS resolving returns multiple records and all address families.
-import ./make-test-python.nix ({ pkgs, ... } : {
-  name = "resolv";
-  meta = with pkgs.lib.maintainers; {
-    maintainers = [ ckauhaus ];
-  };
-
-  nodes.resolv = { ... }: {
-    networking.extraHosts = ''
-      # IPv4 only
-      192.0.2.1 host-ipv4.example.net
-      192.0.2.2 host-ipv4.example.net
-      # IP6 only
-      2001:db8::2:1 host-ipv6.example.net
-      2001:db8::2:2 host-ipv6.example.net
-      # dual stack
-      192.0.2.1 host-dual.example.net
-      192.0.2.2 host-dual.example.net
-      2001:db8::2:1 host-dual.example.net
-      2001:db8::2:2 host-dual.example.net
-    '';
-  };
-
-  testScript = ''
-    def addrs_in(hostname, addrs):
-        res = resolv.succeed("getent ahosts {}".format(hostname))
-        for addr in addrs:
-            assert addr in res, "Expected output '{}' not found in\n{}".format(addr, res)
-
-
-    start_all()
-    resolv.wait_for_unit("nscd")
-
-    ipv4 = ["192.0.2.1", "192.0.2.2"]
-    ipv6 = ["2001:db8::2:1", "2001:db8::2:2"]
-
-    with subtest("IPv4 resolves"):
-        addrs_in("host-ipv4.example.net", ipv4)
-
-    with subtest("IPv6 resolves"):
-        addrs_in("host-ipv6.example.net", ipv6)
-
-    with subtest("Dual stack resolves"):
-        addrs_in("host-dual.example.net", ipv4 + ipv6)
-  '';
-})
diff --git a/nixos/tests/restic.nix b/nixos/tests/restic.nix
index 75fffe9d9a84d..16dd5f8c5c8a3 100644
--- a/nixos/tests/restic.nix
+++ b/nixos/tests/restic.nix
@@ -68,6 +68,9 @@ import ./make-test-python.nix (
               package = pkgs.writeShellScriptBin "restic" ''
                 echo "$@" >> /tmp/fake-restic.log;
               '';
+
+              pruneOpts = [ "--keep-last 1" ];
+              checkOpts = [ "--some-check-option" ];
             };
           };
 
@@ -98,6 +101,7 @@ import ./make-test-python.nix (
           '${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"',
           "systemctl start restic-backups-custompackage.service",
           "grep 'backup .* /opt' /tmp/fake-restic.log",
+          "grep 'check .* --some-check-option' /tmp/fake-restic.log",
           "timedatectl set-time '2017-12-13 13:45'",
           "systemctl start restic-backups-remotebackup.service",
           "rm /opt/backupCleanupCommand",
diff --git a/nixos/tests/retroarch.nix b/nixos/tests/retroarch.nix
index c506ed02da89b..f4bf232ea725e 100644
--- a/nixos/tests/retroarch.nix
+++ b/nixos/tests/retroarch.nix
@@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
 
   {
     name = "retroarch";
-    meta = with pkgs.lib.maintainers; { maintainers = [ j0hax ]; };
+    meta = with pkgs.lib; { maintainers = teams.libretro.members ++ [ maintainers.j0hax ]; };
 
     nodes.machine = { ... }:
 
@@ -11,7 +11,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
         services.xserver.enable = true;
         services.xserver.desktopManager.retroarch = {
           enable = true;
-          package = pkgs.retroarchFull;
+          package = pkgs.retroarchBare;
         };
         services.xserver.displayManager = {
           sddm.enable = true;
diff --git a/nixos/tests/seafile.nix b/nixos/tests/seafile.nix
index 6eec8b1fbe55c..78e735f4fed73 100644
--- a/nixos/tests/seafile.nix
+++ b/nixos/tests/seafile.nix
@@ -79,18 +79,14 @@ import ./make-test-python.nix ({ pkgs, ... }:
               f"seaf-cli download -l {libid} -s http://server -u admin\@example.com -p seafile_password -d . >&2"
           )
 
-          client1.sleep(3)
-
-          client1.succeed("seaf-cli status |grep synchronized >&2")
+          client1.wait_until_succeeds("seaf-cli status |grep synchronized >&2")
 
           client1.succeed("ls -la >&2")
           client1.succeed("ls -la test01 >&2")
 
           client1.execute("echo bla > test01/first_file")
 
-          client1.sleep(2)
-
-          client1.succeed("seaf-cli status |grep synchronized >&2")
+          client1.wait_until_succeeds("seaf-cli status |grep synchronized >&2")
 
       with subtest("client2 sync"):
           client2.wait_for_unit("default.target")
@@ -110,9 +106,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
               f"seaf-cli download -l {libid} -s http://server -u admin\@example.com -p seafile_password -d . >&2"
           )
 
-          client2.sleep(3)
-
-          client2.succeed("seaf-cli status |grep synchronized >&2")
+          client2.wait_until_succeeds("seaf-cli status |grep synchronized >&2")
 
           client2.succeed("ls -la test01 >&2")
 
diff --git a/nixos/tests/spark/default.nix b/nixos/tests/spark/default.nix
index 025c5a5222e71..462f0d23a4032 100644
--- a/nixos/tests/spark/default.nix
+++ b/nixos/tests/spark/default.nix
@@ -7,6 +7,7 @@ import ../make-test-python.nix ({...}: {
         enable = true;
         master = "master:7077";
       };
+      virtualisation.memorySize = 2048;
     };
     master = { config, pkgs, ... }: {
       services.spark.master = {
diff --git a/nixos/tests/sssd-ldap.nix b/nixos/tests/sssd-ldap.nix
index 27dce6ceb98cd..ff83e96068a96 100644
--- a/nixos/tests/sssd-ldap.nix
+++ b/nixos/tests/sssd-ldap.nix
@@ -91,6 +91,11 @@ in import ./make-test-python.nix ({pkgs, ...}: {
     machine.start()
     machine.wait_for_unit("openldap.service")
     machine.wait_for_unit("sssd.service")
-    machine.succeed("getent passwd ${testUser}")
+    result = machine.execute("getent passwd ${testUser}")
+    if result[0] == 0:
+      assert "${testUser}" in result[1]
+    else:
+      machine.wait_for_console_text("Backend is online")
+      machine.succeed("getent passwd ${testUser}")
   '';
 })
diff --git a/nixos/tests/stratis/default.nix b/nixos/tests/stratis/default.nix
index 6964852e30a09..42daadd5fcaac 100644
--- a/nixos/tests/stratis/default.nix
+++ b/nixos/tests/stratis/default.nix
@@ -4,4 +4,5 @@
 
 {
   simple = import ./simple.nix { inherit system pkgs; };
+  encryption = import ./encryption.nix { inherit system pkgs; };
 }
diff --git a/nixos/tests/stratis/encryption.nix b/nixos/tests/stratis/encryption.nix
new file mode 100644
index 0000000000000..3faa3171843f7
--- /dev/null
+++ b/nixos/tests/stratis/encryption.nix
@@ -0,0 +1,33 @@
+import ../make-test-python.nix ({ pkgs, ... }:
+  {
+    name = "stratis";
+
+    meta = with pkgs.lib.maintainers; {
+      maintainers = [ nickcao ];
+    };
+
+    nodes.machine = { pkgs, ... }: {
+      services.stratis.enable = true;
+      virtualisation.emptyDiskImages = [ 2048 ];
+    };
+
+    testScript =
+      let
+        testkey1 = pkgs.writeText "testkey1" "supersecret1";
+        testkey2 = pkgs.writeText "testkey2" "supersecret2";
+      in
+      ''
+        machine.wait_for_unit("stratisd")
+        # test creation of encrypted pool and filesystem
+        machine.succeed("stratis key  set    testkey1  --keyfile-path ${testkey1}")
+        machine.succeed("stratis key  set    testkey2  --keyfile-path ${testkey2}")
+        machine.succeed("stratis pool create testpool /dev/vdb --key-desc testkey1")
+        machine.succeed("stratis fs   create testpool testfs")
+        # test rebinding encrypted pool
+        machine.succeed("stratis pool rebind keyring  testpool testkey2")
+        # test restarting encrypted pool
+        uuid = machine.succeed("stratis pool list | grep -oE '[0-9a-fA-F-]{36}'").rstrip('\n')
+        machine.succeed(" stratis pool stop   testpool")
+        machine.succeed(f"stratis pool start  {uuid}   --unlock-method keyring")
+      '';
+  })
diff --git a/nixos/tests/systemd-cryptenroll.nix b/nixos/tests/systemd-cryptenroll.nix
index 055ae7d1681f2..9ee2d280fbbea 100644
--- a/nixos/tests/systemd-cryptenroll.nix
+++ b/nixos/tests/systemd-cryptenroll.nix
@@ -2,6 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
   name = "systemd-cryptenroll";
   meta = with pkgs.lib.maintainers; {
     maintainers = [ ymatsiuk ];
+    broken = true; # times out after two hours, details -> https://github.com/NixOS/nixpkgs/issues/167994
   };
 
   nodes.machine = { pkgs, lib, ... }: {
diff --git a/nixos/tests/systemd-initrd-modprobe.nix b/nixos/tests/systemd-initrd-modprobe.nix
new file mode 100644
index 0000000000000..bf635a10d0e97
--- /dev/null
+++ b/nixos/tests/systemd-initrd-modprobe.nix
@@ -0,0 +1,17 @@
+import ./make-test-python.nix ({ lib, pkgs, ... }: {
+  name = "systemd-initrd-modprobe";
+
+  nodes.machine = { pkgs, ... }: {
+    boot.initrd.systemd.enable = true;
+    boot.initrd.kernelModules = [ "loop" ]; # Load module in initrd.
+    boot.extraModprobeConfig = ''
+      options loop max_loop=42
+    '';
+  };
+
+  testScript = ''
+    machine.wait_for_unit("multi-user.target")
+    max_loop = machine.succeed("cat /sys/module/loop/parameters/max_loop")
+    assert int(max_loop) == 42, "Parameter should be respected for initrd kernel modules"
+  '';
+})
diff --git a/nixos/tests/systemd-machinectl.nix b/nixos/tests/systemd-machinectl.nix
index 5c7926e24abf2..7a4888ab85f6a 100644
--- a/nixos/tests/systemd-machinectl.nix
+++ b/nixos/tests/systemd-machinectl.nix
@@ -1,4 +1,4 @@
-import ./make-test-python.nix (
+import ./make-test-python.nix ({ pkgs, ... }:
   let
 
     container = {
@@ -18,6 +18,7 @@ import ./make-test-python.nix (
     };
 
     containerSystem = (import ../lib/eval-config.nix {
+      inherit (pkgs) system;
       modules = [ container ];
     }).config.system.build.toplevel;
 
diff --git a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix
index 37a89fc21e442..279b9aac8edb6 100644
--- a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix
+++ b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix
@@ -7,10 +7,10 @@
 # - VLAN 1 is the connection between the ISP and the router
 # - VLAN 2 is the connection between the router and the client
 
-import ./make-test-python.nix ({pkgs, ...}: {
+import ./make-test-python.nix ({ pkgs, lib, ... }: {
   name = "systemd-networkd-ipv6-prefix-delegation";
-  meta = with pkgs.lib.maintainers; {
-    maintainers = [ andir ];
+  meta = with lib.maintainers; {
+    maintainers = [ andir hexa ];
   };
   nodes = {
 
@@ -22,26 +22,38 @@ import ./make-test-python.nix ({pkgs, ...}: {
     #
     # Note: On the ISPs device we don't really care if we are using networkd in
     # this example. That being said we can't use it (yet) as networkd doesn't
-    # implement the serving side of DHCPv6. We will use ISC's well aged dhcpd6
-    # for that task.
+    # implement the serving side of DHCPv6. We will use ISC Kea for that task.
     isp = { lib, pkgs, ... }: {
       virtualisation.vlans = [ 1 ];
       networking = {
         useDHCP = false;
         firewall.enable = false;
-        interfaces.eth1.ipv4.addresses = lib.mkForce []; # no need for legacy IP
-        interfaces.eth1.ipv6.addresses = lib.mkForce [
-          { address = "2001:DB8::1"; prefixLength = 64; }
-        ];
+        interfaces.eth1 = lib.mkForce {}; # Don't use scripted networking
+      };
+
+      systemd.network = {
+        enable = true;
+
+        networks = {
+          "eth1" = {
+            matchConfig.Name = "eth1";
+            address = [
+              "2001:DB8::1/64"
+            ];
+            networkConfig.IPForward = true;
+          };
+        };
       };
 
       # Since we want to program the routes that we delegate to the "customer"
-      # into our routing table we must give dhcpd the required privs.
-      systemd.services.dhcpd6.serviceConfig.AmbientCapabilities =
-        [ "CAP_NET_ADMIN" ];
+      # into our routing table we must provide kea with the required capability.
+      systemd.services.kea-dhcp6-server.serviceConfig = {
+        AmbientCapabilities = [ "CAP_NET_ADMIN" ];
+        CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
+      };
 
       services = {
-        # Configure the DHCPv6 server
+        # Configure the DHCPv6 server to hand out both IA_NA and IA_PD.
         #
         # We will hand out /48 prefixes from the subnet 2001:DB8:F000::/36.
         # That gives us ~8k prefixes. That should be enough for this test.
@@ -49,31 +61,70 @@ import ./make-test-python.nix ({pkgs, ...}: {
         # Since (usually) you will not receive a prefix with the router
         # advertisements we also hand out /128 leases from the range
         # 2001:DB8:0000:0000:FFFF::/112.
-        dhcpd6 = {
+        kea.dhcp6 = {
           enable = true;
-          interfaces = [ "eth1" ];
-          extraConfig = ''
-            subnet6 2001:DB8::/36 {
-              range6 2001:DB8:0000:0000:FFFF:: 2001:DB8:0000:0000:FFFF::FFFF;
-              prefix6 2001:DB8:F000:: 2001:DB8:FFFF:: /48;
-            }
-
-            # This is the secret sauce. We have to extract the prefix and the
-            # next hop when commiting the lease to the database.  dhcpd6
-            # (rightfully) has not concept of adding routes to the systems
-            # routing table. It really depends on the setup.
+          settings = {
+            interfaces-config.interfaces = [ "eth1" ];
+            subnet6 = [ {
+              interface = "eth1";
+              subnet = "2001:DB8:F::/36";
+              pd-pools = [ {
+                prefix = "2001:DB8:F::";
+                prefix-len = 36;
+                delegated-len = 48;
+              } ];
+              pools = [ {
+                pool = "2001:DB8:0000:0000:FFFF::-2001:DB8:0000:0000:FFFF::FFFF";
+              } ];
+            } ];
+
+            # This is the glue between Kea and the Kernel FIB. DHCPv6
+            # rightfully has no concept of setting up a route in your
+            # FIB. This step really depends on your setup.
             #
-            # In a production environment your DHCPv6 server is likely not the
-            # router. You might want to consider BGP, custom NetConf calls, …
-            # in those cases.
-            on commit {
-              set IP = pick-first-value(binary-to-ascii(16, 16, ":", substring(option dhcp6.ia-na, 16, 16)), "n/a");
-              set Prefix = pick-first-value(binary-to-ascii(16, 16, ":", suffix(option dhcp6.ia-pd, 16)), "n/a");
-              set PrefixLength = pick-first-value(binary-to-ascii(10, 8, ":", substring(suffix(option dhcp6.ia-pd, 17), 0, 1)), "n/a");
-              log(concat(IP, " ", Prefix, " ", PrefixLength));
-              execute("${pkgs.iproute2}/bin/ip", "-6", "route", "replace", concat(Prefix,"/",PrefixLength), "via", IP);
-            }
-          '';
+            # In a production environment your DHCPv6 server is likely
+            # not the router. You might want to consider BGP, NETCONF
+            # calls, … in those cases.
+            #
+            # In this example we use the run script hook, that lets use
+            # execute anything and passes information via the environment.
+            # https://kea.readthedocs.io/en/kea-2.2.0/arm/hooks.html#run-script-run-script-support-for-external-hook-scripts
+            hooks-libraries = [ {
+              library = "${pkgs.kea}/lib/kea/hooks/libdhcp_run_script.so";
+              parameters = {
+                name = pkgs.writeShellScript "kea-run-hooks" ''
+                  export PATH="${lib.makeBinPath (with pkgs; [ coreutils iproute2 ])}"
+
+                  set -euxo pipefail
+
+                  leases6_committed() {
+                    for i in $(seq $LEASES6_SIZE); do
+                      idx=$((i-1))
+                      prefix_var="LEASES6_AT''${idx}_ADDRESS"
+                      plen_var="LEASES6_AT''${idx}_PREFIX_LEN"
+
+                      ip -6 route replace ''${!prefix_var}/''${!plen_var} via $QUERY6_REMOTE_ADDR dev $QUERY6_IFACE_NAME
+                    done
+                  }
+
+                  unknown_handler() {
+                    echo "Unhandled function call ''${*}"
+                    exit 123
+                  }
+
+                  case "$1" in
+                      "leases6_committed")
+                          leases6_committed
+                          ;;
+                      *)
+                          unknown_handler "''${@}"
+                          ;;
+                  esac
+                '';
+                sync = false;
+              };
+            } ];
+          };
         };
 
         # Finally we have to set up the router advertisements. While we could be
@@ -176,7 +227,7 @@ import ./make-test-python.nix ({pkgs, ...}: {
               IPv6AcceptRA = false;
 
               # Delegate prefixes from the DHCPv6 PD pool.
-              DHCPv6PrefixDelegation = true;
+              DHCPPrefixDelegation = true;
               IPv6SendRA = true;
             };
 
diff --git a/nixos/tests/systemd-oomd.nix b/nixos/tests/systemd-oomd.nix
index f0b5a5f8e01ab..55c4c13500005 100644
--- a/nixos/tests/systemd-oomd.nix
+++ b/nixos/tests/systemd-oomd.nix
@@ -3,35 +3,52 @@ import ./make-test-python.nix ({ pkgs, ... }:
 {
   name = "systemd-oomd";
 
+  # This test is a simplified version of systemd's testsuite-55.
+  # https://github.com/systemd/systemd/blob/v251/test/units/testsuite-55.sh
   nodes.machine = { pkgs, ... }: {
-    systemd.oomd.extraConfig.DefaultMemoryPressureDurationSec = "1s"; # makes the test faster
-    # Kill cgroups when more than 1% pressure is encountered
-    systemd.slices."-".sliceConfig = {
-      ManagedOOMMemoryPressure = "kill";
-      ManagedOOMMemoryPressureLimit = "1%";
+    # Limit VM resource usage.
+    virtualisation.memorySize = 1024;
+    systemd.oomd.extraConfig.DefaultMemoryPressureDurationSec = "1s";
+
+    systemd.slices.workload = {
+      description = "Test slice for memory pressure kills";
+      sliceConfig = {
+        MemoryAccounting = true;
+        ManagedOOMMemoryPressure = "kill";
+        ManagedOOMMemoryPressureLimit = "10%";
+      };
     };
-    # A service to bring the system under memory pressure
-    systemd.services.testservice = {
-      serviceConfig.ExecStart = "${pkgs.coreutils}/bin/tail /dev/zero";
+
+    systemd.services.testbloat = {
+      description = "Create a lot of memory pressure";
+      serviceConfig = {
+        Slice = "workload.slice";
+        MemoryHigh = "5M";
+        ExecStart = "${pkgs.coreutils}/bin/tail /dev/zero";
+      };
     };
-    # Do not kill the backdoor
-    systemd.services.backdoor.serviceConfig.ManagedOOMMemoryPressure = "auto";
 
-    virtualisation.memorySize = 1024;
+    systemd.services.testchill = {
+      description = "No memory pressure";
+      serviceConfig = {
+        Slice = "workload.slice";
+        MemoryHigh = "3M";
+        ExecStart = "${pkgs.coreutils}/bin/sleep infinity";
+      };
+    };
   };
 
   testScript = ''
-    # Start the system
+    # Start the system.
     machine.wait_for_unit("multi-user.target")
     machine.succeed("oomctl")
 
-    # Bring the system into memory pressure
-    machine.succeed("echo 0 > /proc/sys/vm/panic_on_oom")  # NixOS tests kill the VM when the OOM killer is invoked - override this
-    machine.succeed("systemctl start testservice")
+    machine.succeed("systemctl start testchill.service")
+    with subtest("OOMd should kill the bad service"):
+        machine.fail("systemctl start --wait testbloat.service")
+        assert machine.get_unit_info("testbloat.service")["Result"] == "oom-kill"
 
-    # Wait for oomd to kill something
-    # Matches these lines:
-    # systemd-oomd[508]: Killed /system.slice/systemd-udevd.service due to memory pressure for / being 3.26% > 1.00% for > 1s with reclaim activity
-    machine.wait_until_succeeds("journalctl -b | grep -q 'due to memory pressure for'")
+    with subtest("Service without memory pressure should be untouched"):
+        machine.require_unit_state("testchill.service", "active")
   '';
 })
diff --git a/nixos/tests/systemd.nix b/nixos/tests/systemd.nix
index 3317823e03f76..3c36291b733d2 100644
--- a/nixos/tests/systemd.nix
+++ b/nixos/tests/systemd.nix
@@ -87,12 +87,6 @@ import ./make-test-python.nix ({ pkgs, ... }: {
         machine.succeed("test -e /home/alice/user_conf_read")
         machine.succeed("test -z $(ls -1 /var/log/journal)")
 
-    # Regression test for https://github.com/NixOS/nixpkgs/issues/50273
-    with subtest("DynamicUser actually allocates a user"):
-        assert "iamatest" in machine.succeed(
-            "systemd-run --pty --property=Type=oneshot --property=DynamicUser=yes --property=User=iamatest whoami"
-        )
-
     with subtest("regression test for https://bugs.freedesktop.org/show_bug.cgi?id=77507"):
         retcode, output = machine.execute("systemctl status testservice1.service")
         assert retcode in [0, 3]  # https://bugs.freedesktop.org/show_bug.cgi?id=77507
diff --git a/nixos/tests/tandoor-recipes.nix b/nixos/tests/tandoor-recipes.nix
new file mode 100644
index 0000000000000..54456238fe634
--- /dev/null
+++ b/nixos/tests/tandoor-recipes.nix
@@ -0,0 +1,43 @@
+import ./make-test-python.nix ({ lib, ... }: {
+  name = "tandoor-recipes";
+  meta.maintainers = with lib.maintainers; [ ambroisie ];
+
+  nodes.machine = { pkgs, ... }: {
+    # Setup using Postgres
+    services.tandoor-recipes = {
+      enable = true;
+
+      extraConfig = {
+        DB_ENGINE = "django.db.backends.postgresql";
+        POSTGRES_HOST = "/run/postgresql";
+        POSTGRES_USER = "tandoor_recipes";
+        POSTGRES_DB = "tandoor_recipes";
+      };
+    };
+
+    services.postgresql = {
+      enable = true;
+      ensureDatabases = [ "tandoor_recipes" ];
+      ensureUsers = [
+        {
+          name = "tandoor_recipes";
+          ensurePermissions."DATABASE tandoor_recipes" = "ALL PRIVILEGES";
+        }
+      ];
+    };
+
+    systemd.services = {
+      tandoor-recipes = {
+        after = [ "postgresql.service" ];
+      };
+    };
+  };
+
+  testScript = ''
+    machine.wait_for_unit("tandoor-recipes.service")
+
+    with subtest("Web interface gets ready"):
+        # Wait until server accepts connections
+        machine.wait_until_succeeds("curl -fs localhost:8080")
+  '';
+})
diff --git a/nixos/tests/terminal-emulators.nix b/nixos/tests/terminal-emulators.nix
index c724608b91554..4269d05056d8c 100644
--- a/nixos/tests/terminal-emulators.nix
+++ b/nixos/tests/terminal-emulators.nix
@@ -23,8 +23,9 @@ with pkgs.lib;
 let tests = {
       alacritty.pkg = p: p.alacritty;
 
-      contour.pkg = p: p.contour;
-      contour.cmd = "contour $command";
+      # times out after spending many hours
+      #contour.pkg = p: p.contour;
+      #contour.cmd = "contour $command";
 
       cool-retro-term.pkg = p: p.cool-retro-term;
       cool-retro-term.colourTest = false; # broken by gloss effect
@@ -103,7 +104,8 @@ let tests = {
       wayst.pkg = p: p.wayst;
       wayst.pinkValue = "#FF0066";
 
-      wezterm.pkg = p: p.wezterm;
+      # times out after spending many hours
+      #wezterm.pkg = p: p.wezterm;
 
       xfce4-terminal.pkg = p: p.xfce.xfce4-terminal;
 
diff --git a/nixos/tests/tmate-ssh-server.nix b/nixos/tests/tmate-ssh-server.nix
new file mode 100644
index 0000000000000..e7f94db9bfcf4
--- /dev/null
+++ b/nixos/tests/tmate-ssh-server.nix
@@ -0,0 +1,73 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+let
+  inherit (import ./ssh-keys.nix pkgs)
+    snakeOilPrivateKey snakeOilPublicKey;
+
+  setUpPrivateKey = name: ''
+    ${name}.succeed(
+        "mkdir -p /root/.ssh",
+        "chown 700 /root/.ssh",
+        "cat '${snakeOilPrivateKey}' > /root/.ssh/id_snakeoil",
+        "chown 600 /root/.ssh/id_snakeoil",
+    )
+    ${name}.wait_for_file("/root/.ssh/id_snakeoil")
+  '';
+
+  sshOpts = "-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oIdentityFile=/root/.ssh/id_snakeoil";
+
+in
+{
+  name = "tmate-ssh-server";
+  nodes =
+    {
+      server = { ... }: {
+        services.tmate-ssh-server = {
+          enable = true;
+          port = 2223;
+        };
+      };
+      client = { ... }: {
+        environment.systemPackages = [ pkgs.tmate ];
+        services.openssh.enable = true;
+        users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
+      };
+      client2 = { ... }: {
+        environment.systemPackages = [ pkgs.openssh ];
+      };
+    };
+  testScript = ''
+    start_all()
+
+    server.wait_for_unit("tmate-ssh-server.service")
+    server.wait_for_open_port(2223)
+    server.wait_for_file("/etc/tmate-ssh-server-keys/ssh_host_ed25519_key.pub")
+    server.wait_for_file("/etc/tmate-ssh-server-keys/ssh_host_rsa_key.pub")
+    server.succeed("tmate-client-config > /tmp/tmate.conf")
+    server.wait_for_file("/tmp/tmate.conf")
+
+    ${setUpPrivateKey "server"}
+    client.wait_for_unit("sshd.service")
+    client.wait_for_open_port(22)
+    server.succeed("scp ${sshOpts} /tmp/tmate.conf client:/tmp/tmate.conf")
+
+    client.wait_for_file("/tmp/tmate.conf")
+    client.send_chars("root\n")
+    client.sleep(2)
+    client.send_chars("tmate -f /tmp/tmate.conf\n")
+    client.sleep(2)
+    client.send_chars("q")
+    client.sleep(2)
+    client.send_chars("tmate display -p '#{tmate_ssh}' > /tmp/ssh_command\n")
+    client.wait_for_file("/tmp/ssh_command")
+    ssh_cmd = client.succeed("cat /tmp/ssh_command")
+
+    client2.succeed("mkdir -p ~/.ssh; ssh-keyscan -p 2223 server > ~/.ssh/known_hosts")
+    client2.send_chars("root\n")
+    client2.sleep(2)
+    client2.send_chars(ssh_cmd.strip() + "\n")
+    client2.sleep(2)
+    client2.send_chars("touch /tmp/client_2\n")
+
+    client.wait_for_file("/tmp/client_2")
+  '';
+})
diff --git a/nixos/tests/tracee.nix b/nixos/tests/tracee.nix
new file mode 100644
index 0000000000000..26d0ada931b1c
--- /dev/null
+++ b/nixos/tests/tracee.nix
@@ -0,0 +1,46 @@
+import ./make-test-python.nix ({ pkgs, ... }: {
+  name = "tracee-integration";
+  nodes = {
+    machine = { config, pkgs, ... }: {
+      # EventFilters/trace_only_events_from_new_containers requires docker
+      # podman with docker compat will suffice
+      virtualisation.podman.enable = true;
+      virtualisation.podman.dockerCompat = true;
+
+      environment.systemPackages = [
+        # build the go integration tests as a binary
+        (pkgs.tracee.overrideAttrs (oa: {
+          pname = oa.pname + "-integration";
+          patches = oa.patches or [] ++ [
+            # change the prefix from /usr/bin to /run to find nix processes
+            ../../pkgs/tools/security/tracee/test-EventFilters-prefix-nix-friendly.patch
+            # skip magic_write test that currently fails
+            ../../pkgs/tools/security/tracee/test-EventFilters-magic_write-skip.patch
+          ];
+          buildPhase = ''
+            runHook preBuild
+            # just build the static lib we need for the go test binary
+            make $makeFlags ''${enableParallelBuilding:+-j$NIX_BUILD_CORES -l$NIX_BUILD_CORES} bpf-core ./dist/btfhub ./dist/libbpf/libbpf.a
+            # then compile the tests to be ran later
+            CGO_CFLAGS="-I$PWD/dist/libbpf" CGO_LDFLAGS="-lelf -lz $PWD/dist/libbpf/libbpf.a" go test -tags core,ebpf,integration -p 1 -c -o $GOPATH/tracee-integration ./tests/integration/...
+            runHook postBuild
+          '';
+          doCheck = false;
+          installPhase = ''
+            mkdir -p $out/bin
+            cp $GOPATH/tracee-integration $out/bin
+          '';
+          doInstallCheck = false;
+        }))
+      ];
+    };
+  };
+
+  testScript = ''
+    with subtest("run integration tests"):
+      # EventFilters/trace_only_events_from_new_containers also requires a container called "alpine"
+      machine.succeed('tar cv -C ${pkgs.pkgsStatic.busybox} . | podman import - alpine --change ENTRYPOINT=sleep')
+
+      print(machine.succeed('TRC_BIN="${pkgs.tracee}" tracee-integration -test.v'))
+  '';
+})
diff --git a/nixos/tests/vengi-tools.nix b/nixos/tests/vengi-tools.nix
index 5bc8d72c77237..fd7567991487e 100644
--- a/nixos/tests/vengi-tools.nix
+++ b/nixos/tests/vengi-tools.nix
@@ -20,10 +20,8 @@ import ./make-test-python.nix ({ pkgs, ... }: {
       machine.wait_for_x()
       machine.execute("vengi-voxedit >&2 &")
       machine.wait_for_window("voxedit")
-      # OCR on voxedit's window is very expensive, so we avoid wasting a try
-      # by letting the window load fully first
+      # Let the window load fully
       machine.sleep(15)
-      machine.wait_for_text("Solid")
       machine.screenshot("screen")
     '';
 })
diff --git a/nixos/tests/vscodium.nix b/nixos/tests/vscodium.nix
index 3bdb99947a40b..ee884cc4295dd 100644
--- a/nixos/tests/vscodium.nix
+++ b/nixos/tests/vscodium.nix
@@ -70,15 +70,15 @@ let
 
             # Save the file
             machine.send_key('ctrl-s')
-            machine.wait_for_text('Save')
+            machine.wait_for_text('(Save|Desktop|alice|Size)')
             machine.screenshot('save_window')
             machine.send_key('ret')
 
             # (the default filename is the first line of the file)
             machine.wait_for_file(f'/home/alice/{test_string}')
 
-        machine.send_key('ctrl-q')
-        machine.wait_until_fails('pgrep -x codium')
+        # machine.send_key('ctrl-q')
+        # machine.wait_until_fails('pgrep -x codium')
       '';
     });
 
diff --git a/nixos/tests/wine.nix b/nixos/tests/wine.nix
index 8a64c3179c518..7cbe7ac94f1e7 100644
--- a/nixos/tests/wine.nix
+++ b/nixos/tests/wine.nix
@@ -44,5 +44,8 @@ in
 listToAttrs (
   map (makeWineTest "winePackages" [ hello32 ]) variants
   ++ optionals pkgs.stdenv.is64bit
-    (map (makeWineTest "wineWowPackages" [ hello32 hello64 ]) variants)
+    (map (makeWineTest "wineWowPackages" [ hello32 hello64 ])
+         # This wayland combination times out after spending many hours.
+         # https://hydra.nixos.org/job/nixos/trunk-combined/nixos.tests.wine.wineWowPackages-wayland.x86_64-linux
+         (pkgs.lib.remove "wayland" variants))
 )
diff --git a/nixos/tests/xpadneo.nix b/nixos/tests/xpadneo.nix
new file mode 100644
index 0000000000000..c7b72831fce82
--- /dev/null
+++ b/nixos/tests/xpadneo.nix
@@ -0,0 +1,18 @@
+import ./make-test-python.nix ({ lib, pkgs, ... }: {
+  name = "xpadneo";
+  meta.maintainers = with lib.maintainers; [ kira-bruneau ];
+
+  nodes = {
+    machine = {
+      config.hardware.xpadneo.enable = true;
+    };
+  };
+
+  # This is just a sanity check to make sure the module was
+  # loaded. We'd have to find some way to mock an xbox controller if
+  # we wanted more in-depth testing.
+  testScript = ''
+    machine.start();
+    machine.succeed("modinfo hid_xpadneo | grep 'version:\s\+${pkgs.linuxPackages.xpadneo.version}'")
+  '';
+})