| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2018-04-24 01:50:23 +02:00
										 |  |  |     logger "testReader: START: Waiting for $1 characters, expecting '$2'." | 
					
						
							|  |  |  |     touch ${readyFile} | 
					
						
							|  |  |  |     read -r -N $1 chars | 
					
						
							|  |  |  |     rm -f ${readyFile} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if [ "$chars" == "$2" ]; then | 
					
						
							| 
									
										
										
										
											2018-04-25 00:06:11 +02:00
										 |  |  |       logger -s "testReader: PASS: Got '$2' as expected." 2>${resultFile}.tmp | 
					
						
							| 
									
										
										
										
											2018-04-24 01:50:23 +02:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2018-04-25 00:06:11 +02:00
										 |  |  |       logger -s "testReader: FAIL: Expected '$2' 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 = layout: { extraConfig ? {}, tests }: with pkgs.lib; makeTest { | 
					
						
							| 
									
										
										
										
											2016-03-31 09:26:58 +02:00
										 |  |  |     name = "keymap-${layout}"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 18:17:10 +01:00
										 |  |  |     machine.console.keyMap = mkOverride 900 layout; | 
					
						
							| 
									
										
										
										
											2018-01-11 20:12:49 +01:00
										 |  |  |     machine.services.xserver.desktopManager.xterm.enable = false; | 
					
						
							| 
									
										
										
										
											2016-03-31 09:26:58 +02:00
										 |  |  |     machine.services.xserver.layout = mkOverride 900 layout; | 
					
						
							|  |  |  |     machine.imports = [ ./common/x11.nix extraConfig ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     testScript = ''
 | 
					
						
							| 
									
										
										
										
											2020-01-26 18:17:10 +01:00
										 |  |  |       import json | 
					
						
							|  |  |  |       import shlex | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def run_test_case(cmd, xorg_keymap, test_case_name, inputs, expected): | 
					
						
							|  |  |  |           with subtest(test_case_name): | 
					
						
							|  |  |  |               assert len(inputs) == len(expected) | 
					
						
							|  |  |  |               machine.execute("rm -f ${readyFile} ${resultFile}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               # set up process that expects all the keys to be entered | 
					
						
							|  |  |  |               machine.succeed( | 
					
						
							|  |  |  |                   "{} {} {} {} &".format( | 
					
						
							|  |  |  |                       cmd, | 
					
						
							|  |  |  |                       "${testReader}", | 
					
						
							|  |  |  |                       len(inputs), | 
					
						
							|  |  |  |                       shlex.quote("".join(expected)), | 
					
						
							|  |  |  |                   ) | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               if xorg_keymap: | 
					
						
							|  |  |  |                   # make sure the xterm window is open and has focus | 
					
						
							|  |  |  |                   machine.wait_for_window("testterm") | 
					
						
							|  |  |  |                   machine.wait_until_succeeds( | 
					
						
							|  |  |  |                       "${pkgs.xdotool}/bin/xdotool search --sync --onlyvisible " | 
					
						
							|  |  |  |                       "--class testterm windowfocus --sync" | 
					
						
							|  |  |  |                   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               # wait for reader to be ready | 
					
						
							|  |  |  |               machine.wait_for_file("${readyFile}") | 
					
						
							|  |  |  |               machine.sleep(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               # send all keys | 
					
						
							|  |  |  |               for key in inputs: | 
					
						
							|  |  |  |                   machine.send_key(key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               # wait for result and check | 
					
						
							|  |  |  |               machine.wait_for_file("${resultFile}") | 
					
						
							|  |  |  |               machine.succeed("grep -q 'PASS:' ${resultFile}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       with open("${pkgs.writeText "tests.json" (builtins.toJSON tests)}") as json_file: | 
					
						
							|  |  |  |           tests = json.load(json_file) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       keymap_environments = { | 
					
						
							|  |  |  |           "VT Keymap": "openvt -sw --", | 
					
						
							|  |  |  |           "Xorg Keymap": "DISPLAY=:0 xterm -title testterm -class testterm -fullscreen -e", | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       machine.wait_for_x() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for keymap_env_name, command in keymap_environments.items(): | 
					
						
							|  |  |  |           with subtest(keymap_env_name): | 
					
						
							|  |  |  |               for test_case_name, test_data in tests.items(): | 
					
						
							|  |  |  |                   run_test_case( | 
					
						
							|  |  |  |                       command, | 
					
						
							|  |  |  |                       False, | 
					
						
							|  |  |  |                       test_case_name, | 
					
						
							|  |  |  |                       test_data["qwerty"], | 
					
						
							|  |  |  |                       test_data["expect"], | 
					
						
							|  |  |  |                   ) | 
					
						
							| 
									
										
										
										
											2016-03-31 09:26:58 +02:00
										 |  |  |     '';
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 = [ "~"       "#"       "{"       "["       "|"       ]; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 18:17:10 +01:00
										 |  |  |     extraConfig.console.keyMap = "azerty/fr"; | 
					
						
							| 
									
										
										
										
											2016-03-31 09:26:58 +02:00
										 |  |  |     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"         ]; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 18:17:10 +01:00
										 |  |  |     extraConfig.console.keyMap = "colemak/colemak"; | 
					
						
							| 
									
										
										
										
											2016-03-31 09:26:58 +02:00
										 |  |  |     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 = [ "@" "|"    "{" "[" "]" "}" ]; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 18:17:10 +01:00
										 |  |  |     extraConfig.console.keyMap = "de"; | 
					
						
							| 
									
										
										
										
											2016-03-31 09:26:58 +02:00
										 |  |  |     extraConfig.services.xserver.layout = "de"; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } |