From 0e4c1cc06602af62fa094883695303b5410cf215 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 18 Nov 2014 18:41:56 +0100 Subject: [PATCH] nixos: Add rudimentary VM tests for Chromium. Currently, the test is only for testing the user namespace sandbox and even that isn't very representative, because we're running the tests as root. But apart from that, we should have functionality for opening/closing windows and the main goal here is to get them as deterministic as possible, because Chromium usually isn't very nice to chained xdotool keystrokes. And of course, the most important "test" we have here: We know at least whether Chromium works _at_all_. Signed-off-by: aszlig --- nixos/release.nix | 1 + nixos/tests/chromium.nix | 157 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 nixos/tests/chromium.nix diff --git a/nixos/release.nix b/nixos/release.nix index ddb0b495a91f..83594629226b 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -236,6 +236,7 @@ in rec { tests.avahi = callTest tests/avahi.nix {}; tests.bittorrent = callTest tests/bittorrent.nix {}; tests.blivet = callTest tests/blivet.nix {}; + tests.chromium = callTest tests/chromium.nix {}; tests.cjdns = callTest tests/cjdns.nix {}; tests.containers = callTest tests/containers.nix {}; tests.firefox = callTest tests/firefox.nix {}; diff --git a/nixos/tests/chromium.nix b/nixos/tests/chromium.nix new file mode 100644 index 000000000000..71fa1e5268f3 --- /dev/null +++ b/nixos/tests/chromium.nix @@ -0,0 +1,157 @@ +import ./make-test.nix ({ pkgs, ... }: rec { + name = "chromium"; + + machine.imports = [ ./common/x11.nix ]; + + startupHTML = pkgs.writeText "chromium-startup.html" '' + + + + + Chromium startup notifier + + + + + + ''; + + testScript = let + xdo = name: text: let + xdoScript = pkgs.writeText "${name}.xdo" text; + in "${pkgs.xdotool}/bin/xdotool '${xdoScript}'"; + in '' + sub createNewWin { + $machine->nest("creating a new Chromium window", sub { + $machine->execute("${xdo "new-window" '' + search --onlyvisible --name "startup done" + windowfocus --sync + windowactivate --sync + key Ctrl+n + ''}"); + }); + } + + sub closeWin { + Machine::retry sub { + $machine->execute("${xdo "close-window" '' + search --onlyvisible --name "new tab" + windowfocus --sync + windowactivate --sync + key Ctrl+w + ''}"); + for (1..20) { + my ($status, $out) = $machine->execute("${xdo "wait-for-close" '' + search --onlyvisible --name "new tab" + ''}"); + return 1 if $status != 0; + $machine->sleep(1); + } + } + } + + sub waitForNewWin { + my $ret = 0; + $machine->nest("waiting for new Chromium window to appear", sub { + for (1..20) { + my ($status, $out) = $machine->execute("${xdo "wait-for-window" '' + search --onlyvisible --name "new tab" + windowfocus --sync + windowactivate --sync + ''}"); + if ($status == 0) { + $ret = 1; + last; + } + $machine->sleep(1); + } + }); + return $ret; + } + + sub createAndWaitForNewWin { + for (1..3) { + createNewWin; + return 1 if waitForNewWin; + } + die "new window didn't appear within 60 seconds"; + } + + sub testNewWin { + my ($desc, $code) = @_; + createAndWaitForNewWin; + subtest($desc, $code); + closeWin; + } + + sub chromiumTest { + my ($channel, $pkg, $code) = @_; + $machine->waitForX; + + my $url = "file://${startupHTML}"; + my $args = "--user-data-dir=/tmp/chromium-$channel"; + $machine->execute( + "ulimit -c unlimited; ". + "$pkg/bin/chromium $args \"$url\" & disown" + ); + $machine->waitUntilSucceeds("${xdo "check-startup" '' + search --sync --onlyvisible --name "startup done" + # close first start help popup + key Escape + windowfocus --sync + windowactivate --sync + ''}"); + + createAndWaitForNewWin; + $machine->screenshot($channel."_emptywin"); + closeWin; + + $machine->screenshot($channel."_startup_done"); + + subtest("Chromium $channel", $code); + + $machine->shutdown; + } + + for ( + ["stable", "${pkgs.chromium}"], + ["beta", "${pkgs.chromiumBeta}"], + ["dev", "${pkgs.chromiumDev}"] + ) { + my ($channel, $pkg) = @$_; + chromiumTest $channel, $pkg, sub { + testNewWin "check sandbox", sub { + $machine->succeed("${xdo "type-url" '' + search --sync --onlyvisible --name "new tab" + windowfocus --sync + type --delay 1000 "chrome://sandbox" + ''}"); + + $machine->succeed("${xdo "submit-url" '' + search --sync --onlyvisible --name "new tab" + windowfocus --sync + key --delay 1000 Return + ''}"); + + $machine->screenshot($channel."_sandbox"); + + $machine->succeed("${xdo "submit-url" '' + search --sync --onlyvisible --name "sandbox status" + windowfocus --sync + key --delay 1000 Ctrl+a Ctrl+c + ''}"); + + my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o"); + die "sandbox not working properly: $clipboard" + unless $clipboard =~ /suid sandbox.*yes/mi + && $clipboard =~ /pid namespaces.*yes/mi + && $clipboard =~ /network namespaces.*yes/mi + && $clipboard =~ /seccomp.*sandbox.*yes/mi; + }; + }; + } + ''; +})