You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_commandline_code_executor.py 5.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. # File based from: https://github.com/microsoft/autogen/blob/main/test/coding/test_commandline_code_executor.py
  2. # Credit to original authors
  3. import asyncio
  4. import sys
  5. import tempfile
  6. from pathlib import Path
  7. import pytest
  8. from agnext.components.code_executor import CodeBlock, LocalCommandLineCodeExecutor
  9. from agnext.core import CancellationToken
  10. UNIX_SHELLS = ["bash", "sh", "shell"]
  11. WINDOWS_SHELLS = ["ps1", "pwsh", "powershell"]
  12. PYTHON_VARIANTS = ["python", "Python", "py"]
  13. @pytest.mark.asyncio
  14. async def test_execute_code() -> None:
  15. with tempfile.TemporaryDirectory() as temp_dir:
  16. cancellation_token = CancellationToken()
  17. executor = LocalCommandLineCodeExecutor(work_dir=temp_dir)
  18. # Test single code block.
  19. code_blocks = [CodeBlock(code="import sys; print('hello world!')", language="python")]
  20. code_result = await executor.execute_code_blocks(code_blocks, cancellation_token)
  21. assert code_result.exit_code == 0 and "hello world!" in code_result.output and code_result.code_file is not None
  22. # Test multiple code blocks.
  23. code_blocks = [
  24. CodeBlock(code="import sys; print('hello world!')", language="python"),
  25. CodeBlock(code="a = 100 + 100; print(a)", language="python"),
  26. ]
  27. code_result = await executor.execute_code_blocks(code_blocks, cancellation_token)
  28. assert (
  29. code_result.exit_code == 0
  30. and "hello world!" in code_result.output
  31. and "200" in code_result.output
  32. and code_result.code_file is not None
  33. )
  34. # Test bash script.
  35. if sys.platform not in ["win32"]:
  36. code_blocks = [CodeBlock(code="echo 'hello world!'", language="bash")]
  37. code_result = await executor.execute_code_blocks(code_blocks, cancellation_token)
  38. assert code_result.exit_code == 0 and "hello world!" in code_result.output and code_result.code_file is not None
  39. # Test running code.
  40. file_lines = ["import sys", "print('hello world!')", "a = 100 + 100", "print(a)"]
  41. code_blocks = [CodeBlock(code="\n".join(file_lines), language="python")]
  42. code_result = await executor.execute_code_blocks(code_blocks, cancellation_token)
  43. assert (
  44. code_result.exit_code == 0
  45. and "hello world!" in code_result.output
  46. and "200" in code_result.output
  47. and code_result.code_file is not None
  48. )
  49. # Check saved code file.
  50. with open(code_result.code_file) as f:
  51. code_lines = f.readlines()
  52. for file_line, code_line in zip(file_lines, code_lines):
  53. assert file_line.strip() == code_line.strip()
  54. @pytest.mark.asyncio
  55. async def test_commandline_code_executor_timeout() -> None:
  56. with tempfile.TemporaryDirectory() as temp_dir:
  57. cancellation_token = CancellationToken()
  58. executor = LocalCommandLineCodeExecutor(timeout=1, work_dir=temp_dir)
  59. code_blocks = [CodeBlock(code="import time; time.sleep(10); print('hello world!')", language="python")]
  60. code_result = await executor.execute_code_blocks(code_blocks, cancellation_token)
  61. assert code_result.exit_code and "Timeout" in code_result.output
  62. @pytest.mark.asyncio
  63. async def test_commandline_code_executor_cancellation() -> None:
  64. with tempfile.TemporaryDirectory() as temp_dir:
  65. cancellation_token = CancellationToken()
  66. executor = LocalCommandLineCodeExecutor(work_dir=temp_dir)
  67. code_blocks = [CodeBlock(code="import time; time.sleep(10); print('hello world!')", language="python")]
  68. coro = executor.execute_code_blocks(code_blocks, cancellation_token)
  69. await asyncio.sleep(1)
  70. cancellation_token.cancel()
  71. code_result = await coro
  72. assert code_result.exit_code and "Cancelled" in code_result.output
  73. def test_local_commandline_code_executor_restart() -> None:
  74. executor = LocalCommandLineCodeExecutor()
  75. with pytest.warns(UserWarning, match=r".*No action is taken."):
  76. executor.restart()
  77. @pytest.mark.asyncio
  78. async def test_invalid_relative_path() -> None:
  79. cancellation_token = CancellationToken()
  80. executor = LocalCommandLineCodeExecutor()
  81. code = """# filename: /tmp/test.py
  82. print("hello world")
  83. """
  84. result = await executor.execute_code_blocks([CodeBlock(code=code, language="python")], cancellation_token=cancellation_token)
  85. assert result.exit_code == 1 and "Filename is not in the workspace" in result.output
  86. @pytest.mark.asyncio
  87. async def test_valid_relative_path() -> None:
  88. with tempfile.TemporaryDirectory() as temp_dir_str:
  89. cancellation_token = CancellationToken()
  90. temp_dir = Path(temp_dir_str)
  91. executor = LocalCommandLineCodeExecutor(work_dir=temp_dir)
  92. code = """# filename: test.py
  93. print("hello world")
  94. """
  95. result = await executor.execute_code_blocks([CodeBlock(code=code, language="python")], cancellation_token=cancellation_token)
  96. assert result.exit_code == 0
  97. assert "hello world" in result.output
  98. assert result.code_file is not None
  99. assert "test.py" in result.code_file
  100. assert (temp_dir / Path("test.py")).resolve() == Path(result.code_file).resolve()
  101. assert (temp_dir / Path("test.py")).exists()