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/acme.nix32
-rw-r--r--nixpkgs/nixos/tests/agda.nix11
-rw-r--r--nixpkgs/nixos/tests/all-tests.nix5
-rw-r--r--nixpkgs/nixos/tests/containers-custom-pkgs.nix50
-rw-r--r--nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix1
-rw-r--r--nixpkgs/nixos/tests/hledger-web.nix53
-rw-r--r--nixpkgs/nixos/tests/hostname.nix14
-rw-r--r--nixpkgs/nixos/tests/installer.nix4
-rw-r--r--nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix17
-rw-r--r--nixpkgs/nixos/tests/nextcloud/basic.nix1
-rw-r--r--nixpkgs/nixos/tests/pleroma.nix265
-rw-r--r--nixpkgs/nixos/tests/power-profiles-daemon.nix45
-rw-r--r--nixpkgs/nixos/tests/predictable-interface-names.nix8
-rw-r--r--nixpkgs/nixos/tests/rsyncd.nix39
-rw-r--r--nixpkgs/nixos/tests/scala.nix33
-rw-r--r--nixpkgs/nixos/tests/searx.nix5
-rw-r--r--nixpkgs/nixos/tests/smokeping.nix1
-rw-r--r--nixpkgs/nixos/tests/snapcast.nix19
-rw-r--r--nixpkgs/nixos/tests/vault-postgresql.nix2
-rw-r--r--nixpkgs/nixos/tests/vscodium.nix47
-rw-r--r--nixpkgs/nixos/tests/xmpp/prosody.nix2
-rw-r--r--nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix26
22 files changed, 588 insertions, 92 deletions
diff --git a/nixpkgs/nixos/tests/acme.nix b/nixpkgs/nixos/tests/acme.nix
index eb152cf51a6a..c6d393d91963 100644
--- a/nixpkgs/nixos/tests/acme.nix
+++ b/nixpkgs/nixos/tests/acme.nix
@@ -77,6 +77,27 @@ in import ./make-test-python.nix ({ lib, ... }: {
         after = [ "acme-a.example.test.service" "nginx-config-reload.service" ];
       };
 
+      # Test that account creation is collated into one service
+      specialisation.account-creation.configuration = { nodes, pkgs, lib, ... }: let
+        email = "newhostmaster@example.test";
+        caDomain = nodes.acme.config.test-support.acme.caDomain;
+        # Exit 99 to make it easier to track if this is the reason a renew failed
+        testScript = ''
+          test -e accounts/${caDomain}/${email}/account.json || exit 99
+        '';
+      in {
+        security.acme.email = lib.mkForce email;
+        systemd.services."b.example.test".preStart = testScript;
+        systemd.services."c.example.test".preStart = testScript;
+
+        services.nginx.virtualHosts."b.example.test" = (vhostBase pkgs) // {
+          enableACME = true;
+        };
+        services.nginx.virtualHosts."c.example.test" = (vhostBase pkgs) // {
+          enableACME = true;
+        };
+      };
+
       # Cert config changes will not cause the nginx configuration to change.
       # This tests that the reload service is correctly triggered.
       # It also tests that postRun is exec'd as root
@@ -289,7 +310,7 @@ in import ./make-test-python.nix ({ lib, ... }: {
       acme.start()
       webserver.start()
 
-      acme.wait_for_unit("default.target")
+      acme.wait_for_unit("network-online.target")
       acme.wait_for_unit("pebble.service")
 
       client.succeed("curl https://${caDomain}:15000/roots/0 > /tmp/ca.crt")
@@ -314,6 +335,15 @@ in import ./make-test-python.nix ({ lib, ... }: {
           check_issuer(webserver, "a.example.test", "pebble")
           check_connection(client, "a.example.test")
 
+      with subtest("Runs 1 cert for account creation before others"):
+          switch_to(webserver, "account-creation")
+          webserver.wait_for_unit("acme-finished-a.example.test.target")
+          check_connection(client, "a.example.test")
+          webserver.wait_for_unit("acme-finished-b.example.test.target")
+          webserver.wait_for_unit("acme-finished-c.example.test.target")
+          check_connection(client, "b.example.test")
+          check_connection(client, "c.example.test")
+
       with subtest("Can reload web server when cert configuration changes"):
           switch_to(webserver, "cert-change")
           webserver.wait_for_unit("acme-finished-a.example.test.target")
diff --git a/nixpkgs/nixos/tests/agda.nix b/nixpkgs/nixos/tests/agda.nix
index bbdeb7395aa7..3773907cff55 100644
--- a/nixpkgs/nixos/tests/agda.nix
+++ b/nixpkgs/nixos/tests/agda.nix
@@ -23,6 +23,13 @@ in
   };
 
   testScript = ''
+    assert (
+        "${pkgs.agdaPackages.lib.interfaceFile "Everything.agda"}" == "Everything.agdai"
+    ), "wrong interface file for Everything.agda"
+    assert (
+        "${pkgs.agdaPackages.lib.interfaceFile "tmp/Everything.agda.md"}" == "tmp/Everything.agdai"
+    ), "wrong interface file for tmp/Everything.agda.md"
+
     # Minimal script that typechecks
     machine.succeed("touch TestEmpty.agda")
     machine.succeed("agda TestEmpty.agda")
@@ -36,6 +43,10 @@ in
         "cp ${hello-world} HelloWorld.agda"
     )
     machine.succeed("agda -l standard-library -i . -c HelloWorld.agda")
+    # Check execution
+    assert "Hello World!" in machine.succeed(
+        "./HelloWorld"
+    ), "HelloWorld does not run properly"
   '';
 }
 )
diff --git a/nixpkgs/nixos/tests/all-tests.nix b/nixpkgs/nixos/tests/all-tests.nix
index 246ad7548276..444580bc0bed 100644
--- a/nixpkgs/nixos/tests/all-tests.nix
+++ b/nixpkgs/nixos/tests/all-tests.nix
@@ -155,6 +155,7 @@ in
   # not on other platforms.
   hibernate = handleTestOn ["x86_64-linux"] ./hibernate.nix {};
   hitch = handleTest ./hitch {};
+  hledger-web = handleTest ./hledger-web.nix {};
   hocker-fetchdocker = handleTest ./hocker-fetchdocker {};
   home-assistant = handleTest ./home-assistant.nix {};
   hostname = handleTest ./hostname.nix {};
@@ -188,6 +189,7 @@ in
   kernel-latest = handleTest ./kernel-latest.nix {};
   kernel-lts = handleTest ./kernel-lts.nix {};
   kernel-testing = handleTest ./kernel-testing.nix {};
+  kernel-latest-ath-user-regd = handleTest ./kernel-latest-ath-user-regd.nix {};
   keycloak = discoverTests (import ./keycloak.nix);
   keymap = handleTest ./keymap.nix {};
   knot = handleTest ./knot.nix {};
@@ -302,6 +304,7 @@ in
   php = handleTest ./php {};
   pinnwand = handleTest ./pinnwand.nix {};
   plasma5 = handleTest ./plasma5.nix {};
+  pleroma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./pleroma.nix {};
   plotinus = handleTest ./plotinus.nix {};
   podman = handleTestOn ["x86_64-linux"] ./podman.nix {};
   postfix = handleTest ./postfix.nix {};
@@ -342,7 +345,6 @@ in
   sanoid = handleTest ./sanoid.nix {};
   sbt = handleTest ./sbt.nix {};
   sbt-extras = handleTest ./sbt-extras.nix {};
-  scala = handleTest ./scala.nix {};
   sddm = handleTest ./sddm.nix {};
   searx = handleTest ./searx.nix {};
   service-runner = handleTest ./service-runner.nix {};
@@ -411,6 +413,7 @@ in
   vector = handleTest ./vector.nix {};
   victoriametrics = handleTest ./victoriametrics.nix {};
   virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
+  vscodium = handleTest ./vscodium.nix {};
   wasabibackend = handleTest ./wasabibackend.nix {};
   wireguard = handleTest ./wireguard {};
   wordpress = handleTest ./wordpress.nix {};
diff --git a/nixpkgs/nixos/tests/containers-custom-pkgs.nix b/nixpkgs/nixos/tests/containers-custom-pkgs.nix
index 397a4a905e6d..1412c32bfb5f 100644
--- a/nixpkgs/nixos/tests/containers-custom-pkgs.nix
+++ b/nixpkgs/nixos/tests/containers-custom-pkgs.nix
@@ -1,42 +1,34 @@
-# Test for NixOS' container support.
-
 import ./make-test-python.nix ({ pkgs, lib, ...} : let
 
-  customPkgs = pkgs // {
-    hello = pkgs.hello.overrideAttrs(old: {
-      name = "custom-hello";
+  customPkgs = pkgs.appendOverlays [ (self: super: {
+    hello = super.hello.overrideAttrs (old: {
+       name = "custom-hello";
     });
-  };
+  }) ];
 
 in {
-  name = "containers-hosts";
+  name = "containers-custom-pkgs";
   meta = with lib.maintainers; {
-    maintainers = [ adisbladis ];
+    maintainers = [ adisbladis earvstedt ];
   };
 
-  machine =
-    { ... }:
-    {
-      virtualisation.memorySize = 256;
-      virtualisation.vlans = [];
+  machine = { config, ... }: {
+    assertions = let
+      helloName = (builtins.head config.containers.test.config.system.extraDependencies).name;
+    in [ {
+      assertion = helloName == "custom-hello";
+      message = "Unexpected value: ${helloName}";
+    } ];
 
-      containers.simple = {
-        autoStart = true;
-        pkgs = customPkgs;
-        config = {pkgs, config, ... }: {
-          environment.systemPackages = [
-            pkgs.hello
-          ];
-        };
+    containers.test = {
+      autoStart = true;
+      config = { pkgs, config, ... }: {
+        nixpkgs.pkgs = customPkgs;
+        system.extraDependencies = [ pkgs.hello ];
       };
-
     };
+  };
 
-  testScript = ''
-    start_all()
-    machine.wait_for_unit("default.target")
-    machine.succeed(
-        "test $(nixos-container run simple -- readlink -f /run/current-system/sw/bin/hello) = ${customPkgs.hello}/bin/hello"
-    )
-  '';
+  # This test only consists of evaluating the test machine
+  testScript = "";
 })
diff --git a/nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix b/nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix
index d5c09172308c..1bdd064e1130 100644
--- a/nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix
+++ b/nixpkgs/nixos/tests/dnscrypt-wrapper/default.nix
@@ -31,6 +31,7 @@ import ../make-test-python.nix ({ pkgs, ... }: {
 
     client = { lib, ... }:
       { services.dnscrypt-proxy2.enable = true;
+        services.dnscrypt-proxy2.upstreamDefaults = false;
         services.dnscrypt-proxy2.settings = {
           server_names = [ "server" ];
           static.server.stamp = "sdns://AQAAAAAAAAAAEDE5Mi4xNjguMS4xOjUzNTMgFEHYOv0SCKSuqR5CDYa7-58cCBuXO2_5uTSVU9wNQF0WMi5kbnNjcnlwdC1jZXJ0LnNlcnZlcg";
diff --git a/nixpkgs/nixos/tests/hledger-web.nix b/nixpkgs/nixos/tests/hledger-web.nix
new file mode 100644
index 000000000000..378d819437db
--- /dev/null
+++ b/nixpkgs/nixos/tests/hledger-web.nix
@@ -0,0 +1,53 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+let
+  journal = pkgs.writeText "test.journal" ''
+    2010/01/10 Loan
+        assets:cash                 500$
+        income:loan                -500$
+    2010/01/10 NixOS Foundation donation
+        expenses:donation           250$
+        assets:cash                -250$
+  '';
+in
+rec {
+  name = "hledger-web";
+  meta.maintainers = with lib.maintainers; [ marijanp ];
+
+  nodes = {
+    server = { config, pkgs, ... }: rec {
+      services.hledger-web = {
+        host = "127.0.0.1";
+        port = 5000;
+        enable = true;
+        journalFile = journal;
+      };
+      networking.firewall.allowedTCPPorts = [ services.hledger-web.port ];
+    };
+    apiserver = { config, pkgs, ... }: rec {
+      services.hledger-web = {
+        host = "127.0.0.1";
+        port = 5000;
+        enable = true;
+        serveApi = true;
+        journalFile = journal;
+      };
+      networking.firewall.allowedTCPPorts = [ services.hledger-web.port ];
+    };
+  };
+
+  testScript = ''
+    start_all()
+
+    server.wait_for_unit("hledger-web.service")
+    server.wait_for_open_port(5000)
+    with subtest("Check if web UI is accessible"):
+        page = server.succeed("curl -L http://127.0.0.1:5000")
+        assert "test.journal" in page
+
+    apiserver.wait_for_unit("hledger-web.service")
+    apiserver.wait_for_open_port(5000)
+    with subtest("Check if the JSON API is served"):
+        transactions = apiserver.succeed("curl -L http://127.0.0.1:5000/transactions")
+        assert "NixOS Foundation donation" in transactions
+  '';
+})
diff --git a/nixpkgs/nixos/tests/hostname.nix b/nixpkgs/nixos/tests/hostname.nix
index e598549ef1d2..2e92b4259a6a 100644
--- a/nixpkgs/nixos/tests/hostname.nix
+++ b/nixpkgs/nixos/tests/hostname.nix
@@ -7,9 +7,12 @@ with import ../lib/testing-python.nix { inherit system pkgs; };
 with pkgs.lib;
 
 let
-  makeHostNameTest = hostName: domain:
+  makeHostNameTest = hostName: domain: fqdnOrNull:
     let
       fqdn = hostName + (optionalString (domain != null) ".${domain}");
+      getStr = str: # maybeString2String
+        let res = builtins.tryEval str;
+        in if (res.success && res.value != null) then res.value else "null";
     in
       makeTest {
         name = "hostname-${fqdn}";
@@ -26,13 +29,16 @@ let
           ];
         };
 
-        testScript = ''
+        testScript = { nodes, ... }: ''
           start_all()
 
           machine = ${hostName}
 
           machine.wait_for_unit("network-online.target")
 
+          # Test if NixOS computes the correct FQDN (either a FQDN or an error/null):
+          assert "${getStr nodes.machine.config.networking.fqdn}" == "${getStr fqdnOrNull}"
+
           # The FQDN, domain name, and hostname detection should work as expected:
           assert "${fqdn}" == machine.succeed("hostname --fqdn").strip()
           assert "${optionalString (domain != null) domain}" == machine.succeed("dnsdomainname").strip()
@@ -60,7 +66,7 @@ let
 
 in
 {
-  noExplicitDomain = makeHostNameTest "ahost" null;
+  noExplicitDomain = makeHostNameTest "ahost" null null;
 
-  explicitDomain = makeHostNameTest "ahost" "adomain";
+  explicitDomain = makeHostNameTest "ahost" "adomain" "ahost.adomain";
 }
diff --git a/nixpkgs/nixos/tests/installer.nix b/nixpkgs/nixos/tests/installer.nix
index 5fa4704d02b6..789add331b79 100644
--- a/nixpkgs/nixos/tests/installer.nix
+++ b/nixpkgs/nixos/tests/installer.nix
@@ -76,8 +76,8 @@ let
       def assemble_qemu_flags():
           flags = "-cpu max"
           ${if system == "x86_64-linux"
-            then ''flags += " -m 768"''
-            else ''flags += " -m 512 -enable-kvm -machine virt,gic-version=host"''
+            then ''flags += " -m 1024"''
+            else ''flags += " -m 768 -enable-kvm -machine virt,gic-version=host"''
           }
           return flags
 
diff --git a/nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix b/nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix
new file mode 100644
index 000000000000..11a3959e692e
--- /dev/null
+++ b/nixpkgs/nixos/tests/kernel-latest-ath-user-regd.nix
@@ -0,0 +1,17 @@
+import ./make-test-python.nix ({ pkgs, ...} : {
+  name = "kernel-latest-ath-user-regd";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ veehaitch ];
+  };
+
+  machine = { pkgs, ... }:
+    {
+      boot.kernelPackages = pkgs.linuxPackages_latest;
+      networking.wireless.athUserRegulatoryDomain = true;
+    };
+
+  testScript =
+    ''
+      assert "CONFIG_ATH_USER_REGD=y" in machine.succeed("zcat /proc/config.gz")
+    '';
+})
diff --git a/nixpkgs/nixos/tests/nextcloud/basic.nix b/nixpkgs/nixos/tests/nextcloud/basic.nix
index 78142d379664..900504470427 100644
--- a/nixpkgs/nixos/tests/nextcloud/basic.nix
+++ b/nixpkgs/nixos/tests/nextcloud/basic.nix
@@ -42,6 +42,7 @@ in {
           enable = true;
           startAt = "20:00";
         };
+        phpExtraExtensions = all: [ all.bz2 ];
       };
 
       environment.systemPackages = [ cfg.services.nextcloud.occ ];
diff --git a/nixpkgs/nixos/tests/pleroma.nix b/nixpkgs/nixos/tests/pleroma.nix
new file mode 100644
index 000000000000..797cac44f956
--- /dev/null
+++ b/nixpkgs/nixos/tests/pleroma.nix
@@ -0,0 +1,265 @@
+/*
+  Pleroma E2E VM test.
+
+  Abstract:
+  =========
+  Using pleroma, postgresql, a local CA cert, a nginx reverse proxy
+  and a toot-based client, we're going to:
+
+  1. Provision a pleroma service from scratch (pleroma config + postgres db).
+  2. Create a "jamy" admin user.
+  3. Send a toot from this user.
+  4. Send a upload from this user.
+  5. Check the toot is part of the server public timeline
+
+  Notes:
+  - We need a fully functional TLS setup without having any access to
+    the internet. We do that by issuing a self-signed cert, add this
+    self-cert to the hosts pki trust store and finally spoof the
+    hostnames using /etc/hosts.
+  - For this NixOS test, we *had* to store some DB-related and
+    pleroma-related secrets to the store. Keep in mind the store is
+    world-readable, it's the worst place possible to store *any*
+    secret. **DO NOT DO THIS IN A REAL WORLD DEPLOYMENT**.
+*/
+
+import ./make-test-python.nix ({ pkgs, ... }:
+  let
+  send-toot = pkgs.writeScriptBin "send-toot" ''
+    set -eux
+    # toot is using the requests library internally. This library
+    # sadly embed its own certificate store instead of relying on the
+    # system one. Overriding this pretty bad default behaviour.
+    export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
+
+    export TOOT_LOGIN_CLI_PASSWORD="jamy-password"
+    toot login_cli -i "pleroma.nixos.test" -e "jamy@nixos.test"
+    echo "Login OK"
+
+    # Send a toot then verify it's part of the public timeline
+    echo "y" | toot post "hello world Jamy here"
+    echo "Send toot OK"
+    echo "y" | toot timeline | grep -c "hello world Jamy here"
+    echo "Get toot from timeline OK"
+
+    # Test file upload
+    echo "y" | toot upload ${db-seed} | grep -c "https://pleroma.nixos.test/media"
+    echo "File upload OK"
+
+    echo "====================================================="
+    echo "=                   SUCCESS                         ="
+    echo "=                                                   ="
+    echo "=    We were able to sent a toot + a upload and     ="
+    echo "=   retrieve both of them in the public timeline.   ="
+    echo "====================================================="
+  '';
+
+  provision-db = pkgs.writeScriptBin "provision-db" ''
+    set -eux
+    sudo -u postgres psql -f ${db-seed}
+  '';
+
+  test-db-passwd = "SccZOvTGM//BMrpoQj68JJkjDkMGb4pHv2cECWiI+XhVe3uGJTLI0vFV/gDlZ5jJ";
+
+  /* For this NixOS test, we *had* to store this secret to the store.
+    Keep in mind the store is world-readable, it's the worst place
+    possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+    DEPLOYMENT**.*/
+  db-seed = pkgs.writeText "provision.psql" ''
+    CREATE USER pleroma WITH ENCRYPTED PASSWORD '${test-db-passwd}';
+    CREATE DATABASE pleroma OWNER pleroma;
+    \c pleroma;
+    --Extensions made by ecto.migrate that need superuser access
+    CREATE EXTENSION IF NOT EXISTS citext;
+    CREATE EXTENSION IF NOT EXISTS pg_trgm;
+    CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
+  '';
+
+  pleroma-conf = ''
+    import Config
+
+    config :pleroma, Pleroma.Web.Endpoint,
+       url: [host: "pleroma.nixos.test", scheme: "https", port: 443],
+       http: [ip: {127, 0, 0, 1}, port: 4000]
+
+    config :pleroma, :instance,
+      name: "NixOS test pleroma server",
+      email: "pleroma@nixos.test",
+      notify_email: "pleroma@nixos.test",
+      limit: 5000,
+      registrations_open: true
+
+    config :pleroma, :media_proxy,
+      enabled: false,
+      redirect_on_failure: true
+      #base_url: "https://cache.pleroma.social"
+
+    config :pleroma, Pleroma.Repo,
+      adapter: Ecto.Adapters.Postgres,
+      username: "pleroma",
+      password: "${test-db-passwd}",
+      database: "pleroma",
+      hostname: "localhost",
+      pool_size: 10,
+      prepare: :named,
+      parameters: [
+        plan_cache_mode: "force_custom_plan"
+      ]
+
+    config :pleroma, :database, rum_enabled: false
+    config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
+    config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
+    config :pleroma, configurable_from_database: false
+  '';
+
+  /* For this NixOS test, we *had* to store this secret to the store.
+    Keep in mind the store is world-readable, it's the worst place
+    possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+    DEPLOYMENT**.
+    In a real-word deployment, you'd handle this either by:
+    - manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
+    - use a deployment tool such as morph or NixOps to deploy your secrets.
+  */
+  pleroma-conf-secret = pkgs.writeText "secrets.exs" ''
+    import Config
+
+    config :joken, default_signer: "PS69/wMW7X6FIQPABt9lwvlZvgrJIncfiAMrK9J5mjVus/7/NJJi1DsDA1OghBE5"
+
+    config :pleroma, Pleroma.Web.Endpoint,
+       secret_key_base: "NvfmU7lYaQrmmxt4NACm0AaAfN9t6WxsrX0NCB4awkGHvr1S7jyshlEmrjaPFhhq",
+       signing_salt: "3L41+BuJ"
+
+    config :web_push_encryption, :vapid_details,
+      subject: "mailto:pleroma@nixos.test",
+      public_key: "BKjfNX9-UqAcncaNqERQtF7n9pKrB0-MO-juv6U5E5XQr_Tg5D-f8AlRjduAguDpyAngeDzG8MdrTejMSL4VF30",
+      private_key: "k7o9onKMQrgMjMb6l4fsxSaXO0BTNAer5MVSje3q60k"
+  '';
+
+  /* For this NixOS test, we *had* to store this secret to the store.
+    Keep in mind the store is world-readable, it's the worst place
+    possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+    DEPLOYMENT**.
+    In a real-word deployment, you'd handle this either by:
+    - manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
+    - use a deployment tool such as morph or NixOps to deploy your secrets.
+    */
+  provision-secrets = pkgs.writeScriptBin "provision-secrets" ''
+    set -eux
+    cp "${pleroma-conf-secret}" "/var/lib/pleroma/secrets.exs"
+    chown pleroma:pleroma /var/lib/pleroma/secrets.exs
+  '';
+
+  /* For this NixOS test, we *had* to store this secret to the store.
+    Keep in mind the store is world-readable, it's the worst place
+    possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
+    DEPLOYMENT**.
+  */
+  provision-user = pkgs.writeScriptBin "provision-user" ''
+    set -eux
+
+    # Waiting for pleroma to be up.
+    timeout 5m bash -c 'while [[ "$(curl -s -o /dev/null -w '%{http_code}' https://pleroma.nixos.test/api/v1/instance)" != "200" ]]; do sleep 2; done'
+    pleroma_ctl user new jamy jamy@nixos.test --password 'jamy-password' --moderator --admin -y
+  '';
+
+  tls-cert = pkgs.runCommandNoCC "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
+    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=pleroma.nixos.test'
+    mkdir -p $out
+    cp key.pem cert.pem $out
+  '';
+
+  /* Toot is preventing users from feeding login_cli a password non
+     interactively. While it makes sense most of the times, it's
+     preventing us to login in this non-interactive test. This patch
+     introduce a TOOT_LOGIN_CLI_PASSWORD env variable allowing us to
+     provide a password to toot login_cli
+
+     If https://github.com/ihabunek/toot/pull/180 gets merged at some
+     point, feel free to remove this patch. */
+  custom-toot = pkgs.toot.overrideAttrs(old:{
+    patches = [ (pkgs.fetchpatch {
+      url = "https://github.com/NinjaTrappeur/toot/commit/b4a4c30f41c0cb7e336714c2c4af9bc9bfa0c9f2.patch";
+      sha256 = "sha256-0xxNwjR/fStLjjUUhwzCCfrghRVts+fc+fvVJqVcaFg=";
+    }) ];
+  });
+
+  hosts = nodes: ''
+    ${nodes.pleroma.config.networking.primaryIPAddress} pleroma.nixos.test
+    ${nodes.client.config.networking.primaryIPAddress} client.nixos.test
+  '';
+  in {
+  name = "pleroma";
+  nodes = {
+    client = { nodes, pkgs, config, ... }: {
+      security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
+      networking.extraHosts = hosts nodes;
+      environment.systemPackages = with pkgs; [
+        custom-toot
+        send-toot
+      ];
+    };
+    pleroma = { nodes, pkgs, config, ... }: {
+      security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
+      networking.extraHosts = hosts nodes;
+      networking.firewall.enable = false;
+      environment.systemPackages = with pkgs; [
+        provision-db
+        provision-secrets
+        provision-user
+      ];
+      services = {
+        pleroma = {
+          enable = true;
+          configs = [
+            pleroma-conf
+          ];
+        };
+        postgresql = {
+          enable = true;
+          package = pkgs.postgresql_12;
+        };
+        nginx = {
+          enable = true;
+          virtualHosts."pleroma.nixos.test" = {
+            addSSL = true;
+            sslCertificate = "${tls-cert}/cert.pem";
+            sslCertificateKey = "${tls-cert}/key.pem";
+            locations."/" = {
+              proxyPass = "http://127.0.0.1:4000";
+              extraConfig = ''
+                add_header 'Access-Control-Allow-Origin' '*' always;
+                add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
+                add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
+                add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
+                if ($request_method = OPTIONS) {
+                    return 204;
+                }
+                add_header X-XSS-Protection "1; mode=block";
+                add_header X-Permitted-Cross-Domain-Policies none;
+                add_header X-Frame-Options DENY;
+                add_header X-Content-Type-Options nosniff;
+                add_header Referrer-Policy same-origin;
+                add_header X-Download-Options noopen;
+                proxy_http_version 1.1;
+                proxy_set_header Upgrade $http_upgrade;
+                proxy_set_header Connection "upgrade";
+                proxy_set_header Host $host;
+                client_max_body_size 16m;
+              '';
+            };
+          };
+        };
+      };
+    };
+  };
+
+  testScript = { nodes, ... }: ''
+    pleroma.wait_for_unit("postgresql.service")
+    pleroma.succeed("provision-db")
+    pleroma.succeed("provision-secrets")
+    pleroma.systemctl("restart pleroma.service")
+    pleroma.wait_for_unit("pleroma.service")
+    pleroma.succeed("provision-user")
+    client.succeed("send-toot")
+  '';
+})
diff --git a/nixpkgs/nixos/tests/power-profiles-daemon.nix b/nixpkgs/nixos/tests/power-profiles-daemon.nix
new file mode 100644
index 000000000000..e073677bee9d
--- /dev/null
+++ b/nixpkgs/nixos/tests/power-profiles-daemon.nix
@@ -0,0 +1,45 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+
+{
+  name = "power-profiles-daemon";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ mvnetbiz ];
+  };
+  machine = { pkgs, ... }: {
+    services.power-profiles-daemon.enable = true;
+    environment.systemPackages = [ pkgs.glib ];
+  };
+
+  testScript = ''
+    def get_profile():
+        return machine.succeed(
+            """gdbus call --system --dest net.hadess.PowerProfiles --object-path /net/hadess/PowerProfiles \
+    --method org.freedesktop.DBus.Properties.Get 'net.hadess.PowerProfiles' 'ActiveProfile'
+    """
+        )
+
+
+    def set_profile(profile):
+        return machine.succeed(
+            """gdbus call --system --dest net.hadess.PowerProfiles --object-path /net/hadess/PowerProfiles \
+    --method org.freedesktop.DBus.Properties.Set 'net.hadess.PowerProfiles' 'ActiveProfile' "<'{profile}'>"
+    """.format(
+                profile=profile
+            )
+        )
+
+
+    machine.wait_for_unit("multi-user.target")
+
+    set_profile("power-saver")
+    profile = get_profile()
+    if not "power-saver" in profile:
+        raise Exception("Unable to set power-saver profile")
+
+
+    set_profile("balanced")
+    profile = get_profile()
+    if not "balanced" in profile:
+        raise Exception("Unable to set balanced profile")
+  '';
+})
diff --git a/nixpkgs/nixos/tests/predictable-interface-names.nix b/nixpkgs/nixos/tests/predictable-interface-names.nix
index bab091d57acf..c0b472638a14 100644
--- a/nixpkgs/nixos/tests/predictable-interface-names.nix
+++ b/nixpkgs/nixos/tests/predictable-interface-names.nix
@@ -5,7 +5,11 @@
 
 let
   inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
-in pkgs.lib.listToAttrs (pkgs.lib.crossLists (predictable: withNetworkd: {
+  testCombinations = pkgs.lib.cartesianProductOfSets {
+    predictable = [true false];
+    withNetworkd = [true false];
+  };
+in pkgs.lib.listToAttrs (builtins.map ({ predictable, withNetworkd }: {
   name = pkgs.lib.optionalString (!predictable) "un" + "predictable"
        + pkgs.lib.optionalString withNetworkd "Networkd";
   value = makeTest {
@@ -30,4 +34,4 @@ in pkgs.lib.listToAttrs (pkgs.lib.crossLists (predictable: withNetworkd: {
       machine.${if predictable then "fail" else "succeed"}("ip link show eth0")
     '';
   };
-}) [[true false] [true false]])
+}) testCombinations)
diff --git a/nixpkgs/nixos/tests/rsyncd.nix b/nixpkgs/nixos/tests/rsyncd.nix
index 3639320f645d..44464e42f28d 100644
--- a/nixpkgs/nixos/tests/rsyncd.nix
+++ b/nixpkgs/nixos/tests/rsyncd.nix
@@ -2,24 +2,35 @@ import ./make-test-python.nix ({ pkgs, ... }: {
   name = "rsyncd";
   meta.maintainers = with pkgs.lib.maintainers; [ ehmry ];
 
-  nodes.machine.services.rsyncd = {
-    enable = true;
-    settings = {
-      global = {
-        "reverse lookup" = false;
-        "forward lookup" = false;
+  nodes = let
+    mkNode = socketActivated:
+      { config, ... }: {
+        networking.firewall.allowedTCPPorts = [ config.services.rsyncd.port ];
+        services.rsyncd = {
+          enable = true;
+          inherit socketActivated;
+          settings = {
+            global = {
+              "reverse lookup" = false;
+              "forward lookup" = false;
+            };
+            tmp = {
+              path = "/nix/store";
+              comment = "test module";
+            };
+          };
+        };
       };
-      tmp = {
-        path = "/nix/store";
-        comment = "test module";
-      };
-
-    };
+  in {
+    a = mkNode false;
+    b = mkNode true;
   };
 
   testScript = ''
     start_all()
-    machine.wait_for_unit("rsyncd")
-    machine.succeed("rsync localhost::")
+    a.wait_for_unit("rsync")
+    b.wait_for_unit("sockets.target")
+    b.succeed("rsync a::")
+    a.succeed("rsync b::")
   '';
 })
diff --git a/nixpkgs/nixos/tests/scala.nix b/nixpkgs/nixos/tests/scala.nix
deleted file mode 100644
index 4fc3f8aa7b0a..000000000000
--- a/nixpkgs/nixos/tests/scala.nix
+++ /dev/null
@@ -1,33 +0,0 @@
-{ system ? builtins.currentSystem,
-  config ? {},
-  pkgs ? import ../.. { inherit system config; }
-}:
-
-with pkgs.lib;
-
-let
-  common = name: package: (import ./make-test-python.nix ({
-    inherit name;
-    meta = with pkgs.lib.maintainers; {
-      maintainers = [ nequissimus ];
-    };
-
-    nodes = {
-      scala = { ... }: {
-        environment.systemPackages = [ package ];
-      };
-    };
-
-    testScript = ''
-      start_all()
-
-      scala.succeed("scalac -version 2>&1 | grep '^Scala compiler version ${package.version}'")
-    '';
-  }) { inherit system; });
-
-in with pkgs; {
-  scala_2_10  = common "scala_2_10"  scala_2_10;
-  scala_2_11  = common "scala_2_11"  scala_2_11;
-  scala_2_12  = common "scala_2_12"  scala_2_12;
-  scala_2_13  = common "scala_2_13"  scala_2_13;
-}
diff --git a/nixpkgs/nixos/tests/searx.nix b/nixpkgs/nixos/tests/searx.nix
index 22c1967b8160..7c28eea30d20 100644
--- a/nixpkgs/nixos/tests/searx.nix
+++ b/nixpkgs/nixos/tests/searx.nix
@@ -81,8 +81,9 @@ import ./make-test-python.nix ({ pkgs, ...} :
           base.wait_for_unit("searx-init")
           base.wait_for_file("/run/searx/settings.yml")
           output = base.succeed(
-              "${pkgs.yq-go}/bin/yq r /run/searx/settings.yml"
-              " 'engines.(name==startpage).shortcut'"
+              "${pkgs.yq-go}/bin/yq eval"
+              " '.engines[] | select(.name==\"startpage\") | .shortcut'"
+              " /run/searx/settings.yml"
           ).strip()
           assert output == "start", "Settings not merged"
 
diff --git a/nixpkgs/nixos/tests/smokeping.nix b/nixpkgs/nixos/tests/smokeping.nix
index 4ac672b814bd..ccacf60cfe4b 100644
--- a/nixpkgs/nixos/tests/smokeping.nix
+++ b/nixpkgs/nixos/tests/smokeping.nix
@@ -8,6 +8,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
     sm =
       { ... }:
       {
+        networking.domain = "example.com"; # FQDN: sm.example.com
         services.smokeping = {
           enable = true;
           port = 8081;
diff --git a/nixpkgs/nixos/tests/snapcast.nix b/nixpkgs/nixos/tests/snapcast.nix
index a69b7afe99da..2fef63625140 100644
--- a/nixpkgs/nixos/tests/snapcast.nix
+++ b/nixpkgs/nixos/tests/snapcast.nix
@@ -4,6 +4,8 @@ let
   port = 10004;
   tcpPort = 10005;
   httpPort = 10080;
+  tcpStreamPort = 10006;
+  bufferSize = 742;
 in {
   name = "snapcast";
   meta = with pkgs.lib.maintainers; {
@@ -17,18 +19,27 @@ in {
         port = port;
         tcp.port = tcpPort;
         http.port = httpPort;
+        buffer = bufferSize;
         streams = {
           mpd = {
             type = "pipe";
             location = "/run/snapserver/mpd";
+            query.mode = "create";
           };
           bluetooth = {
             type = "pipe";
             location = "/run/snapserver/bluetooth";
           };
+          tcp = {
+            type = "tcp";
+            location = "127.0.0.1:${toString tcpStreamPort}";
+          };
         };
       };
     };
+    client = {
+      environment.systemPackages = [ pkgs.snapcast ];
+    };
   };
 
   testScript = ''
@@ -42,6 +53,7 @@ in {
     server.wait_until_succeeds("ss -ntl | grep -q ${toString port}")
     server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpPort}")
     server.wait_until_succeeds("ss -ntl | grep -q ${toString httpPort}")
+    server.wait_until_succeeds("ss -ntl | grep -q ${toString tcpStreamPort}")
 
     with subtest("check that pipes are created"):
         server.succeed("test -p /run/snapserver/mpd")
@@ -54,5 +66,12 @@ in {
         server.succeed(
             "curl --fail http://localhost:${toString httpPort}/jsonrpc -d '{json.dumps(get_rpc_version)}'"
         )
+
+    with subtest("test a connection"):
+        client.execute("systemd-run snapclient -h server -p ${toString port}")
+        server.wait_until_succeeds(
+            "journalctl -o cat -u snapserver.service | grep -q 'Hello from'"
+        )
+        client.wait_until_succeeds("journalctl -o cat -u run-\* | grep -q ${toString bufferSize}")
   '';
 })
diff --git a/nixpkgs/nixos/tests/vault-postgresql.nix b/nixpkgs/nixos/tests/vault-postgresql.nix
index daa719763388..a563aead22a3 100644
--- a/nixpkgs/nixos/tests/vault-postgresql.nix
+++ b/nixpkgs/nixos/tests/vault-postgresql.nix
@@ -8,7 +8,7 @@
 import ./make-test-python.nix ({ pkgs, ... }:
 {
   name = "vault-postgresql";
-  meta = with pkgs.stdenv.lib.maintainers; {
+  meta = with pkgs.lib.maintainers; {
     maintainers = [ lnl7 roberth ];
   };
   machine = { lib, pkgs, ... }: {
diff --git a/nixpkgs/nixos/tests/vscodium.nix b/nixpkgs/nixos/tests/vscodium.nix
new file mode 100644
index 000000000000..ca75da35b1e1
--- /dev/null
+++ b/nixpkgs/nixos/tests/vscodium.nix
@@ -0,0 +1,47 @@
+import ./make-test-python.nix ({ pkgs, ...} :
+
+{
+  name = "vscodium";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ turion ];
+  };
+
+  machine = { ... }:
+
+  {
+    imports = [
+      ./common/user-account.nix
+      ./common/x11.nix
+    ];
+
+    virtualisation.memorySize = 2047;
+    services.xserver.enable = true;
+    test-support.displayManager.auto.user = "alice";
+    environment.systemPackages = with pkgs; [
+      vscodium
+    ];
+  };
+
+  enableOCR = true;
+
+  testScript = { nodes, ... }: ''
+    # Start up X
+    start_all()
+    machine.wait_for_x()
+
+    # Start VSCodium with a file that doesn't exist yet
+    machine.fail("ls /home/alice/foo.txt")
+    machine.succeed("su - alice -c 'codium foo.txt' &")
+
+    # Wait for the window to appear
+    machine.wait_for_text("VSCodium")
+
+    # Save file
+    machine.send_key("ctrl-s")
+
+    # Wait until the file has been saved
+    machine.wait_for_file("/home/alice/foo.txt")
+
+    machine.screenshot("VSCodium")
+  '';
+})
diff --git a/nixpkgs/nixos/tests/xmpp/prosody.nix b/nixpkgs/nixos/tests/xmpp/prosody.nix
index e7755e24bab4..2eb06d88287f 100644
--- a/nixpkgs/nixos/tests/xmpp/prosody.nix
+++ b/nixpkgs/nixos/tests/xmpp/prosody.nix
@@ -85,7 +85,7 @@ in import ../make-test-python.nix {
     server.succeed('prosodyctl status | grep "Prosody is running"')
 
     server.succeed("create-prosody-users")
-    client.succeed('send-message 2>&1 | grep "XMPP SCRIPT TEST SUCCESS"')
+    client.succeed("send-message")
     server.succeed("delete-prosody-users")
   '';
 }
diff --git a/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix b/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix
index 30945e68300a..47a77f524c6a 100644
--- a/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix
+++ b/nixpkgs/nixos/tests/xmpp/xmpp-sendmessage.nix
@@ -23,8 +23,26 @@ class CthonTest(ClientXMPP):
     def __init__(self, jid, password):
         ClientXMPP.__init__(self, jid, password)
         self.add_event_handler("session_start", self.session_start)
+        self.test_succeeded = False
 
     async def session_start(self, event):
+        try:
+            # Exceptions in event handlers are printed to stderr but not
+            # propagated, they do not make the script terminate with a non-zero
+            # exit code. We use the `test_succeeded` flag as a workaround and
+            # check it later at the end of the script to exit with a proper
+            # exit code.
+            # Additionally, this flag ensures that this event handler has been
+            # actually run by ClientXMPP, which may well not be the case.
+            await self.test_xmpp_server()
+            self.test_succeeded = True
+        finally:
+            # Even if an exception happens in `test_xmpp_server()`, we still
+            # need to disconnect explicitly, otherwise the process will hang
+            # forever.
+            self.disconnect(wait=True)
+
+    async def test_xmpp_server(self):
         log = logging.getLogger(__name__)
         self.send_presence()
         self.get_roster()
@@ -42,11 +60,12 @@ class CthonTest(ClientXMPP):
             log.error("ERROR: Cannot run upload command. XEP_0363 seems broken")
             sys.exit(1)
         log.info('Upload success!')
+
         # Test MUC
-        self.plugin['xep_0045'].join_muc('testMucRoom', 'cthon98', wait=True)
+        # TODO: use join_muc_wait() after slixmpp 1.8.0 is released.
+        self.plugin['xep_0045'].join_muc('testMucRoom', 'cthon98')
         log.info('MUC join success!')
         log.info('XMPP SCRIPT TEST SUCCESS')
-        self.disconnect(wait=True)
 
 
 if __name__ == '__main__':
@@ -62,4 +81,7 @@ if __name__ == '__main__':
     ct.register_plugin('xep_0045')
     ct.connect(("server", 5222))
     ct.process(forever=False)
+
+    if not ct.test_succeeded:
+        sys.exit(1)
 ''