Skip to content

Commit f8444c5

Browse files
committed
Improve timeout tests with safety harness
Removed duplicate sleep-only timeout tests. Added withTimeout to prevent tests from hanging if fix breaks. Tests now verify partial output capture.
1 parent a771586 commit f8444c5

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

agents/agents-ext/src/jvmTest/kotlin/ai/koog/agents/ext/tool/shell/ExecuteShellCommandToolJvmTest.kt

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import kotlinx.coroutines.delay
77
import kotlinx.coroutines.launch
88
import kotlinx.coroutines.runBlocking
99
import org.junit.jupiter.api.RepeatedTest
10+
import kotlinx.coroutines.withTimeout
1011
import org.junit.jupiter.api.Test
1112
import org.junit.jupiter.api.condition.EnabledOnOs
1213
import org.junit.jupiter.api.condition.OS
@@ -332,33 +333,47 @@ class ExecuteShellCommandToolJvmTest {
332333
fun `command with partial output times out`() = runBlocking {
333334
val result: ExecuteShellCommandTool.Result
334335
val executionTimeMs = measureTimeMillis {
335-
result = executeShellCommand("for i in {1..3}; do echo \$i; sleep 1; done", timeoutSeconds = 1)
336+
result = withTimeout(4000L) {
337+
executeShellCommand("for i in {1..10}; do echo \$i; sleep 1; done", timeoutSeconds = 1)
338+
}
336339
}
337340

338-
assertTrue(result.textForLLM().contains("Command timed out after 1 seconds"))
339-
assertTrue(result.textForLLM().startsWith("Command: for i in {1..3}; do echo \$i; sleep 1; done"))
341+
val partialExpected = """
342+
Command: for i in {1..10}; do echo ${'$'}i; sleep 1; done
343+
1
344+
""".trimIndent()
345+
346+
val output = result.textForLLM()
347+
assertTrue(output.contains(partialExpected))
348+
assertTrue(output.contains("Command timed out after 1 seconds"))
340349
assertNull(result.exitCode)
341-
assertTrue(executionTimeMs <= 1200, "Timeout should occur quickly, but took ${executionTimeMs}ms")
350+
assertTrue(executionTimeMs < 3000, "Should timeout at 1s, but took ${executionTimeMs}ms")
342351
}
343352

344353
@Test
345354
@EnabledOnOs(OS.WINDOWS)
346355
fun `command with partial output times out on Windows`() = runBlocking {
347356
val result: ExecuteShellCommandTool.Result
348357
val executionTimeMs = measureTimeMillis {
349-
result = executeShellCommand(
350-
"""cmd /c "echo 1 & echo 2 & echo 3 & powershell -Command Start-Sleep -Seconds 2"""",
351-
timeoutSeconds = 1
352-
)
358+
result = withTimeout(5000L) {
359+
executeShellCommand(
360+
"""cmd /c "echo 1 & echo 2 & echo 3 & timeout 10"""",
361+
timeoutSeconds = 1
362+
)
363+
}
353364
}
354365

355-
assertTrue(result.textForLLM().contains("Command timed out after 1 seconds"))
356-
assertTrue(
357-
result.textForLLM()
358-
.startsWith("Command: cmd /c \"echo 1 & echo 2 & echo 3 & powershell -Command Start-Sleep -Seconds 2\"")
359-
)
366+
val partialExpected = """
367+
Command: cmd /c "echo 1 & echo 2 & echo 3 & timeout 10"
368+
1
369+
370+
""".trimIndent()
371+
372+
val output = result.textForLLM()
373+
assertTrue(output.contains(partialExpected))
374+
assertTrue(output.contains("Command timed out after 1 seconds"))
360375
assertNull(result.exitCode)
361-
assertTrue(executionTimeMs <= 1300, "Timeout should occur quickly, but took ${executionTimeMs}ms")
376+
assertTrue(executionTimeMs < 4000, "Should timeout at 1s, but took ${executionTimeMs}ms")
362377
}
363378

364379
// CANCELLATION TESTS

0 commit comments

Comments
 (0)