mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
* mypy is invaluable * fix config, add test * Add new-style toml support * add singleton, small doc fixes * fix some cases of loading toml, clean up, try to make it clearer * Add defaults_dict for UI * allow config to be mutable error handling fix toml parsing * remove debug stuff * Adapt Makefile * Add defaults for temperature and top_p * update to CodeActAgent * comments * fix unit tests * implement groups of llm settings (CLI) * fix merge issue * small fix sandboxes, small refactoring * adapt LLM init to accept overrides at runtime * reading config is enough * Encapsulate minimally embeddings initialization * agent bug fix; fix tests * fix sandboxes tests * refactor globals in sandboxes to properties
152 lines
5.0 KiB
Python
152 lines
5.0 KiB
Python
from unittest.mock import MagicMock, call, patch
|
|
|
|
import pytest
|
|
|
|
from agenthub.dummy_agent.agent import DummyAgent
|
|
from opendevin.controller.agent_controller import AgentController
|
|
from opendevin.core.config import config
|
|
from opendevin.events.action.github import GitHubPushAction, GitHubSendPRAction
|
|
from opendevin.events.observation.commands import CmdOutputObservation
|
|
from opendevin.events.observation.error import ErrorObservation
|
|
from opendevin.events.stream import EventStream
|
|
from opendevin.llm.llm import LLM
|
|
|
|
|
|
@pytest.fixture
|
|
def agent_controller():
|
|
# Setup the environment variable
|
|
config.sandbox_type = 'local'
|
|
llm = LLM()
|
|
agent = DummyAgent(llm=llm)
|
|
event_stream = EventStream()
|
|
controller = AgentController(agent, event_stream)
|
|
yield controller
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch.object(config, 'github_token', 'fake_token')
|
|
@patch('random.choices')
|
|
@patch('opendevin.controller.action_manager.ActionManager.run_command')
|
|
async def test_run_push_successful(
|
|
mock_run_command, mock_random_choices, agent_controller
|
|
):
|
|
# Setup mock for random.choices
|
|
mock_random_choices.return_value = ['a', 'b', 'c', 'd', 'e']
|
|
|
|
# Create a CmdOutputObservation instance for successful command execution
|
|
successful_output = CmdOutputObservation(
|
|
content='', command_id=1, command='', exit_code=0
|
|
)
|
|
|
|
# Setup the mock for run_command to return successful output
|
|
mock_run_command.return_value = successful_output
|
|
|
|
# Run the method
|
|
push_action = GitHubPushAction(owner='owner', repo='repo', branch='branch')
|
|
result = await push_action.run(agent_controller)
|
|
|
|
# Verify the result is successful
|
|
assert isinstance(result, CmdOutputObservation)
|
|
assert result.exit_code == 0
|
|
|
|
# Verify that the correct remote commands were sent
|
|
expected_calls = [
|
|
call(
|
|
'git remote add opendevin_temp_abcde https://fake_token@github.com/owner/repo.git',
|
|
background=False,
|
|
),
|
|
call('git push opendevin_temp_abcde branch', background=False),
|
|
call('git remote remove opendevin_temp_abcde', background=False),
|
|
]
|
|
mock_run_command.assert_has_calls(expected_calls)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('random.choices')
|
|
@patch('opendevin.controller.action_manager.ActionManager.run_command')
|
|
async def test_run_push_error_missing_token(
|
|
mock_run_command, mock_random_choices, agent_controller
|
|
):
|
|
# Run the method
|
|
push_action = GitHubPushAction(owner='owner', repo='repo', branch='branch')
|
|
result = await push_action.run(agent_controller)
|
|
|
|
# Verify the result is an error due to missing token
|
|
assert isinstance(result, ErrorObservation)
|
|
assert result.message == 'github_token is not set'
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch.object(config, 'github_token', 'fake_token')
|
|
@patch('requests.post')
|
|
async def test_run_pull_request_created_successfully(mock_post, agent_controller):
|
|
# Set up the mock for the requests.post call to simulate a successful pull request creation
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 201
|
|
mock_response.json.return_value = {'html_url': 'https://github.com/example/pull/1'}
|
|
mock_post.return_value = mock_response
|
|
|
|
# Run the method
|
|
pr_action = GitHubSendPRAction(
|
|
owner='owner',
|
|
repo='repo',
|
|
title='title',
|
|
head='head',
|
|
head_repo='head_repo',
|
|
base='base',
|
|
body='body',
|
|
)
|
|
result = await pr_action.run(agent_controller)
|
|
|
|
# Verify the result is a success observation
|
|
assert 'Pull request created successfully' in result.content
|
|
assert 'https://github.com/example/pull/1' in result.content
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('requests.post')
|
|
@patch.object(config, 'github_token', 'fake_token')
|
|
async def test_run_pull_request_creation_failed(mock_post, agent_controller):
|
|
# Set up the mock for the requests.post call to simulate a failed pull request creation
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 400
|
|
mock_response.text = 'Bad Request'
|
|
mock_post.return_value = mock_response
|
|
|
|
# Run the method
|
|
pr_action = GitHubSendPRAction(
|
|
owner='owner',
|
|
repo='repo',
|
|
title='title',
|
|
head='head',
|
|
head_repo='head_repo',
|
|
base='base',
|
|
body='body',
|
|
)
|
|
result = await pr_action.run(agent_controller)
|
|
|
|
# Verify the result is an error observation
|
|
assert isinstance(result, ErrorObservation)
|
|
assert 'Failed to create pull request' in result.content
|
|
assert 'Status code: 400' in result.content
|
|
assert 'Bad Request' in result.content
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_run_error_missing_token(agent_controller):
|
|
# Run the method
|
|
pr_action = GitHubSendPRAction(
|
|
owner='owner',
|
|
repo='repo',
|
|
title='title',
|
|
head='head',
|
|
head_repo='head_repo',
|
|
base='base',
|
|
body='body',
|
|
)
|
|
result = await pr_action.run(agent_controller)
|
|
|
|
# Verify the result is an error due to missing token
|
|
assert isinstance(result, ErrorObservation)
|
|
assert 'github_token is not set' in result.message
|