at master 9.0 kB view raw
1{ 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: expecting '$1'." 16 touch ${readyFile} 17 read -r -N ''${#1} -t 60 chars 18 rm -f ${readyFile} 19 20 if [ "$chars" == "$1" ]; then 21 logger -s "testReader: PASS: Got '$1' as expected." 2>${resultFile}.tmp 22 else 23 logger -s "testReader: FAIL: Expected '$1' but got '$chars'." 2>${resultFile}.tmp 24 fi 25 # rename after the file is written to prevent a race condition 26 mv ${resultFile}.tmp ${resultFile} 27 ''; 28 29 mkKeyboardTest = 30 layout: 31 { 32 extraConfig ? { }, 33 tests, 34 }: 35 with pkgs.lib; 36 makeTest { 37 name = "keymap-${layout}"; 38 39 nodes.machine.console.keyMap = mkOverride 900 layout; 40 nodes.machine.services.xserver.desktopManager.xterm.enable = false; 41 nodes.machine.services.xserver.xkb.layout = mkOverride 900 layout; 42 nodes.machine.imports = [ 43 ./common/x11.nix 44 extraConfig 45 ]; 46 47 testScript = '' 48 import json 49 import shlex 50 51 52 def run_test_case(cmd, inputs, expected): 53 assert len(inputs) == len(expected) 54 machine.execute("rm -f ${readyFile} ${resultFile}") 55 56 # set up process that expects all the keys to be entered 57 machine.succeed( 58 "${pkgs.systemd}/bin/systemd-cat -t input-test-reader -- {} {} {} &".format( 59 cmd, 60 "${testReader}", 61 shlex.quote("".join(expected)), 62 ) 63 ) 64 65 # wait for reader to be ready 66 machine.wait_for_file("${readyFile}") 67 68 # send all keys 69 for key in inputs: 70 machine.send_key(key) 71 72 # wait for result and check 73 machine.wait_for_file("${resultFile}") 74 machine.succeed("grep -q 'PASS:' ${resultFile}") 75 76 77 with open("${pkgs.writeText "tests.json" (builtins.toJSON tests)}") as json_file: 78 tests = json.load(json_file) 79 80 # These environments used to run in the opposite order, causing the 81 # following error at openvt startup. 82 # 83 # openvt: Couldn't deallocate console 1 84 # 85 # This error did not appear in successful runs. 86 # I don't know the exact cause, but I it seems that openvt and X are 87 # fighting over the virtual terminal. This does not appear to be a problem 88 # when the X test runs first. 89 keymap_environments = { 90 "Xorg Keymap": "env DISPLAY=:0 xterm -title testterm -class testterm -fullscreen -e", 91 "VT Keymap": "openvt -c 2 -sw --", 92 } 93 94 machine.wait_for_x() 95 96 for test_case_name, test_data in tests.items(): 97 for keymap_env_name, command in keymap_environments.items(): 98 with subtest(f"{test_case_name} - {keymap_env_name}"): 99 run_test_case( 100 command, 101 test_data["qwerty"], 102 test_data["expect"], 103 ) 104 ''; 105 }; 106 107in 108pkgs.lib.mapAttrs mkKeyboardTest { 109 azerty = { 110 tests = { 111 azqw.qwerty = [ 112 "q" 113 "w" 114 ]; 115 azqw.expect = [ 116 "a" 117 "z" 118 ]; 119 altgr.qwerty = [ 120 "alt_r-2" 121 "alt_r-3" 122 "alt_r-4" 123 "alt_r-5" 124 "alt_r-6" 125 ]; 126 altgr.expect = [ 127 "~" 128 "#" 129 "{" 130 "[" 131 "|" 132 ]; 133 }; 134 135 extraConfig.console.keyMap = "fr"; 136 extraConfig.services.xserver.xkb.layout = "fr"; 137 }; 138 139 bone = { 140 tests = { 141 layer1.qwerty = [ 142 "f" 143 "j" 144 ]; 145 layer1.expect = [ 146 "e" 147 "n" 148 ]; 149 layer2.qwerty = [ 150 "shift-f" 151 "shift-j" 152 "shift-6" 153 ]; 154 layer2.expect = [ 155 "E" 156 "N" 157 "$" 158 ]; 159 layer3.qwerty = [ 160 "caps_lock-d" 161 "caps_lock-f" 162 ]; 163 layer3.expect = [ 164 "{" 165 "}" 166 ]; 167 }; 168 169 extraConfig.console.keyMap = "bone"; 170 extraConfig.services.xserver.xkb.layout = "de"; 171 extraConfig.services.xserver.xkb.variant = "bone"; 172 }; 173 174 colemak = { 175 tests = { 176 homerow.qwerty = [ 177 "a" 178 "s" 179 "d" 180 "f" 181 "j" 182 "k" 183 "l" 184 "semicolon" 185 ]; 186 homerow.expect = [ 187 "a" 188 "r" 189 "s" 190 "t" 191 "n" 192 "e" 193 "i" 194 "o" 195 ]; 196 }; 197 198 extraConfig.console.keyMap = "colemak"; 199 extraConfig.services.xserver.xkb.layout = "us"; 200 extraConfig.services.xserver.xkb.variant = "colemak"; 201 }; 202 203 dvorak = { 204 tests = { 205 homerow.qwerty = [ 206 "a" 207 "s" 208 "d" 209 "f" 210 "j" 211 "k" 212 "l" 213 "semicolon" 214 ]; 215 homerow.expect = [ 216 "a" 217 "o" 218 "e" 219 "u" 220 "h" 221 "t" 222 "n" 223 "s" 224 ]; 225 symbols.qwerty = [ 226 "q" 227 "w" 228 "e" 229 "minus" 230 "equal" 231 ]; 232 symbols.expect = [ 233 "'" 234 "," 235 "." 236 "[" 237 "]" 238 ]; 239 }; 240 241 extraConfig.console.keyMap = "dvorak"; 242 extraConfig.services.xserver.xkb.layout = "us"; 243 extraConfig.services.xserver.xkb.variant = "dvorak"; 244 }; 245 246 dvorak-programmer = { 247 tests = { 248 homerow.qwerty = [ 249 "a" 250 "s" 251 "d" 252 "f" 253 "j" 254 "k" 255 "l" 256 "semicolon" 257 ]; 258 homerow.expect = [ 259 "a" 260 "o" 261 "e" 262 "u" 263 "h" 264 "t" 265 "n" 266 "s" 267 ]; 268 numbers.qwerty = map (x: "shift-${x}") [ 269 "1" 270 "2" 271 "3" 272 "4" 273 "5" 274 "6" 275 "7" 276 "8" 277 "9" 278 "0" 279 "minus" 280 ]; 281 numbers.expect = [ 282 "%" 283 "7" 284 "5" 285 "3" 286 "1" 287 "9" 288 "0" 289 "2" 290 "4" 291 "6" 292 "8" 293 ]; 294 symbols.qwerty = [ 295 "1" 296 "2" 297 "3" 298 "4" 299 "5" 300 "6" 301 "7" 302 "8" 303 "9" 304 "0" 305 "minus" 306 ]; 307 symbols.expect = [ 308 "&" 309 "[" 310 "{" 311 "}" 312 "(" 313 "=" 314 "*" 315 ")" 316 "+" 317 "]" 318 "!" 319 ]; 320 }; 321 322 extraConfig.console.keyMap = "dvorak-programmer"; 323 extraConfig.services.xserver.xkb.layout = "us"; 324 extraConfig.services.xserver.xkb.variant = "dvp"; 325 }; 326 327 neo = { 328 tests = { 329 layer1.qwerty = [ 330 "f" 331 "j" 332 ]; 333 layer1.expect = [ 334 "e" 335 "n" 336 ]; 337 layer2.qwerty = [ 338 "shift-f" 339 "shift-j" 340 "shift-6" 341 ]; 342 layer2.expect = [ 343 "E" 344 "N" 345 "$" 346 ]; 347 layer3.qwerty = [ 348 "caps_lock-d" 349 "caps_lock-f" 350 ]; 351 layer3.expect = [ 352 "{" 353 "}" 354 ]; 355 }; 356 357 extraConfig.console.keyMap = "neo"; 358 extraConfig.services.xserver.xkb.layout = "de"; 359 extraConfig.services.xserver.xkb.variant = "neo"; 360 }; 361 362 qwertz = { 363 tests = { 364 zy.qwerty = [ 365 "z" 366 "y" 367 ]; 368 zy.expect = [ 369 "y" 370 "z" 371 ]; 372 altgr.qwerty = map (x: "alt_r-${x}") [ 373 "q" 374 "less" 375 "7" 376 "8" 377 "9" 378 "0" 379 ]; 380 altgr.expect = [ 381 "@" 382 "|" 383 "{" 384 "[" 385 "]" 386 "}" 387 ]; 388 }; 389 390 extraConfig.console.keyMap = "de"; 391 extraConfig.services.xserver.xkb.layout = "de"; 392 }; 393 394 custom = { 395 tests = { 396 us.qwerty = [ 397 "a" 398 "b" 399 "g" 400 "d" 401 "z" 402 "shift-2" 403 "shift-3" 404 ]; 405 us.expect = [ 406 "a" 407 "b" 408 "g" 409 "d" 410 "z" 411 "@" 412 "#" 413 ]; 414 greek.qwerty = map (x: "alt_r-${x}") [ 415 "a" 416 "b" 417 "g" 418 "d" 419 "z" 420 ]; 421 greek.expect = [ 422 "α" 423 "β" 424 "γ" 425 "δ" 426 "ζ" 427 ]; 428 }; 429 430 extraConfig.console.useXkbConfig = true; 431 extraConfig.services.xserver.xkb.layout = "us-greek"; 432 extraConfig.services.xserver.xkb.extraLayouts.us-greek = { 433 description = "US layout with alt-gr greek"; 434 languages = [ "eng" ]; 435 symbolsFile = pkgs.writeText "us-greek" '' 436 xkb_symbols "us-greek" 437 { 438 include "us(basic)" 439 include "level3(ralt_switch)" 440 key <LatA> { [ a, A, Greek_alpha ] }; 441 key <LatB> { [ b, B, Greek_beta ] }; 442 key <LatG> { [ g, G, Greek_gamma ] }; 443 key <LatD> { [ d, D, Greek_delta ] }; 444 key <LatZ> { [ z, Z, Greek_zeta ] }; 445 }; 446 ''; 447 }; 448 }; 449}