@@ -106,27 +106,28 @@ class TestAsyncDevboxCommandExecution:
106106 @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
107107 async def test_exec_simple_command (self , shared_devbox : AsyncDevbox ) -> None :
108108 """Test executing a simple command asynchronously."""
109- result = await shared_devbox .cmd .exec ("echo 'Hello from async SDK!'" )
109+ result = await shared_devbox .cmd .exec (command = "echo 'Hello from async SDK!'" )
110110
111111 assert result is not None
112112 assert result .exit_code == 0
113113 assert result .success is True
114114
115- stdout = await result .stdout ()
115+ stdout = await result .stdout (num_lines = 1 )
116116 assert "Hello from async SDK!" in stdout
117117
118118 @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
119119 async def test_exec_with_exit_code (self , shared_devbox : AsyncDevbox ) -> None :
120120 """Test command execution captures exit codes correctly."""
121- result = await shared_devbox .cmd .exec ("exit 42" )
121+ result = await shared_devbox .cmd .exec (command = "exit 42" )
122122
123123 assert result .exit_code == 42
124124 assert result .success is False
125+ assert await result .stdout (num_lines = 1 ) == ""
125126
126127 @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
127128 async def test_exec_async_command (self , shared_devbox : AsyncDevbox ) -> None :
128129 """Test executing a command asynchronously with exec_async."""
129- execution = await shared_devbox .cmd .exec_async ("echo 'Async command' && sleep 1" )
130+ execution = await shared_devbox .cmd .exec_async (command = "echo 'Async command' && sleep 1" )
130131
131132 assert execution is not None
132133 assert execution .execution_id is not None
@@ -136,7 +137,7 @@ async def test_exec_async_command(self, shared_devbox: AsyncDevbox) -> None:
136137 assert result .exit_code == 0
137138 assert result .success is True
138139
139- stdout = await result .stdout ()
140+ stdout = await result .stdout (num_lines = 2 )
140141 assert "Async command" in stdout
141142
142143 @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
@@ -148,13 +149,16 @@ def stdout_callback(line: str) -> None:
148149 stdout_lines .append (line )
149150
150151 result = await shared_devbox .cmd .exec (
151- 'echo "line1" && echo "line2" && echo "line3"' ,
152+ command = 'echo "line1" && echo "line2" && echo "line3"' ,
152153 stdout = stdout_callback ,
153154 )
154155
155156 assert result .success is True
156157 assert result .exit_code == 0
157158
159+ combined_stdout = await result .stdout (num_lines = 3 )
160+ assert "line1" in combined_stdout
161+
158162 # Verify callback received output
159163 assert len (stdout_lines ) > 0
160164 stdout_combined = "" .join (stdout_lines )
@@ -171,19 +175,36 @@ def stderr_callback(line: str) -> None:
171175 stderr_lines .append (line )
172176
173177 result = await shared_devbox .cmd .exec (
174- 'echo "error1" >&2 && echo "error2" >&2' ,
178+ command = 'echo "error1" >&2 && echo "error2" >&2' ,
175179 stderr = stderr_callback ,
176180 )
177181
178182 assert result .success is True
179183 assert result .exit_code == 0
180184
185+ combined_stderr = await result .stderr (num_lines = 2 )
186+ assert "error1" in combined_stderr
187+
181188 # Verify callback received stderr output
182189 assert len (stderr_lines ) > 0
183190 stderr_combined = "" .join (stderr_lines )
184191 assert "error1" in stderr_combined
185192 assert "error2" in stderr_combined
186193
194+ @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
195+ async def test_exec_with_large_stdout (self , shared_devbox : AsyncDevbox ) -> None :
196+ """Ensure we capture all stdout lines (similar to TS last_n coverage)."""
197+ result = await shared_devbox .cmd .exec (
198+ command = "; " .join ([f"echo line { i } " for i in range (1 , 7 )]),
199+ )
200+
201+ assert result .exit_code == 0
202+ lines = (await result .stdout ()).strip ().split ("\n " )
203+ assert lines == [f"line { i } " for i in range (1 , 7 )]
204+
205+ tail = (await result .stdout (num_lines = 3 )).strip ().split ("\n " )
206+ assert tail == ["line 4" , "line 5" , "line 6" ]
207+
187208 @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
188209 async def test_exec_with_output_callback (self , shared_devbox : AsyncDevbox ) -> None :
189210 """Test command execution with combined output callback."""
@@ -193,13 +214,16 @@ def output_callback(line: str) -> None:
193214 output_lines .append (line )
194215
195216 result = await shared_devbox .cmd .exec (
196- 'echo "stdout1" && echo "stderr1" >&2 && echo "stdout2"' ,
217+ command = 'echo "stdout1" && echo "stderr1" >&2 && echo "stdout2"' ,
197218 output = output_callback ,
198219 )
199220
200221 assert result .success is True
201222 assert result .exit_code == 0
202223
224+ stdout_capture = await result .stdout (num_lines = 2 )
225+ assert "stdout1" in stdout_capture or "stdout2" in stdout_capture
226+
203227 # Verify callback received both stdout and stderr
204228 assert len (output_lines ) > 0
205229 output_combined = "" .join (output_lines )
@@ -214,7 +238,7 @@ def stdout_callback(line: str) -> None:
214238 stdout_lines .append (line )
215239
216240 execution = await shared_devbox .cmd .exec_async (
217- 'echo "async output"' ,
241+ command = 'echo "async output"' ,
218242 stdout = stdout_callback ,
219243 )
220244
@@ -225,6 +249,9 @@ def stdout_callback(line: str) -> None:
225249 assert result .success is True
226250 assert result .exit_code == 0
227251
252+ async_stdout = await result .stdout (num_lines = 1 )
253+ assert "async output" in async_stdout
254+
228255 # Verify streaming captured output
229256 assert len (stdout_lines ) > 0
230257 stdout_combined = "" .join (stdout_lines )
@@ -241,10 +268,10 @@ async def test_file_write_and_read(self, shared_devbox: AsyncDevbox) -> None:
241268 content = "Hello from async SDK file operations!"
242269
243270 # Write file
244- await shared_devbox .file .write (file_path , content )
271+ await shared_devbox .file .write (file_path = file_path , contents = content )
245272
246273 # Read file
247- read_content = await shared_devbox .file .read (file_path )
274+ read_content = await shared_devbox .file .read (file_path = file_path )
248275 assert read_content == content
249276
250277 @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
@@ -254,10 +281,10 @@ async def test_file_write_bytes(self, shared_devbox: AsyncDevbox) -> None:
254281 content = b"Binary content from async SDK"
255282
256283 # Write bytes
257- await shared_devbox .file .write (file_path , content )
284+ await shared_devbox .file .write (file_path = file_path , contents = content . decode ( "utf-8" ) )
258285
259286 # Read and verify
260- read_content = await shared_devbox .file .read (file_path )
287+ read_content = await shared_devbox .file .read (file_path = file_path )
261288 assert read_content == content .decode ("utf-8" )
262289
263290 @pytest .mark .timeout (THIRTY_SECOND_TIMEOUT )
@@ -267,10 +294,10 @@ async def test_file_download(self, shared_devbox: AsyncDevbox) -> None:
267294 content = "Content to download"
268295
269296 # Write file first
270- await shared_devbox .file .write (file_path , content )
297+ await shared_devbox .file .write (file_path = file_path , contents = content )
271298
272299 # Download file
273- downloaded = await shared_devbox .file .download (file_path )
300+ downloaded = await shared_devbox .file .download (path = file_path )
274301 assert isinstance (downloaded , bytes )
275302 assert downloaded .decode ("utf-8" ) == content
276303
@@ -285,10 +312,10 @@ async def test_file_upload(self, shared_devbox: AsyncDevbox) -> None:
285312 try :
286313 # Upload file
287314 remote_path = "~/uploaded_async_test.txt"
288- await shared_devbox .file .upload (remote_path , Path (tmp_path ))
315+ await shared_devbox .file .upload (path = remote_path , file = Path (tmp_path ))
289316
290317 # Verify by reading
291- content = await shared_devbox .file .read (remote_path )
318+ content = await shared_devbox .file .read (file_path = remote_path )
292319 assert content == "Uploaded content from async SDK"
293320 finally :
294321 # Cleanup temp file
@@ -309,6 +336,10 @@ async def test_suspend_and_resume(self, async_sdk_client: AsyncRunloopSDK) -> No
309336 try :
310337 # Suspend the devbox
311338 suspended_info = await devbox .suspend ()
339+ if suspended_info .status != "suspended" :
340+ suspended_info = await devbox .await_suspended (
341+ polling_config = PollingConfig (timeout_seconds = 120.0 , interval_seconds = 5.0 )
342+ )
312343 assert suspended_info .status == "suspended"
313344
314345 # Verify suspended state
@@ -317,6 +348,10 @@ async def test_suspend_and_resume(self, async_sdk_client: AsyncRunloopSDK) -> No
317348
318349 # Resume the devbox
319350 resumed_info = await devbox .resume ()
351+ if resumed_info .status != "running" :
352+ resumed_info = await devbox .await_running (
353+ polling_config = PollingConfig (timeout_seconds = 120.0 , interval_seconds = 5.0 )
354+ )
320355 assert resumed_info .status == "running"
321356
322357 # Verify running state
@@ -402,7 +437,7 @@ async def test_create_from_blueprint_id(self, async_sdk_client: AsyncRunloopSDK)
402437 try :
403438 # Create devbox from blueprint
404439 devbox = await async_sdk_client .devbox .create_from_blueprint_id (
405- blueprint .id ,
440+ blueprint_id = blueprint .id ,
406441 name = unique_name ("sdk-async-devbox-from-blueprint-id" ),
407442 launch_parameters = {"resource_size_request" : "SMALL" , "keep_alive_time_seconds" : 60 * 5 },
408443 )
@@ -430,7 +465,7 @@ async def test_create_from_blueprint_name(self, async_sdk_client: AsyncRunloopSD
430465 try :
431466 # Create devbox from blueprint name
432467 devbox = await async_sdk_client .devbox .create_from_blueprint_name (
433- blueprint_name ,
468+ blueprint_name = blueprint_name ,
434469 name = unique_name ("sdk-async-devbox-from-blueprint-name" ),
435470 launch_parameters = {"resource_size_request" : "SMALL" , "keep_alive_time_seconds" : 60 * 5 },
436471 )
@@ -455,7 +490,9 @@ async def test_create_from_snapshot(self, async_sdk_client: AsyncRunloopSDK) ->
455490
456491 try :
457492 # Create a file in the devbox
458- await source_devbox .file .write ("/tmp/test_async_snapshot.txt" , "Async snapshot test content" )
493+ await source_devbox .file .write (
494+ file_path = "/tmp/test_async_snapshot.txt" , contents = "Async snapshot test content"
495+ )
459496
460497 # Create snapshot
461498 snapshot = await source_devbox .snapshot_disk (
@@ -465,7 +502,7 @@ async def test_create_from_snapshot(self, async_sdk_client: AsyncRunloopSDK) ->
465502 try :
466503 # Create devbox from snapshot
467504 devbox = await async_sdk_client .devbox .create_from_snapshot (
468- snapshot .id ,
505+ snapshot_id = snapshot .id ,
469506 name = unique_name ("sdk-async-devbox-from-snapshot" ),
470507 launch_parameters = {"resource_size_request" : "SMALL" , "keep_alive_time_seconds" : 60 * 5 },
471508 )
@@ -476,7 +513,7 @@ async def test_create_from_snapshot(self, async_sdk_client: AsyncRunloopSDK) ->
476513 assert info .status == "running"
477514
478515 # Verify snapshot content is present
479- content = await devbox .file .read ("/tmp/test_async_snapshot.txt" )
516+ content = await devbox .file .read (file_path = "/tmp/test_async_snapshot.txt" )
480517 assert content == "Async snapshot test content"
481518 finally :
482519 await devbox .shutdown ()
@@ -532,7 +569,7 @@ async def test_snapshot_disk(self, async_sdk_client: AsyncRunloopSDK) -> None:
532569
533570 try :
534571 # Create a file to snapshot
535- await devbox .file .write ("/tmp/async_snapshot_test.txt" , "Async snapshot content" )
572+ await devbox .file .write (file_path = "/tmp/async_snapshot_test.txt" , contents = "Async snapshot content" )
536573
537574 # Create snapshot (waits for completion)
538575 snapshot = await devbox .snapshot_disk (
0 commit comments