nixosTests.chromium: Port to Python

This commit is contained in:
Jacek Galowicz 2020-02-06 14:50:47 +01:00 committed by Jacek Galowicz
parent 1013c2e3a6
commit 2e7d406b11

View File

@ -8,7 +8,7 @@
} }
}: }:
with import ../lib/testing.nix { inherit system pkgs; }; with import ../lib/testing-python.nix { inherit system pkgs; };
with pkgs.lib; with pkgs.lib;
mapAttrs (channel: chromiumPkg: makeTest rec { mapAttrs (channel: chromiumPkg: makeTest rec {
@ -21,9 +21,11 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
enableOCR = true; enableOCR = true;
user = "alice";
machine.imports = [ ./common/user-account.nix ./common/x11.nix ]; machine.imports = [ ./common/user-account.nix ./common/x11.nix ];
machine.virtualisation.memorySize = 2047; machine.virtualisation.memorySize = 2047;
machine.test-support.displayManager.auto.user = "alice"; machine.test-support.displayManager.auto.user = user;
machine.environment.systemPackages = [ chromiumPkg ]; machine.environment.systemPackages = [ chromiumPkg ];
startupHTML = pkgs.writeText "chromium-startup.html" '' startupHTML = pkgs.writeText "chromium-startup.html" ''
@ -47,155 +49,218 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
xdoScript = pkgs.writeText "${name}.xdo" text; xdoScript = pkgs.writeText "${name}.xdo" text;
in "${pkgs.xdotool}/bin/xdotool '${xdoScript}'"; in "${pkgs.xdotool}/bin/xdotool '${xdoScript}'";
in '' in ''
import shlex
from contextlib import contextmanager, _GeneratorContextManager
# Run as user alice # Run as user alice
sub ru ($) { def ru(cmd):
my $esc = $_[0] =~ s/'/'\\${"'"}'/gr; return "su - ${user} -c " + shlex.quote(cmd)
return "su - alice -c '$esc'";
}
sub createNewWin {
$machine->nest("creating a new Chromium window", sub {
$machine->execute(ru "${xdo "new-window" ''
search --onlyvisible --name "startup done"
windowfocus --sync
windowactivate --sync
''}");
$machine->execute(ru "${xdo "new-window" ''
key Ctrl+n
''}");
});
}
sub closeWin { def create_new_win():
Machine::retry sub { with machine.nested("Creating a new Chromium window"):
$machine->execute(ru "${xdo "close-window" '' machine.execute(
search --onlyvisible --name "new tab" ru(
windowfocus --sync "${xdo "new-window" ''
windowactivate --sync search --onlyvisible --name "startup done"
''}"); windowfocus --sync
$machine->execute(ru "${xdo "close-window" '' windowactivate --sync
key Ctrl+w ''}"
''}"); )
for (1..20) { )
my ($status, $out) = $machine->execute(ru "${xdo "wait-for-close" '' machine.execute(
search --onlyvisible --name "new tab" ru(
''}"); "${xdo "new-window" ''
return 1 if $status != 0; key Ctrl+n
$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(ru "${xdo "wait-for-window" ''
search --onlyvisible --name "new tab"
windowfocus --sync
windowactivate --sync
''}");
if ($status == 0) {
$ret = 1;
# XXX: Somehow Chromium is not accepting keystrokes for a few def close_win():
# seconds after a new window has appeared, so let's wait a while. def try_close(_):
$machine->sleep(10); machine.execute(
ru(
"${xdo "close-window" ''
search --onlyvisible --name "new tab"
windowfocus --sync
windowactivate --sync
''}"
)
)
machine.execute(
ru(
"${xdo "close-window" ''
key Ctrl+w
''}"
)
)
for _ in range(1, 20):
status, out = machine.execute(
ru(
"${xdo "wait-for-close" ''
search --onlyvisible --name "new tab"
''}"
)
)
if status != 0:
return True
machine.sleep(1)
return False
last; retry(try_close)
}
$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 { def wait_for_new_win():
my ($desc, $code) = @_; ret = False
createAndWaitForNewWin; with machine.nested("Waiting for new Chromium window to appear"):
subtest($desc, $code); for _ in range(1, 20):
closeWin; status, out = machine.execute(
} ru(
"${xdo "wait-for-window" ''
search --onlyvisible --name "new tab"
windowfocus --sync
windowactivate --sync
''}"
)
)
if status == 0:
ret = True
machine.sleep(10)
break
machine.sleep(1)
return ret
$machine->waitForX;
my $url = "file://${startupHTML}"; def create_and_wait_for_new_win():
$machine->execute(ru "ulimit -c unlimited; chromium \"$url\" & disown"); for _ in range(1, 3):
$machine->waitForText(qr/startup done/); create_new_win()
$machine->waitUntilSucceeds(ru "${xdo "check-startup" '' if wait_for_new_win():
search --sync --onlyvisible --name "startup done" return True
# close first start help popup assert False, "new window did not appear within 60 seconds"
key -delay 1000 Escape
windowfocus --sync
windowactivate --sync
''}");
createAndWaitForNewWin;
$machine->screenshot("empty_windows");
closeWin;
$machine->screenshot("startup_done"); @contextmanager
def test_new_win(description):
create_and_wait_for_new_win()
with machine.nested(description):
yield
close_win()
testNewWin "check sandbox", sub {
$machine->succeed(ru "${xdo "type-url" ''
search --sync --onlyvisible --name "new tab"
windowfocus --sync
type --delay 1000 "chrome://sandbox"
''}");
$machine->succeed(ru "${xdo "submit-url" '' machine.wait_for_x()
search --sync --onlyvisible --name "new tab"
windowfocus --sync
key --delay 1000 Return
''}");
$machine->screenshot("sandbox_info"); url = "file://${startupHTML}"
machine.succeed(ru(f'ulimit -c unlimited; chromium "{url}" & disown'))
machine.wait_for_text("startup done")
machine.wait_until_succeeds(
ru(
"${xdo "check-startup" ''
search --sync --onlyvisible --name "startup done"
# close first start help popup
key -delay 1000 Escape
windowfocus --sync
windowactivate --sync
''}"
)
)
$machine->succeed(ru "${xdo "find-window" '' create_and_wait_for_new_win()
search --sync --onlyvisible --name "sandbox status" machine.screenshot("empty_windows")
windowfocus --sync close_win()
''}");
$machine->succeed(ru "${xdo "copy-sandbox-info" ''
key --delay 1000 Ctrl+a Ctrl+c
''}");
my $clipboard = $machine->succeed(ru "${pkgs.xclip}/bin/xclip -o"); machine.screenshot("startup_done")
die "sandbox not working properly: $clipboard"
unless $clipboard =~ /layer 1 sandbox.*namespace/mi
&& $clipboard =~ /pid namespaces.*yes/mi
&& $clipboard =~ /network namespaces.*yes/mi
&& $clipboard =~ /seccomp.*sandbox.*yes/mi
&& $clipboard =~ /you are adequately sandboxed/mi;
$machine->sleep(1); with test_new_win("check sandbox"):
$machine->succeed(ru "${xdo "find-window-after-copy" '' machine.succeed(
search --onlyvisible --name "sandbox status" ru(
''}"); "${xdo "type-url" ''
search --sync --onlyvisible --name "new tab"
windowfocus --sync
type --delay 1000 "chrome://sandbox"
''}"
)
)
my $clipboard = $machine->succeed(ru "echo void | ${pkgs.xclip}/bin/xclip -i"); machine.succeed(
$machine->succeed(ru "${xdo "copy-sandbox-info" '' ru(
key --delay 1000 Ctrl+a Ctrl+c "${xdo "submit-url" ''
''}"); search --sync --onlyvisible --name "new tab"
windowfocus --sync
key --delay 1000 Return
''}"
)
)
my $clipboard = $machine->succeed(ru "${pkgs.xclip}/bin/xclip -o"); machine.screenshot("sandbox_info")
die "copying twice in a row does not work properly: $clipboard"
unless $clipboard =~ /layer 1 sandbox.*namespace/mi
&& $clipboard =~ /pid namespaces.*yes/mi
&& $clipboard =~ /network namespaces.*yes/mi
&& $clipboard =~ /seccomp.*sandbox.*yes/mi
&& $clipboard =~ /you are adequately sandboxed/mi;
$machine->screenshot("afer_copy_from_chromium"); machine.succeed(
}; ru(
"${xdo "find-window" ''
search --sync --onlyvisible --name "sandbox status"
windowfocus --sync
''}"
)
)
machine.succeed(
ru(
"${xdo "copy-sandbox-info" ''
key --delay 1000 Ctrl+a Ctrl+c
''}"
)
)
$machine->shutdown; clipboard = machine.succeed(
ru("${pkgs.xclip}/bin/xclip -o")
)
filters = [
"layer 1 sandbox.*namespace",
"pid namespaces.*yes",
"network namespaces.*yes",
"seccomp.*sandbox.*yes",
"you are adequately sandboxed",
]
if not all(
re.search(filter, clipboard, flags=re.DOTALL | re.IGNORECASE)
for filter in filters
):
assert False, f"sandbox not working properly: {clipboard}"
machine.sleep(1)
machine.succeed(
ru(
"${xdo "find-window-after-copy" ''
search --onlyvisible --name "sandbox status"
''}"
)
)
clipboard = machine.succeed(
ru(
"echo void | ${pkgs.xclip}/bin/xclip -i"
)
)
machine.succeed(
ru(
"${xdo "copy-sandbox-info" ''
key --delay 1000 Ctrl+a Ctrl+c
''}"
)
)
clipboard = machine.succeed(
ru("${pkgs.xclip}/bin/xclip -o")
)
if not all(
re.search(filter, clipboard, flags=re.DOTALL | re.IGNORECASE)
for filter in filters
):
assert False, f"copying twice in a row does not work properly: {clipboard}"
machine.screenshot("after_copy_from_chromium")
machine.shutdown()
''; '';
}) channelMap }) channelMap