From 18a5d23b55d0b0d1bff6bfd971d471d3064011c2 Mon Sep 17 00:00:00 2001 From: Florian Jacob Date: Mon, 5 Aug 2019 20:24:18 +0200 Subject: nixos/printers: declarative configuration --- nixos/tests/printing.nix | 177 +++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 81 deletions(-) (limited to 'nixos/tests') diff --git a/nixos/tests/printing.nix b/nixos/tests/printing.nix index 74583ae5562..4d0df289cf7 100644 --- a/nixos/tests/printing.nix +++ b/nixos/tests/printing.nix @@ -1,99 +1,114 @@ # Test printing via CUPS. -import ./make-test.nix ({pkgs, ... }: { +import ./make-test.nix ({pkgs, ... }: +let + printingServer = startWhenNeeded: { + services.printing.enable = true; + services.printing.startWhenNeeded = startWhenNeeded; + services.printing.listenAddresses = [ "*:631" ]; + services.printing.defaultShared = true; + services.printing.extraConf = + '' + + Order allow,deny + Allow from all + + ''; + networking.firewall.allowedTCPPorts = [ 631 ]; + # Add a HP Deskjet printer connected via USB to the server. + hardware.printers.ensurePrinters = [{ + name = "DeskjetLocal"; + deviceUri = "usb://foobar/printers/foobar"; + model = "drv:///sample.drv/deskjet.ppd"; + }]; + }; + printingClient = startWhenNeeded: { + services.printing.enable = true; + services.printing.startWhenNeeded = startWhenNeeded; + # Add printer to the client as well, via IPP. + hardware.printers.ensurePrinters = [{ + name = "DeskjetRemote"; + deviceUri = "ipp://${if startWhenNeeded then "socketActivatedServer" else "serviceServer"}/printers/DeskjetLocal"; + model = "drv:///sample.drv/deskjet.ppd"; + }]; + hardware.printers.ensureDefaultPrinter = "DeskjetRemote"; + }; + +in + +{ name = "printing"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ domenkozar eelco matthewbauer ]; }; nodes = { + socketActivatedServer = { ... }: (printingServer true); + serviceServer = { ... }: (printingServer false); - server = - { ... }: - { services.printing.enable = true; - services.printing.listenAddresses = [ "*:631" ]; - services.printing.defaultShared = true; - services.printing.extraConf = - '' - - Order allow,deny - Allow from all - - ''; - networking.firewall.allowedTCPPorts = [ 631 ]; - }; - - client = - { ... }: - { services.printing.enable = true; - }; - + socketActivatedClient = { ... }: (printingClient true); + serviceClient = { ... }: (printingClient false); }; testScript = '' startAll; - $client->succeed("lpstat -r") =~ /scheduler is running/ or die; - # check local encrypted connections work without error - $client->succeed("lpstat -E -r") =~ /scheduler is running/ or die; - # Test that UNIX socket is used for connections. - $client->succeed("lpstat -H") =~ "/run/cups/cups.sock" or die; - # Test that HTTP server is available too. - $client->succeed("curl --fail http://localhost:631/"); - $client->succeed("curl --fail http://server:631/"); - $server->fail("curl --fail --connect-timeout 2 http://client:631/"); - - # Add a HP Deskjet printer connected via USB to the server. - $server->succeed("lpadmin -p DeskjetLocal -E -v usb://foobar/printers/foobar"); - - # Add it to the client as well via IPP. - $client->succeed("lpadmin -p DeskjetRemote -E -v ipp://server/printers/DeskjetLocal"); - $client->succeed("lpadmin -d DeskjetRemote"); - - # Do some status checks. - $client->succeed("lpstat -a") =~ /DeskjetRemote accepting requests/ or die; - $client->succeed("lpstat -h server:631 -a") =~ /DeskjetLocal accepting requests/ or die; - $client->succeed("cupsdisable DeskjetRemote"); - $client->succeed("lpq") =~ /DeskjetRemote is not ready.*no entries/s or die; - $client->succeed("cupsenable DeskjetRemote"); - $client->succeed("lpq") =~ /DeskjetRemote is ready.*no entries/s or die; - - # Test printing various file types. - foreach my $file ("${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 =~ /([^\/]*)$/; my $fn = $1; - - subtest "print $fn", sub { - - # Print the file on the client. - $client->succeed("lp $file"); - $client->sleep(10); - $client->succeed("lpq") =~ /active.*root.*$fn/ or die; - - # 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->waitForFile("/var/spool/cups/d*-001"); - $server->sleep(10); - $server->succeed("lpq -a") =~ /$fn/ or die; - - # Delete the job on the client. It should disappear on the - # server as well. - $client->succeed("lprm"); - $client->sleep(10); - $client->succeed("lpq -a") =~ /no entries/; - Machine::retry sub { - return 1 if $server->succeed("lpq -a") =~ /no entries/; + # Make sure that cups is up on both sides. + $serviceServer->waitForUnit("cups.service"); + $serviceClient->waitForUnit("cups.service"); + # wait until cups is fully initialized and ensure-printers has executed with 10s delay + $serviceClient->sleep(20); + $socketActivatedClient->waitUntilSucceeds("systemctl status ensure-printers | grep -q -E 'code=exited, status=0/SUCCESS'"); + sub testPrinting { + my ($client, $server) = (@_); + my $clientHostname = $client->name(); + my $serverHostname = $server->name(); + $client->succeed("lpstat -r") =~ /scheduler is running/ or die; + # Test that UNIX socket is used for connections. + $client->succeed("lpstat -H") =~ "/var/run/cups/cups.sock" or die; + # Test that HTTP server is available too. + $client->succeed("curl --fail http://localhost:631/"); + $client->succeed("curl --fail http://$serverHostname:631/"); + $server->fail("curl --fail --connect-timeout 2 http://$clientHostname:631/"); + # Do some status checks. + $client->succeed("lpstat -a") =~ /DeskjetRemote accepting requests/ or die; + $client->succeed("lpstat -h $serverHostname:631 -a") =~ /DeskjetLocal accepting requests/ or die; + $client->succeed("cupsdisable DeskjetRemote"); + $client->succeed("lpq") =~ /DeskjetRemote is not ready.*no entries/s or die; + $client->succeed("cupsenable DeskjetRemote"); + $client->succeed("lpq") =~ /DeskjetRemote is ready.*no entries/s or die; + # Test printing various file types. + foreach my $file ("${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 =~ /([^\/]*)$/; my $fn = $1; + subtest "print $fn", sub { + # Print the file on the client. + $client->succeed("lp $file"); + $client->waitUntilSucceeds("lpq | grep -q -E 'active.*root.*$fn'"); + # 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->waitForFile("/var/spool/cups/d*-001"); + $server->waitUntilSucceeds("lpq -a | grep -q -E '$fn'"); + # Delete the job on the client. It should disappear on the + # server as well. + $client->succeed("lprm"); + $client->waitUntilSucceeds("lpq -a | grep -q -E 'no entries'"); + Machine::retry sub { + return 1 if $server->succeed("lpq -a") =~ /no entries/; + }; + # 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/*"); }; - # 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/*"); - }; + } } - ''; + testPrinting($serviceClient, $serviceServer); + testPrinting($socketActivatedClient, $socketActivatedServer); + ''; }) -- cgit v1.2.3