wchisp: remove overuse of with lib (#357239)
[NixPkgs.git] / nixos / tests / keymap.nix
blob3542dea58f7f379a7268d1f0d0a830eb163b8651
1 { system ? builtins.currentSystem,
2   config ? {},
3   pkgs ? import ../.. { inherit system config; }
4 }:
6 with import ../lib/testing-python.nix { inherit system pkgs; };
8 let
9   readyFile  = "/tmp/readerReady";
10   resultFile = "/tmp/readerResult";
12   testReader = pkgs.writeScript "test-input-reader" ''
13     rm -f ${resultFile} ${resultFile}.tmp
14     logger "testReader: START: expecting '$1'."
15     touch ${readyFile}
16     read -r -N ''${#1} -t 60 chars
17     rm -f ${readyFile}
19     if [ "$chars" == "$1" ]; then
20       logger -s "testReader: PASS: Got '$1' as expected." 2>${resultFile}.tmp
21     else
22       logger -s "testReader: FAIL: Expected '$1' 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   '';
29   mkKeyboardTest = layout: { extraConfig ? {}, tests }: with pkgs.lib; makeTest {
30     name = "keymap-${layout}";
32     nodes.machine.console.keyMap = mkOverride 900 layout;
33     nodes.machine.services.xserver.desktopManager.xterm.enable = false;
34     nodes.machine.services.xserver.xkb.layout = mkOverride 900 layout;
35     nodes.machine.imports = [ ./common/x11.nix extraConfig ];
37     testScript = ''
38       import json
39       import shlex
42       def run_test_case(cmd, inputs, expected):
43           assert len(inputs) == len(expected)
44           machine.execute("rm -f ${readyFile} ${resultFile}")
46           # set up process that expects all the keys to be entered
47           machine.succeed(
48               "${pkgs.systemd}/bin/systemd-cat -t input-test-reader -- {} {} {} &".format(
49                   cmd,
50                   "${testReader}",
51                   shlex.quote("".join(expected)),
52               )
53           )
55           # wait for reader to be ready
56           machine.wait_for_file("${readyFile}")
58           # send all keys
59           for key in inputs:
60               machine.send_key(key)
62           # wait for result and check
63           machine.wait_for_file("${resultFile}")
64           machine.succeed("grep -q 'PASS:' ${resultFile}")
67       with open("${pkgs.writeText "tests.json" (builtins.toJSON tests)}") as json_file:
68           tests = json.load(json_file)
70       # These environments used to run in the opposite order, causing the
71       # following error at openvt startup.
72       #
73       # openvt: Couldn't deallocate console 1
74       #
75       # This error did not appear in successful runs.
76       # I don't know the exact cause, but I it seems that openvt and X are
77       # fighting over the virtual terminal. This does not appear to be a problem
78       # when the X test runs first.
79       keymap_environments = {
80           "Xorg Keymap": "env DISPLAY=:0 xterm -title testterm -class testterm -fullscreen -e",
81           "VT Keymap": "openvt -c 2 -sw --",
82       }
84       machine.wait_for_x()
86       for test_case_name, test_data in tests.items():
87           for keymap_env_name, command in keymap_environments.items():
88               with subtest(f"{test_case_name} - {keymap_env_name}"):
89                   run_test_case(
90                       command,
91                       test_data["qwerty"],
92                       test_data["expect"],
93                   )
94     '';
95   };
97 in pkgs.lib.mapAttrs mkKeyboardTest {
98   azerty = {
99     tests = {
100       azqw.qwerty = [ "q" "w" ];
101       azqw.expect = [ "a" "z" ];
102       altgr.qwerty = [ "alt_r-2" "alt_r-3" "alt_r-4" "alt_r-5" "alt_r-6" ];
103       altgr.expect = [ "~"       "#"       "{"       "["       "|"       ];
104     };
106     extraConfig.console.keyMap = "fr";
107     extraConfig.services.xserver.xkb.layout = "fr";
108   };
110   bone = {
111     tests = {
112       layer1.qwerty = [ "f"           "j"                     ];
113       layer1.expect = [ "e"           "n"                     ];
114       layer2.qwerty = [ "shift-f"     "shift-j"     "shift-6" ];
115       layer2.expect = [ "E"           "N"           "$"       ];
116       layer3.qwerty = [ "caps_lock-d" "caps_lock-f"           ];
117       layer3.expect = [ "{"           "}"                     ];
118     };
120     extraConfig.console.keyMap = "bone";
121     extraConfig.services.xserver.xkb.layout = "de";
122     extraConfig.services.xserver.xkb.variant = "bone";
123   };
125   colemak = {
126     tests = {
127       homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ];
128       homerow.expect = [ "a" "r" "s" "t" "n" "e" "i" "o"         ];
129     };
131     extraConfig.console.keyMap = "colemak";
132     extraConfig.services.xserver.xkb.layout = "us";
133     extraConfig.services.xserver.xkb.variant = "colemak";
134   };
136   dvorak = {
137     tests = {
138       homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ];
139       homerow.expect = [ "a" "o" "e" "u" "h" "t" "n" "s"         ];
140       symbols.qwerty = [ "q" "w" "e" "minus" "equal" ];
141       symbols.expect = [ "'" "," "." "["     "]"     ];
142     };
144     extraConfig.console.keyMap = "dvorak";
145     extraConfig.services.xserver.xkb.layout = "us";
146     extraConfig.services.xserver.xkb.variant = "dvorak";
147   };
149   dvorak-programmer = {
150     tests = {
151       homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ];
152       homerow.expect = [ "a" "o" "e" "u" "h" "t" "n" "s"         ];
153       numbers.qwerty = map (x: "shift-${x}")
154                        [ "1" "2" "3" "4" "5" "6" "7" "8" "9" "0" "minus" ];
155       numbers.expect = [ "%" "7" "5" "3" "1" "9" "0" "2" "4" "6" "8" ];
156       symbols.qwerty = [ "1" "2" "3" "4" "5" "6" "7" "8" "9" "0" "minus" ];
157       symbols.expect = [ "&" "[" "{" "}" "(" "=" "*" ")" "+" "]" "!" ];
158     };
160     extraConfig.console.keyMap = "dvorak-programmer";
161     extraConfig.services.xserver.xkb.layout = "us";
162     extraConfig.services.xserver.xkb.variant = "dvp";
163   };
165   neo = {
166     tests = {
167       layer1.qwerty = [ "f"           "j"                     ];
168       layer1.expect = [ "e"           "n"                     ];
169       layer2.qwerty = [ "shift-f"     "shift-j"     "shift-6" ];
170       layer2.expect = [ "E"           "N"           "$"       ];
171       layer3.qwerty = [ "caps_lock-d" "caps_lock-f"           ];
172       layer3.expect = [ "{"           "}"                     ];
173     };
175     extraConfig.console.keyMap = "neo";
176     extraConfig.services.xserver.xkb.layout = "de";
177     extraConfig.services.xserver.xkb.variant = "neo";
178   };
180   qwertz = {
181     tests = {
182       zy.qwerty = [ "z" "y" ];
183       zy.expect = [ "y" "z" ];
184       altgr.qwerty = map (x: "alt_r-${x}")
185                      [ "q" "less" "7" "8" "9" "0" ];
186       altgr.expect = [ "@" "|"    "{" "[" "]" "}" ];
187     };
189     extraConfig.console.keyMap = "de";
190     extraConfig.services.xserver.xkb.layout = "de";
191   };
193   custom = {
194     tests = {
195       us.qwerty = [ "a" "b" "g" "d" "z" "shift-2" "shift-3" ];
196       us.expect = [ "a" "b" "g" "d" "z" "@" "#" ];
197       greek.qwerty = map (x: "alt_r-${x}")
198                      [ "a" "b" "g" "d" "z" ];
199       greek.expect = [ "α" "β" "γ" "δ" "ζ" ];
200     };
202     extraConfig.console.useXkbConfig = true;
203     extraConfig.services.xserver.xkb.layout = "us-greek";
204     extraConfig.services.xserver.xkb.extraLayouts.us-greek =
205       { description = "US layout with alt-gr greek";
206         languages   = [ "eng" ];
207         symbolsFile = pkgs.writeText "us-greek" ''
208           xkb_symbols "us-greek"
209           {
210             include "us(basic)"
211             include "level3(ralt_switch)"
212             key <LatA> { [ a, A, Greek_alpha ] };
213             key <LatB> { [ b, B, Greek_beta  ] };
214             key <LatG> { [ g, G, Greek_gamma ] };
215             key <LatD> { [ d, D, Greek_delta ] };
216             key <LatZ> { [ z, Z, Greek_zeta  ] };
217           };
218         '';
219       };
220   };