nixosTests.printing: Port to Python

This commit is contained in:
Jacek Galowicz 2020-02-06 11:29:23 +01:00
parent 484ea7bbac
commit bc7444384f

View File

@ -1,19 +1,18 @@
# Test printing via CUPS. # Test printing via CUPS.
import ./make-test.nix ({pkgs, ... }: import ./make-test-python.nix ({pkgs, ... }:
let let
printingServer = startWhenNeeded: { printingServer = startWhenNeeded: {
services.printing.enable = true; services.printing.enable = true;
services.printing.startWhenNeeded = startWhenNeeded; services.printing.startWhenNeeded = startWhenNeeded;
services.printing.listenAddresses = [ "*:631" ]; services.printing.listenAddresses = [ "*:631" ];
services.printing.defaultShared = true; services.printing.defaultShared = true;
services.printing.extraConf = services.printing.extraConf = ''
'' <Location />
<Location /> Order allow,deny
Order allow,deny Allow from all
Allow from all </Location>
</Location> '';
'';
networking.firewall.allowedTCPPorts = [ 631 ]; networking.firewall.allowedTCPPorts = [ 631 ];
# Add a HP Deskjet printer connected via USB to the server. # Add a HP Deskjet printer connected via USB to the server.
hardware.printers.ensurePrinters = [{ hardware.printers.ensurePrinters = [{
@ -34,9 +33,7 @@ let
hardware.printers.ensureDefaultPrinter = "DeskjetRemote"; hardware.printers.ensureDefaultPrinter = "DeskjetRemote";
}; };
in in {
{
name = "printing"; name = "printing";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ domenkozar eelco matthewbauer ]; maintainers = [ domenkozar eelco matthewbauer ];
@ -50,65 +47,91 @@ in
serviceClient = { ... }: (printingClient false); serviceClient = { ... }: (printingClient false);
}; };
testScript = testScript = ''
'' import os
startAll; import re
import sys
# Make sure that cups is up on both sides. start_all()
$serviceServer->waitForUnit("cups.service");
$serviceClient->waitForUnit("cups.service"); with subtest("Make sure that cups is up on both sides"):
# wait until cups is fully initialized and ensure-printers has executed with 10s delay serviceServer.wait_for_unit("cups.service")
$serviceClient->sleep(20); serviceClient.wait_for_unit("cups.service")
$socketActivatedClient->waitUntilSucceeds("systemctl status ensure-printers | grep -q -E 'code=exited, status=0/SUCCESS'");
sub testPrinting { with subtest(
my ($client, $server) = (@_); "Wait until cups is fully initialized and ensure-printers has "
my $clientHostname = $client->name(); "executed with 10s delay"
my $serverHostname = $server->name(); ):
$client->succeed("lpstat -r") =~ /scheduler is running/ or die; serviceClient.sleep(20)
# Test that UNIX socket is used for connections. socketActivatedClient.wait_until_succeeds(
$client->succeed("lpstat -H") =~ "/var/run/cups/cups.sock" or die; "systemctl status ensure-printers | grep -q -E 'code=exited, status=0/SUCCESS'"
# 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/"); def test_printing(client, server):
# Do some status checks. assert "scheduler is running" in client.succeed("lpstat -r")
$client->succeed("lpstat -a") =~ /DeskjetRemote accepting requests/ or die;
$client->succeed("lpstat -h $serverHostname:631 -a") =~ /DeskjetLocal accepting requests/ or die; with subtest("UNIX socket is used for connections"):
$client->succeed("cupsdisable DeskjetRemote"); assert "/var/run/cups/cups.sock" in client.succeed("lpstat -H")
$client->succeed("lpq") =~ /DeskjetRemote is not ready.*no entries/s or die; with subtest("HTTP server is available too"):
$client->succeed("cupsenable DeskjetRemote"); client.succeed("curl --fail http://localhost:631/")
$client->succeed("lpq") =~ /DeskjetRemote is ready.*no entries/s or die; client.succeed(f"curl --fail http://{server.name}:631/")
# Test printing various file types. server.fail(f"curl --fail --connect-timeout 2 http://{client.name}:631/")
foreach my $file ("${pkgs.groff.doc}/share/doc/*/examples/mom/penguin.pdf",
"${pkgs.groff.doc}/share/doc/*/meref.ps", with subtest("LP status checks"):
"${pkgs.cups.out}/share/doc/cups/images/cups.png", assert "DeskjetRemote accepting requests" in client.succeed("lpstat -a")
"${pkgs.pcre.doc}/share/doc/pcre/pcre.txt") assert "DeskjetLocal accepting requests" in client.succeed(
{ f"lpstat -h {server.name}:631 -a"
$file =~ /([^\/]*)$/; my $fn = $1; )
subtest "print $fn", sub { client.succeed("cupsdisable DeskjetRemote")
# Print the file on the client. out = client.succeed("lpq")
$client->succeed("lp $file"); print(out)
$client->waitUntilSucceeds("lpq | grep -q -E 'active.*root.*$fn'"); assert re.search(
# Ensure that a raw PCL file appeared in the server's queue "DeskjetRemote is not ready.*no entries",
# (showing that the right filters have been applied). Of client.succeed("lpq"),
# course, since there is no actual USB printer attached, the flags=re.DOTALL,
# file will stay in the queue forever. )
$server->waitForFile("/var/spool/cups/d*-001"); client.succeed("cupsenable DeskjetRemote")
$server->waitUntilSucceeds("lpq -a | grep -q -E '$fn'"); assert re.match(
# Delete the job on the client. It should disappear on the "DeskjetRemote is ready.*no entries", client.succeed("lpq"), flags=re.DOTALL
# server as well. )
$client->succeed("lprm");
$client->waitUntilSucceeds("lpq -a | grep -q -E 'no entries'"); # Test printing various file types.
Machine::retry sub { for file in [
return 1 if $server->succeed("lpq -a") =~ /no entries/; "${pkgs.groff.doc}/share/doc/*/examples/mom/penguin.pdf",
}; "${pkgs.groff.doc}/share/doc/*/meref.ps",
# The queue is empty already, so this should be safe. "${pkgs.cups.out}/share/doc/cups/images/cups.png",
# Otherwise, pairs of "c*"-"d*-001" files might persist. "${pkgs.pcre.doc}/share/doc/pcre/pcre.txt",
$server->execute("rm /var/spool/cups/*"); ]:
}; file_name = os.path.basename(file)
} with subtest(f"print {file_name}"):
} # Print the file on the client.
testPrinting($serviceClient, $serviceServer); print(client.succeed("lpq"))
testPrinting($socketActivatedClient, $socketActivatedServer); 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}'")
# 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"))
# 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)
''; '';
}) })