From 4f67365482305a0fec444b725b131c82c563982b Mon Sep 17 00:00:00 2001
From: rnhmjoj <rnhmjoj@inventati.org>
Date: Wed, 7 Dec 2022 15:52:08 +0100
Subject: [PATCH] nixos/tests/printing: split into service/socket

This splits the tests into two: one where cups.socket is started
normally, the order with socket activation.

Why? It's almost impossible to follow the test with 4 different
machines printing at the same time. It should also be more efficient
because only two VMs at a time were needed anyway.
---
 nixos/release-combined.nix |   3 +-
 nixos/tests/all-tests.nix  |   3 +-
 nixos/tests/printing.nix   | 177 ++++++++++++++++++-------------------
 3 files changed, 89 insertions(+), 94 deletions(-)

diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix
index 337b5192776f..ed698b63ee63 100644
--- a/nixos/release-combined.nix
+++ b/nixos/release-combined.nix
@@ -146,7 +146,8 @@ in rec {
         (onFullSupported "nixos.tests.predictable-interface-names.predictable")
         (onFullSupported "nixos.tests.predictable-interface-names.unpredictableNetworkd")
         (onFullSupported "nixos.tests.predictable-interface-names.unpredictable")
-        (onFullSupported "nixos.tests.printing")
+        (onFullSupported "nixos.tests.printing-service")
+        (onFullSupported "nixos.tests.printing-socket")
         (onFullSupported "nixos.tests.proxy")
         (onFullSupported "nixos.tests.sddm.default")
         (onFullSupported "nixos.tests.shadow")
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 726884d7cd9c..6a14c575662d 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -525,7 +525,8 @@ in {
   power-profiles-daemon = handleTest ./power-profiles-daemon.nix {};
   pppd = handleTest ./pppd.nix {};
   predictable-interface-names = handleTest ./predictable-interface-names.nix {};
-  printing = handleTest ./printing.nix {};
+  printing-socket = handleTest ./printing.nix { socket = true; };
+  printing-service = handleTest ./printing.nix { socket = false; };
   privacyidea = handleTest ./privacyidea.nix {};
   privoxy = handleTest ./privoxy.nix {};
   prometheus = handleTest ./prometheus.nix {};
diff --git a/nixos/tests/printing.nix b/nixos/tests/printing.nix
index cfebe232d92a..7df042e72e90 100644
--- a/nixos/tests/printing.nix
+++ b/nixos/tests/printing.nix
@@ -1,19 +1,31 @@
 # Test printing via CUPS.
 
-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;
-    services.printing.extraConf = ''
-      <Location />
-        Order allow,deny
-        Allow from all
-      </Location>
-    '';
+import ./make-test-python.nix (
+{ pkgs
+, socket ? true # whether to use socket activation
+, ...
+}:
+
+{
+  name = "printing";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ domenkozar eelco matthewbauer ];
+  };
+
+  nodes.server = { ... }: {
+    services.printing = {
+      enable = true;
+      stateless = true;
+      startWhenNeeded = socket;
+      listenAddresses = [ "*:631" ];
+      defaultShared = true;
+      extraConf = ''
+        <Location />
+          Order allow,deny
+          Allow from all
+        </Location>
+      '';
+    };
     networking.firewall.allowedTCPPorts = [ 631 ];
     # Add a HP Deskjet printer connected via USB to the server.
     hardware.printers.ensurePrinters = [{
@@ -22,32 +34,19 @@ let
       model = "drv:///sample.drv/deskjet.ppd";
     }];
   };
-  printingClient = startWhenNeeded: {
+
+  nodes.client = { ... }: {
     services.printing.enable = true;
-    services.printing.startWhenNeeded = startWhenNeeded;
+    services.printing.startWhenNeeded = socket;
     # Add printer to the client as well, via IPP.
     hardware.printers.ensurePrinters = [{
       name = "DeskjetRemote";
-      deviceUri = "ipp://${if startWhenNeeded then "socketActivatedServer" else "serviceServer"}/printers/DeskjetLocal";
+      deviceUri = "ipp://server/printers/DeskjetLocal";
       model = "drv:///sample.drv/deskjet.ppd";
     }];
     hardware.printers.ensureDefaultPrinter = "DeskjetRemote";
   };
 
-in {
-  name = "printing";
-  meta = with pkgs.lib.maintainers; {
-    maintainers = [ domenkozar eelco matthewbauer ];
-  };
-
-  nodes = {
-    socketActivatedServer = { ... }: (printingServer true);
-    serviceServer = { ... }: (printingServer false);
-
-    socketActivatedClient = { ... }: (printingClient true);
-    serviceClient = { ... }: (printingClient false);
-  };
-
   testScript = ''
     import os
     import re
@@ -55,75 +54,69 @@ in {
     start_all()
 
     with subtest("Make sure that cups is up on both sides and printers are set up"):
-        serviceServer.wait_for_unit("cups.service")
-        serviceClient.wait_for_unit("cups.service")
-        socketActivatedClient.wait_for_unit("ensure-printers.service")
+        server.wait_for_unit("cups.${if socket then "socket" else "service"}")
+        client.wait_for_unit("cups.${if socket then "socket" else "service"}")
 
+    assert "scheduler is running" in client.succeed("lpstat -r")
 
-    def test_printing(client, server):
-        assert "scheduler is running" in client.succeed("lpstat -r")
+    with subtest("UNIX socket is used for connections"):
+        assert "/var/run/cups/cups.sock" in client.succeed("lpstat -H")
 
-        with subtest("UNIX socket is used for connections"):
-            assert "/var/run/cups/cups.sock" in client.succeed("lpstat -H")
-        with subtest("HTTP server is available too"):
-            client.succeed("curl --fail http://localhost:631/")
-            client.succeed(f"curl --fail http://{server.name}:631/")
-            server.fail(f"curl --fail --connect-timeout 2 http://{client.name}:631/")
+    with subtest("HTTP server is available too"):
+        client.succeed("curl --fail http://localhost:631/")
+        client.succeed(f"curl --fail http://{server.name}:631/")
+        server.fail(f"curl --fail --connect-timeout 2 http://{client.name}:631/")
 
-        with subtest("LP status checks"):
-            assert "DeskjetRemote accepting requests" in client.succeed("lpstat -a")
-            assert "DeskjetLocal accepting requests" in client.succeed(
-                f"lpstat -h {server.name}:631 -a"
-            )
-            client.succeed("cupsdisable DeskjetRemote")
-            out = client.succeed("lpq")
-            print(out)
-            assert re.search(
-                "DeskjetRemote is not ready.*no entries",
-                client.succeed("lpq"),
-                flags=re.DOTALL,
-            )
-            client.succeed("cupsenable DeskjetRemote")
-            assert re.match(
-                "DeskjetRemote is ready.*no entries", client.succeed("lpq"), flags=re.DOTALL
+    with subtest("LP status checks"):
+        assert "DeskjetRemote accepting requests" in client.succeed("lpstat -a")
+        assert "DeskjetLocal accepting requests" in client.succeed(
+            f"lpstat -h {server.name}:631 -a"
+        )
+        client.succeed("cupsdisable DeskjetRemote")
+        out = client.succeed("lpq")
+        print(out)
+        assert re.search(
+            "DeskjetRemote is not ready.*no entries",
+            client.succeed("lpq"),
+            flags=re.DOTALL,
+        )
+        client.succeed("cupsenable DeskjetRemote")
+        assert re.match(
+            "DeskjetRemote is ready.*no entries", client.succeed("lpq"), flags=re.DOTALL
+        )
+
+    # Test printing various file types.
+    for file in [
+        "${pkgs.groff.doc}/share/doc/*/examples/mom/penguin.pdf",
+        "${pkgs.groff.doc}/share/doc/*/meref.ps",
+        "${pkgs.cups.out}/share/doc/cups/images/cups.png",
+        "${pkgs.pcre.doc}/share/doc/pcre/pcre.txt",
+    ]:
+        file_name = os.path.basename(file)
+        with subtest(f"print {file_name}"):
+            # Print the file on the client.
+            print(client.succeed("lpq"))
+            client.succeed(f"lp {file}")
+            client.wait_until_succeeds(
+                f"lpq; lpq | grep -q -E 'active.*root.*{file_name}'"
             )
 
-        # Test printing various file types.
-        for file in [
-            "${pkgs.groff.doc}/share/doc/*/examples/mom/penguin.pdf",
-            "${pkgs.groff.doc}/share/doc/*/meref.ps",
-            "${pkgs.cups.out}/share/doc/cups/images/cups.png",
-            "${pkgs.pcre.doc}/share/doc/pcre/pcre.txt",
-        ]:
-            file_name = os.path.basename(file)
-            with subtest(f"print {file_name}"):
-                # Print the file on the client.
-                print(client.succeed("lpq"))
-                client.succeed(f"lp {file}")
-                client.wait_until_succeeds(
-                    f"lpq; lpq | grep -q -E 'active.*root.*{file_name}'"
-                )
+            # Ensure that a raw PCL file appeared in the server's queue
+            # (showing that the right filters have been applied).  Of
+            # course, since there is no actual USB printer attached, the
+            # file will stay in the queue forever.
+            server.wait_for_file("/var/spool/cups/d*-001")
+            server.wait_until_succeeds(f"lpq -a | grep -q -E '{file_name}'")
 
-                # Ensure that a raw PCL file appeared in the server's queue
-                # (showing that the right filters have been applied).  Of
-                # course, since there is no actual USB printer attached, the
-                # file will stay in the queue forever.
-                server.wait_for_file("/var/spool/cups/d*-001")
-                server.wait_until_succeeds(f"lpq -a | grep -q -E '{file_name}'")
+            # Delete the job on the client.  It should disappear on the
+            # server as well.
+            client.succeed("lprm")
+            client.wait_until_succeeds("lpq -a | grep -q -E 'no entries'")
 
-                # Delete the job on the client.  It should disappear on the
-                # server as well.
-                client.succeed("lprm")
-                client.wait_until_succeeds("lpq -a | grep -q -E 'no entries'")
+            retry(lambda _: "no entries" in server.succeed("lpq -a"))
 
-                retry(lambda _: "no entries" in server.succeed("lpq -a"))
-
-                # The queue is empty already, so this should be safe.
-                # Otherwise, pairs of "c*"-"d*-001" files might persist.
-                server.execute("rm /var/spool/cups/*")
-
-
-    test_printing(serviceClient, serviceServer)
-    test_printing(socketActivatedClient, socketActivatedServer)
+            # The queue is empty already, so this should be safe.
+            # Otherwise, pairs of "c*"-"d*-001" files might persist.
+            server.execute("rm /var/spool/cups/*")
   '';
 })