at 23.11-pre 7.0 kB view raw
1{ system ? builtins.currentSystem, 2 config ? {}, 3 pkgs ? import ../.. { inherit system config; } 4}: 5 6with import ../lib/testing-python.nix { inherit system pkgs; }; 7 8let 9 readyFile = "/tmp/readerReady"; 10 resultFile = "/tmp/readerResult"; 11 12 testReader = pkgs.writeScript "test-input-reader" '' 13 rm -f ${resultFile} ${resultFile}.tmp 14 logger "testReader: START: Waiting for $1 characters, expecting '$2'." 15 touch ${readyFile} 16 read -r -N $1 chars 17 rm -f ${readyFile} 18 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 = layout: { extraConfig ? {}, tests }: with pkgs.lib; makeTest { 30 name = "keymap-${layout}"; 31 32 machine.console.keyMap = mkOverride 900 layout; 33 machine.services.xserver.desktopManager.xterm.enable = false; 34 machine.services.xserver.layout = mkOverride 900 layout; 35 machine.imports = [ ./common/x11.nix extraConfig ]; 36 37 testScript = '' 38 import json 39 import shlex 40 41 42 def run_test_case(cmd, xorg_keymap, test_case_name, inputs, expected): 43 with subtest(test_case_name): 44 assert len(inputs) == len(expected) 45 machine.execute("rm -f ${readyFile} ${resultFile}") 46 47 # set up process that expects all the keys to be entered 48 machine.succeed( 49 "{} {} {} {} >&2 &".format( 50 cmd, 51 "${testReader}", 52 len(inputs), 53 shlex.quote("".join(expected)), 54 ) 55 ) 56 57 if xorg_keymap: 58 # make sure the xterm window is open and has focus 59 machine.wait_for_window("testterm") 60 machine.wait_until_succeeds( 61 "${pkgs.xdotool}/bin/xdotool search --sync --onlyvisible " 62 "--class testterm windowfocus --sync" 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": "DISPLAY=:0 xterm -title testterm -class testterm -fullscreen -e", 91 "VT Keymap": "openvt -sw --", 92 } 93 94 machine.wait_for_x() 95 96 for keymap_env_name, command in keymap_environments.items(): 97 with subtest(keymap_env_name): 98 for test_case_name, test_data in tests.items(): 99 run_test_case( 100 command, 101 False, 102 test_case_name, 103 test_data["qwerty"], 104 test_data["expect"], 105 ) 106 ''; 107 }; 108 109in pkgs.lib.mapAttrs mkKeyboardTest { 110 azerty = { 111 tests = { 112 azqw.qwerty = [ "q" "w" ]; 113 azqw.expect = [ "a" "z" ]; 114 altgr.qwerty = [ "alt_r-2" "alt_r-3" "alt_r-4" "alt_r-5" "alt_r-6" ]; 115 altgr.expect = [ "~" "#" "{" "[" "|" ]; 116 }; 117 118 extraConfig.console.keyMap = "fr"; 119 extraConfig.services.xserver.layout = "fr"; 120 }; 121 122 bone = { 123 tests = { 124 layer1.qwerty = [ "f" "j" ]; 125 layer1.expect = [ "e" "n" ]; 126 layer2.qwerty = [ "shift-f" "shift-j" "shift-6" ]; 127 layer2.expect = [ "E" "N" "$" ]; 128 layer3.qwerty = [ "caps_lock-d" "caps_lock-f" ]; 129 layer3.expect = [ "{" "}" ]; 130 }; 131 132 extraConfig.console.keyMap = "bone"; 133 extraConfig.services.xserver.layout = "de"; 134 extraConfig.services.xserver.xkbVariant = "bone"; 135 }; 136 137 colemak = { 138 tests = { 139 homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ]; 140 homerow.expect = [ "a" "r" "s" "t" "n" "e" "i" "o" ]; 141 }; 142 143 extraConfig.console.keyMap = "colemak"; 144 extraConfig.services.xserver.layout = "us"; 145 extraConfig.services.xserver.xkbVariant = "colemak"; 146 }; 147 148 dvorak = { 149 tests = { 150 homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ]; 151 homerow.expect = [ "a" "o" "e" "u" "h" "t" "n" "s" ]; 152 symbols.qwerty = [ "q" "w" "e" "minus" "equal" ]; 153 symbols.expect = [ "'" "," "." "[" "]" ]; 154 }; 155 156 extraConfig.console.keyMap = "dvorak"; 157 extraConfig.services.xserver.layout = "us"; 158 extraConfig.services.xserver.xkbVariant = "dvorak"; 159 }; 160 161 dvorak-programmer = { 162 tests = { 163 homerow.qwerty = [ "a" "s" "d" "f" "j" "k" "l" "semicolon" ]; 164 homerow.expect = [ "a" "o" "e" "u" "h" "t" "n" "s" ]; 165 numbers.qwerty = map (x: "shift-${x}") 166 [ "1" "2" "3" "4" "5" "6" "7" "8" "9" "0" "minus" ]; 167 numbers.expect = [ "%" "7" "5" "3" "1" "9" "0" "2" "4" "6" "8" ]; 168 symbols.qwerty = [ "1" "2" "3" "4" "5" "6" "7" "8" "9" "0" "minus" ]; 169 symbols.expect = [ "&" "[" "{" "}" "(" "=" "*" ")" "+" "]" "!" ]; 170 }; 171 172 extraConfig.console.keyMap = "dvorak-programmer"; 173 extraConfig.services.xserver.layout = "us"; 174 extraConfig.services.xserver.xkbVariant = "dvp"; 175 }; 176 177 neo = { 178 tests = { 179 layer1.qwerty = [ "f" "j" ]; 180 layer1.expect = [ "e" "n" ]; 181 layer2.qwerty = [ "shift-f" "shift-j" "shift-6" ]; 182 layer2.expect = [ "E" "N" "$" ]; 183 layer3.qwerty = [ "caps_lock-d" "caps_lock-f" ]; 184 layer3.expect = [ "{" "}" ]; 185 }; 186 187 extraConfig.console.keyMap = "neo"; 188 extraConfig.services.xserver.layout = "de"; 189 extraConfig.services.xserver.xkbVariant = "neo"; 190 }; 191 192 qwertz = { 193 tests = { 194 zy.qwerty = [ "z" "y" ]; 195 zy.expect = [ "y" "z" ]; 196 altgr.qwerty = map (x: "alt_r-${x}") 197 [ "q" "less" "7" "8" "9" "0" ]; 198 altgr.expect = [ "@" "|" "{" "[" "]" "}" ]; 199 }; 200 201 extraConfig.console.keyMap = "de"; 202 extraConfig.services.xserver.layout = "de"; 203 }; 204}