nixpkgs/nixos/tests/keymap.nix
xeji 6891bda370 nixos/tests/keymap: wait for xdotool to succeed
xdotool failed in rare cases when a window was already created
but not yet decorated by the window manager.
also prevent a (never observed but possible) race condition
2018-04-25 10:16:52 +02:00

155 lines
5.1 KiB
Nix

{ system ? builtins.currentSystem }:
with import ../lib/testing.nix { inherit system; };
let
readyFile = "/tmp/readerReady";
resultFile = "/tmp/readerResult";
testReader = pkgs.writeScript "test-input-reader" ''
#!${pkgs.stdenv.shell}
rm -f ${resultFile} ${resultFile}.tmp
logger "testReader: START: Waiting for $1 characters, expecting '$2'."
touch ${readyFile}
read -r -N $1 chars
rm -f ${readyFile}
if [ "$chars" == "$2" ]; then
logger -s "testReader: PASS: Got '$2' as expected." 2>${resultFile}.tmp
else
logger -s "testReader: FAIL: Expected '$2' but got '$chars'." 2>${resultFile}.tmp
fi
# rename after the file is written to prevent a race condition
mv ${resultFile}.tmp ${resultFile}
'';
mkKeyboardTest = layout: { extraConfig ? {}, tests }: with pkgs.lib; let
combinedTests = foldAttrs (acc: val: acc ++ val) [] (builtins.attrValues tests);
perlStr = val: "'${escape ["'" "\\"] val}'";
lq = length combinedTests.qwerty;
le = length combinedTests.expect;
msg = "length mismatch between qwerty (${toString lq}) and expect (${toString le}) lists!";
send = concatMapStringsSep ", " perlStr combinedTests.qwerty;
expect = if (lq == le) then concatStrings combinedTests.expect else throw msg;
in makeTest {
name = "keymap-${layout}";
machine.services.xserver.desktopManager.xterm.enable = false;
machine.i18n.consoleKeyMap = mkOverride 900 layout;
machine.services.xserver.layout = mkOverride 900 layout;
machine.imports = [ ./common/x11.nix extraConfig ];
testScript = ''
sub mkTest ($$) {
my ($desc, $cmd) = @_;
subtest $desc, sub {
# prepare and start testReader
$machine->execute("rm -f ${readyFile} ${resultFile}");
$machine->succeed("$cmd ${testReader} ${toString le} ".q(${escapeShellArg expect} & ));
if ($desc eq "Xorg keymap") {
# make sure the xterm window is open and has focus
$machine->waitForWindow(qr/testterm/);
$machine->waitUntilSucceeds("${pkgs.xdotool}/bin/xdotool search --sync --onlyvisible --class testterm windowfocus --sync");
}
# wait for reader to be ready
$machine->waitForFile("${readyFile}");
$machine->sleep(1);
# send all keys
foreach ((${send})) { $machine->sendKeys($_); };
# wait for result and check
$machine->waitForFile("${resultFile}");
$machine->succeed("grep -q 'PASS:' ${resultFile}");
};
};
$machine->waitForX;
mkTest "VT keymap", "openvt -sw --";
mkTest "Xorg keymap", "DISPLAY=:0 xterm -title testterm -class testterm -fullscreen -e";
'';
};
in pkgs.lib.mapAttrs mkKeyboardTest {
azerty = {
tests = {
azqw.qwerty = [ "q" "w" ];
azqw.expect = [ "a" "z" ];
altgr.qwerty = [ "alt_r-2" "alt_r-3" "alt_r-4" "alt_r-5" "alt_r-6" ];
altgr.expect = [ "~" "#" "{" "[" "|" ];
};
extraConfig.i18n.consoleKeyMap = "azerty/fr";
extraConfig.services.xserver.layout = "fr";
};
colemak = {
tests = {
homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ];
homerow.expect = [ "a" "r" "s" "t" "n" "e" "i" "o" ];
};
extraConfig.i18n.consoleKeyMap = "en-latin9";
extraConfig.services.xserver.layout = "us";
extraConfig.services.xserver.xkbVariant = "colemak";
};
dvorak = {
tests = {
homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ];
homerow.expect = [ "a" "o" "e" "u" "h" "t" "n" "s" ];
symbols.qwerty = [ "q" "w" "e" "minus" "equal" ];
symbols.expect = [ "'" "," "." "[" "]" ];
};
};
dvp = {
tests = {
homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ];
homerow.expect = [ "a" "o" "e" "u" "h" "t" "n" "s" ];
numbers.qwerty = map (x: "shift-${x}")
[ "1" "2" "3" "4" "5" "6" "7" "8" "9" "0" "minus" ];
numbers.expect = [ "%" "7" "5" "3" "1" "9" "0" "2" "4" "6" "8" ];
symbols.qwerty = [ "1" "2" "3" "4" "5" "6" "7" "8" "9" "0" "minus" ];
symbols.expect = [ "&" "[" "{" "}" "(" "=" "*" ")" "+" "]" "!" ];
};
extraConfig.services.xserver.layout = "us";
extraConfig.services.xserver.xkbVariant = "dvp";
};
neo = {
tests = {
layer1.qwerty = [ "f" "j" ];
layer1.expect = [ "e" "n" ];
layer2.qwerty = [ "shift-f" "shift-j" "shift-6" ];
layer2.expect = [ "E" "N" "$" ];
layer3.qwerty = [ "caps_lock-d" "caps_lock-f" ];
layer3.expect = [ "{" "}" ];
};
extraConfig.services.xserver.layout = "de";
extraConfig.services.xserver.xkbVariant = "neo";
};
qwertz = {
tests = {
zy.qwerty = [ "z" "y" ];
zy.expect = [ "y" "z" ];
altgr.qwerty = map (x: "alt_r-${x}")
[ "q" "less" "7" "8" "9" "0" ];
altgr.expect = [ "@" "|" "{" "[" "]" "}" ];
};
extraConfig.i18n.consoleKeyMap = "de";
extraConfig.services.xserver.layout = "de";
};
}