1# Test printing via CUPS.
2
3import ./make-test.nix ({pkgs, ... }: {
4 name = "printing";
5 meta = with pkgs.stdenv.lib.maintainers; {
6 maintainers = [ domenkozar eelco chaoflow jgeerds ];
7 };
8
9 nodes = {
10
11 server =
12 { config, pkgs, ... }:
13 { services.printing.enable = true;
14 services.printing.listenAddresses = [ "*:631" ];
15 services.printing.defaultShared = true;
16 services.printing.extraConf =
17 ''
18 <Location />
19 Order allow,deny
20 Allow from all
21 </Location>
22 '';
23 networking.firewall.allowedTCPPorts = [ 631 ];
24 };
25
26 client =
27 { config, pkgs, nodes, ... }:
28 { services.printing.enable = true;
29 };
30
31 };
32
33 testScript =
34 ''
35 startAll;
36
37 # Make sure that cups is up on both sides.
38 $server->waitForUnit("cups.service");
39 $client->waitForUnit("cups.service");
40 $client->sleep(10); # wait until cups is fully initialized
41 $client->succeed("lpstat -r") =~ /scheduler is running/ or die;
42 $client->succeed("lpstat -H") =~ "/var/run/cups/cups.sock" or die;
43 $client->succeed("curl --fail http://localhost:631/");
44 $client->succeed("curl --fail http://server:631/");
45 $server->fail("curl --fail --connect-timeout 2 http://client:631/");
46
47 # Add a HP Deskjet printer connected via USB to the server.
48 $server->succeed("lpadmin -p DeskjetLocal -E -v usb://foobar/printers/foobar");
49
50 # Add it to the client as well via IPP.
51 $client->succeed("lpadmin -p DeskjetRemote -E -v ipp://server/printers/DeskjetLocal");
52 $client->succeed("lpadmin -d DeskjetRemote");
53
54 # Do some status checks.
55 $client->succeed("lpstat -a") =~ /DeskjetRemote accepting requests/ or die;
56 $client->succeed("lpstat -h server:631 -a") =~ /DeskjetLocal accepting requests/ or die;
57 $client->succeed("cupsdisable DeskjetRemote");
58 $client->succeed("lpq") =~ /DeskjetRemote is not ready.*no entries/s or die;
59 $client->succeed("cupsenable DeskjetRemote");
60 $client->succeed("lpq") =~ /DeskjetRemote is ready.*no entries/s or die;
61
62 # Test printing various file types.
63 foreach my $file ("${pkgs.groff.doc}/share/doc/*/examples/mom/penguin.pdf",
64 "${pkgs.groff.doc}/share/doc/*/meref.ps",
65 "${pkgs.cups.out}/share/doc/cups/images/cups.png",
66 "${pkgs.pcre.doc}/share/doc/pcre/pcre.txt")
67 {
68 $file =~ /([^\/]*)$/; my $fn = $1;
69
70 subtest "print $fn", sub {
71
72 # Print the file on the client.
73 $client->succeed("lp $file");
74 $client->sleep(10);
75 $client->succeed("lpq") =~ /active.*root.*$fn/ or die;
76
77 # Ensure that a raw PCL file appeared in the server's queue
78 # (showing that the right filters have been applied). Of
79 # course, since there is no actual USB printer attached, the
80 # file will stay in the queue forever.
81 $server->waitForFile("/var/spool/cups/d*-001");
82 $server->sleep(10);
83 $server->succeed("lpq -a") =~ /$fn/ or die;
84
85 # Delete the job on the client. It should disappear on the
86 # server as well.
87 $client->succeed("lprm");
88 $client->sleep(10);
89 $client->succeed("lpq -a") =~ /no entries/;
90 Machine::retry sub {
91 return 1 if $server->succeed("lpq -a") =~ /no entries/;
92 };
93 # The queue is empty already, so this should be safe.
94 # Otherwise, pairs of "c*"-"d*-001" files might persist.
95 $server->execute("rm /var/spool/cups/*");
96 };
97 }
98 '';
99})