Skip to content

Commit 1832d0a

Browse files
stephentoubCopilot
andauthored
Avoid shell kill cwd cleanup flakes (#1207)
* Avoid shell kill cwd cleanup flake Run the long-lived shell kill command outside the fixture workspace so a surviving Windows child process cannot hold copilot-test-work-* open during cleanup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Avoid shell kill cwd flakes across SDKs Run mirrored long-lived shell kill E2E commands outside each fixture workspace so surviving Windows child processes cannot block temp workspace cleanup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Wait for CLI stderr on stdio disconnect When stdio startup fails quickly, wait briefly for the stderr reader before formatting the connection-lost exception so CLI argument errors are reported deterministically. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Include CLI stderr for stdio startup pipe failures Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert "Include CLI stderr for stdio startup pipe failures" This reverts commit b35e9f6. * Revert "Wait for CLI stderr on stdio disconnect" This reverts commit 344b18f. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3c622b9 commit 1832d0a

4 files changed

Lines changed: 16 additions & 4 deletions

File tree

dotnet/test/E2E/RpcShellAndFleetE2ETests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ public async Task Should_Kill_Shell_Process()
3434
? "powershell -NoLogo -NoProfile -Command \"Start-Sleep -Seconds 30\""
3535
: "sleep 30";
3636

37-
var execResult = await session.Rpc.Shell.ExecAsync(command);
37+
// On Windows, terminating the shell wrapper can briefly leave grandchildren alive.
38+
// Keep this command outside the fixture workspace so that cleanup is not blocked by cwd handles.
39+
var execResult = await session.Rpc.Shell.ExecAsync(command, cwd: Path.GetTempPath());
3840
Assert.False(string.IsNullOrWhiteSpace(execResult.ProcessId));
3941

4042
var killResult = await session.Rpc.Shell.KillAsync(execResult.ProcessId);

go/internal/e2e/rpc_shell_and_fleet_e2e_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ func TestRpcShellAndFleetE2E(t *testing.T) {
6363
command = "sleep 30"
6464
}
6565

66-
exec, err := session.RPC.Shell.Exec(t.Context(), &rpc.ShellExecRequest{Command: command})
66+
// On Windows, terminating the shell wrapper can briefly leave grandchildren alive.
67+
// Keep this command outside the fixture workspace so cleanup is not blocked by cwd handles.
68+
cwd := os.TempDir()
69+
exec, err := session.RPC.Shell.Exec(t.Context(), &rpc.ShellExecRequest{Command: command, Cwd: &cwd})
6770
if err != nil {
6871
t.Fatalf("Failed to call session.shell.exec: %v", err)
6972
}

nodejs/test/e2e/rpc_shell_and_fleet.e2e.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ describe("Shell and fleet RPC", async () => {
8585
? `powershell -NoLogo -NoProfile -Command "Start-Sleep -Seconds 30"`
8686
: "sleep 30";
8787

88-
const execResult = await session.rpc.shell.exec({ command });
88+
// On Windows, terminating the shell wrapper can briefly leave grandchildren alive.
89+
// Keep this command outside the fixture workspace so cleanup is not blocked by cwd handles.
90+
const execResult = await session.rpc.shell.exec({ command, cwd: os.tmpdir() });
8991
expect(execResult.processId).toBeTruthy();
9092

9193
const killResult = await session.rpc.shell.kill({ processId: execResult.processId });

python/e2e/test_rpc_shell_and_fleet_e2e.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import asyncio
1111
import sys
12+
import tempfile
1213
import uuid
1314
from pathlib import Path
1415

@@ -75,7 +76,11 @@ async def test_should_kill_shell_process(self, ctx: E2ETestContext):
7576
else:
7677
command = "sleep 30"
7778

78-
exec_result = await session.rpc.shell.exec(ShellExecRequest(command=command))
79+
# On Windows, terminating the shell wrapper can briefly leave grandchildren alive.
80+
# Keep this command outside the fixture workspace so cleanup is not blocked by cwd handles.
81+
exec_result = await session.rpc.shell.exec(
82+
ShellExecRequest(command=command, cwd=tempfile.gettempdir())
83+
)
7984
assert (exec_result.process_id or "").strip()
8085

8186
kill_result = await session.rpc.shell.kill(

0 commit comments

Comments
 (0)