conftest.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import datetime
  2. import logging
  3. import os
  4. import shutil
  5. import subprocess
  6. import pytest
  7. SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
  8. CASES_DIR = os.path.join(SCRIPT_DIR, 'cases')
  9. AGENTHUB_DIR = os.path.join(SCRIPT_DIR, '../', 'agenthub')
  10. def agents():
  11. """Retrieves a list of available agents.
  12. Returns:
  13. A list of agent names.
  14. """
  15. agents = []
  16. for agent in os.listdir(AGENTHUB_DIR):
  17. if os.path.isdir(os.path.join(AGENTHUB_DIR, agent)) and agent.endswith(
  18. '_agent'
  19. ):
  20. agents.append(agent)
  21. return agents
  22. @pytest.fixture(scope='session')
  23. def test_cases_dir():
  24. """Fixture that provides the directory path for test cases.
  25. Returns:
  26. The directory path for test cases.
  27. """
  28. return CASES_DIR
  29. @pytest.fixture
  30. def task_file(test_cases_dir, request):
  31. """Fixture that provides the path to the task file for a test case.
  32. Args:
  33. test_cases_dir: The directory path for test cases.
  34. request: The pytest request object.
  35. Returns:
  36. The path to the task file for the test case.
  37. """
  38. test_case_dir = os.path.dirname(request.module.__file__)
  39. task_file_path = os.path.join(test_case_dir, 'task.txt')
  40. return task_file_path
  41. @pytest.fixture
  42. def workspace_dir(test_cases_dir, request):
  43. """Fixture that provides the workspace directory for a test case.
  44. Args:
  45. test_cases_dir: The directory path for test cases.
  46. request: The pytest request object.
  47. Returns:
  48. The workspace directory for the test case.
  49. """
  50. test_case_dir = os.path.dirname(request.module.__file__)
  51. workspace_dir = os.path.join(test_case_dir, 'workspace')
  52. return workspace_dir
  53. @pytest.fixture
  54. def model(request):
  55. """Fixture that provides the model name.
  56. Args:
  57. request: The pytest request object.
  58. Returns:
  59. The model name, defaulting to "gpt-3.5-turbo".
  60. """
  61. return request.config.getoption('model', default='gpt-3.5-turbo')
  62. @pytest.fixture
  63. def run_test_case(test_cases_dir, workspace_dir, request):
  64. """Fixture that provides a function to run a test case.
  65. Args:
  66. test_cases_dir: The directory path for test cases.
  67. workspace_dir: The workspace directory for the test case.
  68. request: The pytest request object.
  69. Returns:
  70. A function that runs a test case for a given agent and case.
  71. """
  72. def _run_test_case(agent, case):
  73. """Runs a test case for a given agent.
  74. Args:
  75. agent: The name of the agent to run the test case for.
  76. case: The name of the test case to run.
  77. Returns:
  78. The path to the workspace directory for the agent and test case.
  79. Raises:
  80. AssertionError: If the test case execution fails (non-zero return code).
  81. Steps:
  82. """
  83. case_dir = os.path.join(test_cases_dir, case)
  84. task = open(os.path.join(case_dir, 'task.txt'), 'r').read().strip()
  85. outputs_dir = os.path.join(case_dir, 'outputs')
  86. agent_dir = os.path.join(outputs_dir, agent)
  87. if not os.path.exists(agent_dir):
  88. os.makedirs(agent_dir)
  89. shutil.rmtree(os.path.join(agent_dir, 'workspace'), ignore_errors=True)
  90. if os.path.isdir(os.path.join(case_dir, 'start')):
  91. os.copytree(
  92. os.path.join(case_dir, 'start'), os.path.join(agent_dir, 'workspace')
  93. )
  94. else:
  95. os.makedirs(os.path.join(agent_dir, 'workspace'))
  96. agents_ref = {
  97. 'codeact_agent': 'CodeActAgent',
  98. }
  99. process = subprocess.Popen(
  100. [
  101. 'python3',
  102. f'{SCRIPT_DIR}/../../openhands/main.py',
  103. '-d',
  104. f"{os.path.join(agent_dir, 'workspace')}",
  105. '-c',
  106. f'{agents_ref[agent]}',
  107. '-t',
  108. f'{task}',
  109. '-m',
  110. 'gpt-3.5-turbo',
  111. ],
  112. stdout=subprocess.PIPE,
  113. stderr=subprocess.PIPE,
  114. universal_newlines=True,
  115. )
  116. stdout, stderr = process.communicate()
  117. logging.info(f'Stdout: {stdout}')
  118. logging.error(f'Stderr: {stderr}')
  119. assert process.returncode == 0
  120. return os.path.join(agent_dir, 'workspace')
  121. return _run_test_case
  122. def pytest_configure(config):
  123. """Configuration hook for pytest.
  124. Args:
  125. config: The pytest configuration object.
  126. """
  127. now = datetime.datetime.now()
  128. logging.basicConfig(
  129. level=logging.INFO,
  130. format='%(asctime)s [%(levelname)s] %(message)s',
  131. handlers=[
  132. logging.FileHandler(f"test_results_{now.strftime('%Y%m%d_%H%M%S')}.log"),
  133. logging.StreamHandler(),
  134. ],
  135. )