1# The test template is taken from the `./keymap.nix`
2{ system ? builtins.currentSystem
3, config ? { }
4, pkgs ? import ../.. { inherit system config; }
5}:
6
7with import ../lib/testing-python.nix { inherit system pkgs; };
8
9let
10 readyFile = "/tmp/readerReady";
11 resultFile = "/tmp/readerResult";
12
13 testReader = pkgs.writeScript "test-input-reader" ''
14 rm -f ${resultFile} ${resultFile}.tmp
15 logger "testReader: START: Waiting for $1 characters, expecting '$2'."
16 touch ${readyFile}
17 read -r -N $1 chars
18 rm -f ${readyFile}
19 if [ "$chars" == "$2" ]; then
20 logger -s "testReader: PASS: Got '$2' as expected." 2>${resultFile}.tmp
21 else
22 logger -s "testReader: FAIL: Expected '$2' but got '$chars'." 2>${resultFile}.tmp
23 fi
24 # rename after the file is written to prevent a race condition
25 mv ${resultFile}.tmp ${resultFile}
26 '';
27
28
29 mkKeyboardTest = name: { settings, test }: with pkgs.lib; makeTest {
30 inherit name;
31
32 nodes.machine = {
33 services.keyd = {
34 enable = true;
35 inherit settings;
36 };
37 };
38
39 testScript = ''
40 import shlex
41
42 machine.wait_for_unit("keyd.service")
43
44 def run_test_case(cmd, test_case_name, inputs, expected):
45 with subtest(test_case_name):
46 assert len(inputs) == len(expected)
47 machine.execute("rm -f ${readyFile} ${resultFile}")
48 # set up process that expects all the keys to be entered
49 machine.succeed(
50 "{} {} {} {} >&2 &".format(
51 cmd,
52 "${testReader}",
53 len(inputs),
54 shlex.quote("".join(expected)),
55 )
56 )
57 # wait for reader to be ready
58 machine.wait_for_file("${readyFile}")
59 # send all keys
60 for key in inputs:
61 machine.send_key(key)
62 # wait for result and check
63 machine.wait_for_file("${resultFile}")
64 machine.succeed("grep -q 'PASS:' ${resultFile}")
65 test = ${builtins.toJSON test}
66 run_test_case("openvt -sw --", "${name}", test["press"], test["expect"])
67 '';
68 };
69
70in
71pkgs.lib.mapAttrs mkKeyboardTest {
72 swap-ab_and_ctrl-as-shift = {
73 test.press = [ "a" "ctrl-b" "c" ];
74 test.expect = [ "b" "A" "c" ];
75
76 settings.main = {
77 "a" = "b";
78 "b" = "a";
79 "control" = "oneshot(shift)";
80 };
81 };
82}