Skip to content

Commit c20f64a

Browse files
committed
ui-tests: verify that interrupting clones via SSH works
This was the actual use case that was broken and necessitated the fix in 7674c51 (Cygwin: console: Set ENABLE_PROCESSED_INPUT when disable_master_thread, 2025-07-01). It does require an SSH server, which Git for Windows no longer ships. Therefore, this test uses the `sshd.exe` of OpenSSH for Windows (https://github.com/powershell/Win32-OpenSSH) in conjunction with Git for Windows' `ssh.exe` (because using OpenSSH for Windows' variant of `ssh.exe` would not exercise the MSYS2 runtime and therefore not demonstrate a regression, should it surface in the future). To avoid failing the test because OpenSSH for Windows is not available, the test case is guarded by the environment variable `OPENSSH_FOR_WINDOWS_DIRECTORY` which needs to point to a directory that contains a working `sshd.exe`. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent f96752c commit c20f64a

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

ui-tests/ctrl-c.ahk

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,73 @@ Sleep 150
3636
; Wait for the `^C` tell-tale that is the PowerShell prompt to appear
3737
WaitForRegExInWindowsTerminal('>[ `n`r]*$', 'Timed out waiting for interrupt', 'Sleep was interrupted as desired')
3838

39+
; Clone via SSH test; Requires an OpenSSH for Windows `sshd.exe` whose directory needs to be specified via
40+
; the environment variable `OPENSSH_FOR_WINDOWS_DIRECTORY`. The clone will still be performed via Git's
41+
; included `ssh.exe`, to exercise the MSYS2 runtime (which these UI tests are all about).
42+
43+
openSSHPath := EnvGet('OPENSSH_FOR_WINDOWS_DIRECTORY')
44+
if (openSSHPath != '' and FileExist(openSSHPath . '\sshd.exe')) {
45+
Info('Generate 26M of data')
46+
RunWait('git init --bare large.git', '', 'Hide')
47+
RunWait('git --git-dir=large.git -c alias.c="!(' .
48+
'printf \"reset refs/heads/main\\n\"; ' .
49+
'seq 100000 | ' .
50+
'sed \"s|.*|blob\\nmark :&\\ndata <<E\\n&\\nE\\ncommit refs/heads/main\\n' .
51+
'committer a <[email protected]> 1234& +0000\\ndata <<E\\n&\\nE\\nM 100644 :& file|\"' .
52+
') | git fast-import" c', '', 'Hide')
53+
Info('Done generating 26M of data')
54+
55+
; Set up SSH server
56+
Info('Generating host key')
57+
RunWait('git -c alias.c="!ssh-keygen -b 4096 -f ssh_host_rsa_key -N \"\"" c', '', 'Hide')
58+
if A_LastError
59+
ExitWithError 'Error generating host key: ' A_LastError
60+
Info('Generating client key')
61+
RunWait('git -c alias.c="!ssh-keygen -f id_rsa -N \"\"" c', '', 'Hide')
62+
if A_LastError
63+
ExitWithError 'Error generating client key: ' A_LastError
64+
FileAppend('Port 2322`n' .
65+
'HostKey "' . workTree . '\ssh_host_rsa_key"`n' .
66+
'AuthorizedKeysFile "' . workTree . '\id_rsa.pub"`n',
67+
'sshd_config')
68+
sshdOptions := '-f "' . workTree . '\sshd_config" -D -d -d -d -E sshd.log'
69+
70+
; Start SSH server
71+
Info('Starting SSH server')
72+
Run(openSSHPath . '\sshd.exe ' . sshdOptions, '', 'Hide', &sshdPID)
73+
if A_LastError
74+
ExitWithError 'Error starting SSH server: ' A_LastError
75+
Info('Started SSH server: ' sshdPID)
76+
77+
Info('Starting clone')
78+
workTreeMSYS := RunWaitOne('git -c alias.cygpath="!cygpath" cygpath -u "' . workTree . '"')
79+
sshOptions := '-i ' . workTreeMSYS . '/id_rsa -p 2322 -T ' .
80+
'-o UserKnownHostsFile=' . workTreeMSYS . '/known_hosts ' .
81+
'-o StrictHostKeyChecking=accept-new '
82+
; The `--upload-pack` option is needed because OpenSSH for Windows' default shell
83+
; is `cmd.exe`, which does not handle single-quoted strings as Git expects.
84+
; An heavy-handed alternative would be to require PowerShell to be configured via
85+
; HKLM:\SOFTWARE\OpenSSH's DefaultShell property, for full details see
86+
; https://github.com/PowerShell/Win32-OpenSSH/wiki/Setting-up-a-Git-server-on-Windows-using-Git-for-Windows-and-Win32_OpenSSH
87+
;
88+
; The username is needed because by default, on domain-joined machines MSYS2's
89+
; `ssh.exe` prefixes the username with the domain name.
90+
cloneOptions := '--upload-pack="powershell git upload-pack" ' .
91+
EnvGet('USERNAME') . '@localhost:' . workTree . '\large.git large-clone'
92+
Send('git -c core.sshCommand="ssh ' . sshOptions . '" clone ' . cloneOptions . '{Enter}')
93+
Sleep 50
94+
Info('Waiting for clone to start')
95+
WinActivate('ahk_id ' . hwnd)
96+
WaitForRegExInWindowsTerminal('remote: ', 'Timed out waiting for clone to start', 'Clone started', 5000, 'ahk_id ' . hwnd)
97+
Info('Trying to interrupt clone')
98+
Send('^C') ; interrupt clone
99+
Sleep 150
100+
WaitForRegExInWindowsTerminal('`nfatal: (.*`r?`n){1,3}PS .*>[ `n`r]*$', 'Timed out waiting for clone to be interrupted', 'clone was interrupted as desired')
101+
102+
if DirExist(workTree . '\large-clone')
103+
ExitWithError('`large-clone` was unexpectedly not deleted on interrupt')
104+
}
105+
39106
Send('exit{Enter}')
40107
Sleep 50
41108
CleanUpWorkTree()

0 commit comments

Comments
 (0)