diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 571ce3430..0c16b353b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,10 +96,11 @@ jobs: os: windows-latest python-version: "3.14" coverage: false - # Keep each test file in one worker while using both hosted-runner cores. - # Keep test names visible until a Windows-only control-event - # interruption can be attributed to its active worker/file. - pytest_args: "-n 2 --dist loadfile -vv" + # Real PowerShell/process-tree tests share the hosted runner's + # Windows console. Separate xdist workers can therefore deliver a + # control event across worker boundaries; run this compatibility + # matrix serially, as nanobot itself does in one client process. + pytest_args: "--full-trace" steps: - uses: actions/checkout@v4 diff --git a/tests/tools/test_exec_platform.py b/tests/tools/test_exec_platform.py index 637a3ec60..3162453d3 100644 --- a/tests/tools/test_exec_platform.py +++ b/tests/tools/test_exec_platform.py @@ -896,30 +896,33 @@ class TestWindowsRealExec: @pytest.mark.asyncio async def test_windows_powershell_session_output_is_utf8(self): manager = ExecSessionManager() - result = await ExecTool(timeout=180, session_manager=manager).execute( - command="Start-Sleep -Milliseconds 1500; Write-Output 'café λ 你好'", - shell="powershell", - yield_time_ms=1000, - ) - - if "session_id:" in result: - session_id = result.split("session_id:", 1)[1].splitlines()[0].strip() - poll_result = await WriteStdinTool(manager=manager).execute( - session_id=session_id, - chars="", - wait_for="café λ 你好", - wait_timeout_ms=120_000, + try: + result = await ExecTool(timeout=180, session_manager=manager).execute( + command="Start-Sleep -Milliseconds 1500; Write-Output 'café λ 你好'", + shell="powershell", + yield_time_ms=1000, ) - result += "\n" + poll_result - if "Process running." in poll_result: - final_result = await WriteStdinTool(manager=manager).execute( + + if "session_id:" in result: + session_id = result.split("session_id:", 1)[1].splitlines()[0].strip() + poll_result = await WriteStdinTool(manager=manager).execute( session_id=session_id, chars="", - yield_time_ms=30_000, + wait_for="café λ 你好", + wait_timeout_ms=120_000, ) - result += "\n" + final_result - assert "Process running." not in final_result + result += "\n" + poll_result + if "Process running." in poll_result: + final_result = await WriteStdinTool(manager=manager).execute( + session_id=session_id, + chars="", + yield_time_ms=30_000, + ) + result += "\n" + final_result + assert "Process running." not in final_result - assert "café λ 你好" in result - assert "Exit code: 0" in result - assert "\x00" not in result + assert "café λ 你好" in result + assert "Exit code: 0" in result + assert "\x00" not in result + finally: + await manager.close_all()