Files
OpenHands/tests/unit/test_ipython.py
Shimada666 26fc3c886a Make plugins sandbox-agnostic (#2101)
* tmp

* tmp

* merge main

* feat: auto build image cache

* remove plugins

* use config file

* update mamba setup shell

* support agnostic sandbox image autobuild

* remove config

* Update .gitignore

Co-authored-by: Xingyao Wang <xingyao6@illinois.edu>

* Update opendevin/runtime/docker/ssh_box.py

Co-authored-by: Xingyao Wang <xingyao6@illinois.edu>

* update setup.sh

* readd sudo

* add sudo in dockerfile

* remove export

* move od-runtime dependencies to sandbox dockerfile

* factor out re-build logic into a separate util file

* tweak existing plugin to use OD specific sandbox

* update testcase

* attempt to fix unit test using image built in ghcr

* use cache tag

* try to fix unit tests

* add unittest

* add unittest

* add some unittests

* revert gh workflow changes

* feat: optimize sandbox image naming rule

* add pull latest image hint

* add opendevin python hint and use mamba to install gcc

* update docker image naming rule and fix mamba issue

* Update opendevin/runtime/docker/ssh_box.py

Co-authored-by: Boxuan Li <liboxuan@connect.hku.hk>

* fix: opendevin user use correct pip

* fix lint issue

* fix custom sandbox base image

* rename test name

* add skipif

---------

Co-authored-by: Graham Neubig <neubig@gmail.com>
Co-authored-by: Xingyao Wang <xingyao6@illinois.edu>
Co-authored-by: Boxuan Li <liboxuan@connect.hku.hk>
Co-authored-by: Yufan Song <33971064+yufansong@users.noreply.github.com>
Co-authored-by: tobitege <tobitege@gmx.de>
2024-06-19 19:58:07 -07:00

104 lines
3.9 KiB
Python

import pathlib
import tempfile
from unittest.mock import MagicMock, call, patch
import pytest
from opendevin.core.config import config
from opendevin.events.action import IPythonRunCellAction
from opendevin.events.observation import IPythonRunCellObservation
from opendevin.runtime.docker.ssh_box import DockerSSHBox
from opendevin.runtime.plugins import JupyterRequirement
from opendevin.runtime.server.runtime import ServerRuntime
@pytest.fixture
def temp_dir(monkeypatch):
# get a temporary directory
with tempfile.TemporaryDirectory() as temp_dir:
pathlib.Path().mkdir(parents=True, exist_ok=True)
yield temp_dir
@pytest.mark.asyncio
async def test_run_python_backticks():
# Create a mock event_stream
mock_event_stream = MagicMock()
test_code = "print('Hello, `World`!\n')"
# Mock the asynchronous sandbox execute method
mock_sandbox_execute = MagicMock()
mock_sandbox_execute.side_effect = [
(0, ''), # Initial call during DockerSSHBox initialization
(0, ''), # Initial call during DockerSSHBox initialization
(0, ''), # Initial call during DockerSSHBox initialization
(0, ''), # Write command
(0, test_code), # Execute command
]
# Set up the patches for the runtime and sandbox
with patch(
'opendevin.runtime.docker.ssh_box.DockerSSHBox.execute',
new=mock_sandbox_execute,
):
# Initialize the runtime with the mock event_stream
runtime = ServerRuntime(event_stream=mock_event_stream)
# Define the test action with a simple IPython command
action = IPythonRunCellAction(code=test_code)
# Call the run_ipython method with the test action
result = await runtime.run_action(action)
# Assert that the result is an instance of IPythonRunCellObservation
assert isinstance(result, IPythonRunCellObservation)
# Assert that the execute method was called with the correct commands
expected_write_command = (
"cat > /tmp/opendevin_jupyter_temp.py <<'EOL'\n" f'{test_code}\n' 'EOL'
)
expected_execute_command = 'cat /tmp/opendevin_jupyter_temp.py | execute_cli'
mock_sandbox_execute.assert_has_calls(
[
call('mkdir -p /tmp'),
call('git config --global user.name "OpenDevin"'),
call('git config --global user.email "opendevin@all-hands.dev"'),
call(expected_write_command),
call(expected_execute_command),
]
)
assert (
test_code == result.content
), f'The output should contain the expected print output, got: {result.content}'
def test_sandbox_jupyter_plugin_backticks(temp_dir):
# get a temporary directory
with patch.object(config, 'workspace_base', new=temp_dir), patch.object(
config, 'workspace_mount_path', new=temp_dir
), patch.object(config, 'run_as_devin', new='true'), patch.object(
config, 'sandbox_type', new='ssh'
):
for box in [DockerSSHBox()]:
box.init_plugins([JupyterRequirement])
test_code = "print('Hello, `World`!')"
expected_write_command = (
"cat > /tmp/opendevin_jupyter_temp.py <<'EOL'\n" f'{test_code}\n' 'EOL'
)
expected_execute_command = (
'cat /tmp/opendevin_jupyter_temp.py | execute_cli'
)
exit_code, output = box.execute(expected_write_command)
exit_code, output = box.execute(expected_execute_command)
print(output)
assert exit_code == 0, (
'The exit code should be 0 for ' + box.__class__.__name__
)
assert output.strip() == 'Hello, `World`!', (
'The output should be the same as the input for '
+ box.__class__.__name__
)
box.close()