2018-11-11 17:41:11 +09:00
|
|
|
|
{
|
|
|
|
|
system ? builtins.currentSystem,
|
|
|
|
|
config ? { },
|
|
|
|
|
pkgs ? import ../.. { inherit system config; },
|
|
|
|
|
}:
|
2016-03-31 09:26:58 +02:00
|
|
|
|
|
2020-01-26 18:17:10 +01:00
|
|
|
|
with import ../lib/testing-python.nix { inherit system pkgs; };
|
2016-03-31 09:26:58 +02:00
|
|
|
|
|
|
|
|
|
let
|
2018-04-24 01:50:23 +02:00
|
|
|
|
readyFile = "/tmp/readerReady";
|
|
|
|
|
resultFile = "/tmp/readerResult";
|
|
|
|
|
|
2016-03-31 09:26:58 +02:00
|
|
|
|
testReader = pkgs.writeScript "test-input-reader" ''
|
2018-04-25 00:06:11 +02:00
|
|
|
|
rm -f ${resultFile} ${resultFile}.tmp
|
2024-10-19 08:56:02 +03:00
|
|
|
|
logger "testReader: START: expecting '$1'."
|
2018-04-24 01:50:23 +02:00
|
|
|
|
touch ${readyFile}
|
2024-10-19 08:56:02 +03:00
|
|
|
|
read -r -N ''${#1} -t 60 chars
|
2018-04-24 01:50:23 +02:00
|
|
|
|
rm -f ${readyFile}
|
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
if [ "$chars" == "$1" ]; then
|
|
|
|
|
logger -s "testReader: PASS: Got '$1' as expected." 2>${resultFile}.tmp
|
2018-04-24 01:50:23 +02:00
|
|
|
|
else
|
2024-10-19 08:56:02 +03:00
|
|
|
|
logger -s "testReader: FAIL: Expected '$1' but got '$chars'." 2>${resultFile}.tmp
|
2018-04-24 01:50:23 +02:00
|
|
|
|
fi
|
2018-04-25 00:06:11 +02:00
|
|
|
|
# rename after the file is written to prevent a race condition
|
|
|
|
|
mv ${resultFile}.tmp ${resultFile}
|
2016-03-31 09:26:58 +02:00
|
|
|
|
'';
|
|
|
|
|
|
2020-01-26 18:17:10 +01:00
|
|
|
|
mkKeyboardTest =
|
2024-12-10 20:23:58 +01:00
|
|
|
|
layout:
|
|
|
|
|
{
|
2020-01-26 18:17:10 +01:00
|
|
|
|
extraConfig ? { },
|
2024-12-10 20:23:58 +01:00
|
|
|
|
tests,
|
|
|
|
|
}:
|
2020-01-26 18:17:10 +01:00
|
|
|
|
with pkgs.lib;
|
|
|
|
|
makeTest {
|
2016-03-31 09:26:58 +02:00
|
|
|
|
name = "keymap-${layout}";
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
2023-07-18 17:07:19 +02:00
|
|
|
|
nodes.machine.console.keyMap = mkOverride 900 layout;
|
|
|
|
|
nodes.machine.services.xserver.desktopManager.xterm.enable = false;
|
2023-10-09 14:31:13 +13:00
|
|
|
|
nodes.machine.services.xserver.xkb.layout = mkOverride 900 layout;
|
2023-07-18 17:07:19 +02:00
|
|
|
|
nodes.machine.imports = [
|
|
|
|
|
./common/x11.nix
|
|
|
|
|
extraConfig
|
2024-12-10 20:23:58 +01:00
|
|
|
|
];
|
|
|
|
|
|
2016-03-31 09:26:58 +02:00
|
|
|
|
testScript = ''
|
2020-01-26 18:17:10 +01:00
|
|
|
|
import json
|
|
|
|
|
import shlex
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
def run_test_case(cmd, inputs, expected):
|
|
|
|
|
assert len(inputs) == len(expected)
|
|
|
|
|
machine.execute("rm -f ${readyFile} ${resultFile}")
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
# set up process that expects all the keys to be entered
|
|
|
|
|
machine.succeed(
|
|
|
|
|
"${pkgs.systemd}/bin/systemd-cat -t input-test-reader -- {} {} {} &".format(
|
2024-12-10 20:23:58 +01:00
|
|
|
|
cmd,
|
2024-10-19 08:56:02 +03:00
|
|
|
|
"${testReader}",
|
|
|
|
|
shlex.quote("".join(expected)),
|
2024-12-10 20:23:58 +01:00
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
# wait for reader to be ready
|
|
|
|
|
machine.wait_for_file("${readyFile}")
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
# send all keys
|
|
|
|
|
for key in inputs:
|
|
|
|
|
machine.send_key(key)
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
# wait for result and check
|
|
|
|
|
machine.wait_for_file("${resultFile}")
|
|
|
|
|
machine.succeed("grep -q 'PASS:' ${resultFile}")
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
|
|
|
|
|
2020-01-26 18:17:10 +01:00
|
|
|
|
with open("${pkgs.writeText "tests.json" (builtins.toJSON tests)}") as json_file:
|
|
|
|
|
tests = json.load(json_file)
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
2022-12-24 13:58:22 +01:00
|
|
|
|
# These environments used to run in the opposite order, causing the
|
|
|
|
|
# following error at openvt startup.
|
2024-12-10 20:23:58 +01:00
|
|
|
|
#
|
2022-12-24 13:58:22 +01:00
|
|
|
|
# openvt: Couldn't deallocate console 1
|
2024-12-10 20:23:58 +01:00
|
|
|
|
#
|
2022-12-24 13:58:22 +01:00
|
|
|
|
# This error did not appear in successful runs.
|
|
|
|
|
# I don't know the exact cause, but I it seems that openvt and X are
|
|
|
|
|
# fighting over the virtual terminal. This does not appear to be a problem
|
|
|
|
|
# when the X test runs first.
|
2020-01-26 18:17:10 +01:00
|
|
|
|
keymap_environments = {
|
2024-10-19 08:56:02 +03:00
|
|
|
|
"Xorg Keymap": "env DISPLAY=:0 xterm -title testterm -class testterm -fullscreen -e",
|
2024-10-19 09:22:55 +03:00
|
|
|
|
"VT Keymap": "openvt -c 2 -sw --",
|
2024-12-10 20:23:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-26 18:17:10 +01:00
|
|
|
|
machine.wait_for_x()
|
2024-12-10 20:23:58 +01:00
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
for test_case_name, test_data in tests.items():
|
|
|
|
|
for keymap_env_name, command in keymap_environments.items():
|
|
|
|
|
with subtest(f"{test_case_name} - {keymap_env_name}"):
|
2020-01-26 18:17:10 +01:00
|
|
|
|
run_test_case(
|
2024-12-10 20:23:58 +01:00
|
|
|
|
command,
|
2020-01-26 18:17:10 +01:00
|
|
|
|
test_data["qwerty"],
|
|
|
|
|
test_data["expect"],
|
2024-12-10 20:23:58 +01:00
|
|
|
|
)
|
|
|
|
|
'';
|
|
|
|
|
};
|
2016-03-31 09:26:58 +02:00
|
|
|
|
|
2024-10-19 08:56:02 +03:00
|
|
|
|
in
|
|
|
|
|
pkgs.lib.mapAttrs mkKeyboardTest {
|
2016-03-31 09:26:58 +02:00
|
|
|
|
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 = [
|
|
|
|
|
"~"
|
|
|
|
|
"#"
|
|
|
|
|
"{"
|
|
|
|
|
"["
|
|
|
|
|
"|"
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-11 05:25:53 +02:00
|
|
|
|
extraConfig.console.keyMap = "fr";
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "fr";
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-11 05:25:53 +02:00
|
|
|
|
bone = {
|
|
|
|
|
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 = [
|
|
|
|
|
"{"
|
|
|
|
|
"}"
|
2024-12-10 20:23:58 +01:00
|
|
|
|
];
|
2021-04-11 05:25:53 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extraConfig.console.keyMap = "bone";
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "de";
|
|
|
|
|
extraConfig.services.xserver.xkb.variant = "bone";
|
2021-04-11 05:25:53 +02:00
|
|
|
|
};
|
|
|
|
|
|
2016-03-31 09:26:58 +02:00
|
|
|
|
colemak = {
|
|
|
|
|
tests = {
|
|
|
|
|
homerow.qwerty = [
|
|
|
|
|
"a"
|
|
|
|
|
"s"
|
|
|
|
|
"d"
|
|
|
|
|
"f"
|
|
|
|
|
"j"
|
|
|
|
|
"k"
|
|
|
|
|
"l"
|
|
|
|
|
"semicolon"
|
|
|
|
|
];
|
|
|
|
|
homerow.expect = [
|
|
|
|
|
"a"
|
|
|
|
|
"r"
|
|
|
|
|
"s"
|
|
|
|
|
"t"
|
|
|
|
|
"n"
|
|
|
|
|
"e"
|
|
|
|
|
"i"
|
|
|
|
|
"o"
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-11 05:25:53 +02:00
|
|
|
|
extraConfig.console.keyMap = "colemak";
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "us";
|
|
|
|
|
extraConfig.services.xserver.xkb.variant = "colemak";
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 = [
|
|
|
|
|
"'"
|
|
|
|
|
","
|
|
|
|
|
"."
|
|
|
|
|
"["
|
|
|
|
|
"]"
|
2024-12-10 20:23:58 +01:00
|
|
|
|
];
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
2021-04-11 05:25:53 +02:00
|
|
|
|
|
|
|
|
|
extraConfig.console.keyMap = "dvorak";
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "us";
|
|
|
|
|
extraConfig.services.xserver.xkb.variant = "dvorak";
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-11 05:25:53 +02:00
|
|
|
|
dvorak-programmer = {
|
2016-03-31 09:26:58 +02:00
|
|
|
|
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 = [
|
|
|
|
|
"&"
|
|
|
|
|
"["
|
|
|
|
|
"{"
|
|
|
|
|
"}"
|
|
|
|
|
"("
|
|
|
|
|
"="
|
|
|
|
|
"*"
|
|
|
|
|
")"
|
|
|
|
|
"+"
|
|
|
|
|
"]"
|
|
|
|
|
"!"
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-11 05:25:53 +02:00
|
|
|
|
extraConfig.console.keyMap = "dvorak-programmer";
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "us";
|
|
|
|
|
extraConfig.services.xserver.xkb.variant = "dvp";
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 = [
|
|
|
|
|
"{"
|
|
|
|
|
"}"
|
2024-12-10 20:23:58 +01:00
|
|
|
|
];
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-11 05:25:53 +02:00
|
|
|
|
extraConfig.console.keyMap = "neo";
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "de";
|
|
|
|
|
extraConfig.services.xserver.xkb.variant = "neo";
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 = [
|
|
|
|
|
"@"
|
|
|
|
|
"|"
|
|
|
|
|
"{"
|
|
|
|
|
"["
|
|
|
|
|
"]"
|
|
|
|
|
"}"
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-26 18:17:10 +01:00
|
|
|
|
extraConfig.console.keyMap = "de";
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "de";
|
2016-03-31 09:26:58 +02:00
|
|
|
|
};
|
2023-07-18 17:07:19 +02:00
|
|
|
|
|
|
|
|
|
custom = {
|
|
|
|
|
tests = {
|
|
|
|
|
us.qwerty = [
|
|
|
|
|
"a"
|
|
|
|
|
"b"
|
|
|
|
|
"g"
|
|
|
|
|
"d"
|
|
|
|
|
"z"
|
|
|
|
|
"shift-2"
|
|
|
|
|
"shift-3"
|
|
|
|
|
];
|
|
|
|
|
us.expect = [
|
|
|
|
|
"a"
|
|
|
|
|
"b"
|
|
|
|
|
"g"
|
|
|
|
|
"d"
|
|
|
|
|
"z"
|
|
|
|
|
"@"
|
|
|
|
|
"#"
|
2024-12-10 20:23:58 +01:00
|
|
|
|
];
|
2023-07-18 17:07:19 +02:00
|
|
|
|
greek.qwerty = map (x: "alt_r-${x}") [
|
|
|
|
|
"a"
|
|
|
|
|
"b"
|
|
|
|
|
"g"
|
|
|
|
|
"d"
|
|
|
|
|
"z"
|
|
|
|
|
];
|
|
|
|
|
greek.expect = [
|
|
|
|
|
"α"
|
|
|
|
|
"β"
|
|
|
|
|
"γ"
|
|
|
|
|
"δ"
|
|
|
|
|
"ζ"
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extraConfig.console.useXkbConfig = true;
|
2023-10-09 14:31:13 +13:00
|
|
|
|
extraConfig.services.xserver.xkb.layout = "us-greek";
|
2023-11-01 11:55:25 +01:00
|
|
|
|
extraConfig.services.xserver.xkb.extraLayouts.us-greek = {
|
2023-07-18 17:07:19 +02:00
|
|
|
|
description = "US layout with alt-gr greek";
|
|
|
|
|
languages = [ "eng" ];
|
|
|
|
|
symbolsFile = pkgs.writeText "us-greek" ''
|
|
|
|
|
xkb_symbols "us-greek"
|
|
|
|
|
{
|
|
|
|
|
include "us(basic)"
|
|
|
|
|
include "level3(ralt_switch)"
|
|
|
|
|
key <LatA> { [ a, A, Greek_alpha ] };
|
|
|
|
|
key <LatB> { [ b, B, Greek_beta ] };
|
|
|
|
|
key <LatG> { [ g, G, Greek_gamma ] };
|
|
|
|
|
key <LatD> { [ d, D, Greek_delta ] };
|
|
|
|
|
key <LatZ> { [ z, Z, Greek_zeta ] };
|
|
|
|
|
};
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
2016-03-31 09:26:58 +02:00
|
|
|
|
}
|