···
# Test printing via CUPS.
3
-
import ./make-test-python.nix ({pkgs, ... }:
5
-
printingServer = startWhenNeeded: {
6
-
services.printing.enable = true;
7
-
services.printing.stateless = true;
8
-
services.printing.startWhenNeeded = startWhenNeeded;
9
-
services.printing.listenAddresses = [ "*:631" ];
10
-
services.printing.defaultShared = true;
11
-
services.printing.extraConf = ''
3
+
import ./make-test-python.nix (
5
+
, socket ? true # whether to use socket activation
11
+
meta = with pkgs.lib.maintainers; {
12
+
maintainers = [ domenkozar eelco matthewbauer ];
15
+
nodes.server = { ... }: {
16
+
services.printing = {
19
+
startWhenNeeded = socket;
20
+
listenAddresses = [ "*:631" ];
21
+
defaultShared = true;
networking.firewall.allowedTCPPorts = [ 631 ];
# Add a HP Deskjet printer connected via USB to the server.
hardware.printers.ensurePrinters = [{
···
model = "drv:///sample.drv/deskjet.ppd";
25
-
printingClient = startWhenNeeded: {
38
+
nodes.client = { ... }: {
services.printing.enable = true;
27
-
services.printing.startWhenNeeded = startWhenNeeded;
40
+
services.printing.startWhenNeeded = socket;
# Add printer to the client as well, via IPP.
hardware.printers.ensurePrinters = [{
31
-
deviceUri = "ipp://${if startWhenNeeded then "socketActivatedServer" else "serviceServer"}/printers/DeskjetLocal";
44
+
deviceUri = "ipp://server/printers/DeskjetLocal";
model = "drv:///sample.drv/deskjet.ppd";
hardware.printers.ensureDefaultPrinter = "DeskjetRemote";
39
-
meta = with pkgs.lib.maintainers; {
40
-
maintainers = [ domenkozar eelco matthewbauer ];
44
-
socketActivatedServer = { ... }: (printingServer true);
45
-
serviceServer = { ... }: (printingServer false);
47
-
socketActivatedClient = { ... }: (printingClient true);
48
-
serviceClient = { ... }: (printingClient false);
···
with subtest("Make sure that cups is up on both sides and printers are set up"):
58
-
serviceServer.wait_for_unit("cups.service")
59
-
serviceClient.wait_for_unit("cups.service")
60
-
socketActivatedClient.wait_for_unit("ensure-printers.service")
57
+
server.wait_for_unit("cups.${if socket then "socket" else "service"}")
58
+
client.wait_for_unit("cups.${if socket then "socket" else "service"}")
60
+
assert "scheduler is running" in client.succeed("lpstat -r")
63
-
def test_printing(client, server):
64
-
assert "scheduler is running" in client.succeed("lpstat -r")
62
+
with subtest("UNIX socket is used for connections"):
63
+
assert "/var/run/cups/cups.sock" in client.succeed("lpstat -H")
65
+
with subtest("HTTP server is available too"):
66
+
client.succeed("curl --fail http://localhost:631/")
67
+
client.succeed(f"curl --fail http://{server.name}:631/")
68
+
server.fail(f"curl --fail --connect-timeout 2 http://{client.name}:631/")
66
-
with subtest("UNIX socket is used for connections"):
67
-
assert "/var/run/cups/cups.sock" in client.succeed("lpstat -H")
68
-
with subtest("HTTP server is available too"):
69
-
client.succeed("curl --fail http://localhost:631/")
70
-
client.succeed(f"curl --fail http://{server.name}:631/")
71
-
server.fail(f"curl --fail --connect-timeout 2 http://{client.name}:631/")
70
+
with subtest("LP status checks"):
71
+
assert "DeskjetRemote accepting requests" in client.succeed("lpstat -a")
72
+
assert "DeskjetLocal accepting requests" in client.succeed(
73
+
f"lpstat -h {server.name}:631 -a"
75
+
client.succeed("cupsdisable DeskjetRemote")
76
+
out = client.succeed("lpq")
79
+
"DeskjetRemote is not ready.*no entries",
80
+
client.succeed("lpq"),
83
+
client.succeed("cupsenable DeskjetRemote")
85
+
"DeskjetRemote is ready.*no entries", client.succeed("lpq"), flags=re.DOTALL
73
-
with subtest("LP status checks"):
74
-
assert "DeskjetRemote accepting requests" in client.succeed("lpstat -a")
75
-
assert "DeskjetLocal accepting requests" in client.succeed(
76
-
f"lpstat -h {server.name}:631 -a"
78
-
client.succeed("cupsdisable DeskjetRemote")
79
-
out = client.succeed("lpq")
82
-
"DeskjetRemote is not ready.*no entries",
83
-
client.succeed("lpq"),
86
-
client.succeed("cupsenable DeskjetRemote")
88
-
"DeskjetRemote is ready.*no entries", client.succeed("lpq"), flags=re.DOTALL
88
+
# Test printing various file types.
90
+
"${pkgs.groff.doc}/share/doc/*/examples/mom/penguin.pdf",
91
+
"${pkgs.groff.doc}/share/doc/*/meref.ps",
92
+
"${pkgs.cups.out}/share/doc/cups/images/cups.png",
93
+
"${pkgs.pcre.doc}/share/doc/pcre/pcre.txt",
95
+
file_name = os.path.basename(file)
96
+
with subtest(f"print {file_name}"):
97
+
# Print the file on the client.
98
+
print(client.succeed("lpq"))
99
+
client.succeed(f"lp {file}")
100
+
client.wait_until_succeeds(
101
+
f"lpq; lpq | grep -q -E 'active.*root.*{file_name}'"
91
-
# Test printing various file types.
93
-
"${pkgs.groff.doc}/share/doc/*/examples/mom/penguin.pdf",
94
-
"${pkgs.groff.doc}/share/doc/*/meref.ps",
95
-
"${pkgs.cups.out}/share/doc/cups/images/cups.png",
96
-
"${pkgs.pcre.doc}/share/doc/pcre/pcre.txt",
98
-
file_name = os.path.basename(file)
99
-
with subtest(f"print {file_name}"):
100
-
# Print the file on the client.
101
-
print(client.succeed("lpq"))
102
-
client.succeed(f"lp {file}")
103
-
client.wait_until_succeeds(
104
-
f"lpq; lpq | grep -q -E 'active.*root.*{file_name}'"
107
-
# Ensure that a raw PCL file appeared in the server's queue
108
-
# (showing that the right filters have been applied). Of
109
-
# course, since there is no actual USB printer attached, the
110
-
# file will stay in the queue forever.
111
-
server.wait_for_file("/var/spool/cups/d*-001")
112
-
server.wait_until_succeeds(f"lpq -a | grep -q -E '{file_name}'")
114
-
# Delete the job on the client. It should disappear on the
116
-
client.succeed("lprm")
117
-
client.wait_until_succeeds("lpq -a | grep -q -E 'no entries'")
104
+
# Ensure that a raw PCL file appeared in the server's queue
105
+
# (showing that the right filters have been applied). Of
106
+
# course, since there is no actual USB printer attached, the
107
+
# file will stay in the queue forever.
108
+
server.wait_for_file("/var/spool/cups/d*-001")
109
+
server.wait_until_succeeds(f"lpq -a | grep -q -E '{file_name}'")
119
-
retry(lambda _: "no entries" in server.succeed("lpq -a"))
121
-
# The queue is empty already, so this should be safe.
122
-
# Otherwise, pairs of "c*"-"d*-001" files might persist.
123
-
server.execute("rm /var/spool/cups/*")
111
+
# Delete the job on the client. It should disappear on the
113
+
client.succeed("lprm")
114
+
client.wait_until_succeeds("lpq -a | grep -q -E 'no entries'")
116
+
retry(lambda _: "no entries" in server.succeed("lpq -a"))
126
-
test_printing(serviceClient, serviceServer)
127
-
test_printing(socketActivatedClient, socketActivatedServer)
118
+
# The queue is empty already, so this should be safe.
119
+
# Otherwise, pairs of "c*"-"d*-001" files might persist.
120
+
server.execute("rm /var/spool/cups/*")