diff --git a/autogpt/commands/execute_code.py b/autogpt/commands/execute_code.py index 590f95cc..1bcdede2 100644 --- a/autogpt/commands/execute_code.py +++ b/autogpt/commands/execute_code.py @@ -113,15 +113,9 @@ def execute_shell(command_line: str) -> str: str: The output of the command """ - if not CFG.execute_local_commands: - return ( - "You are not allowed to run local shell commands. To execute" - " shell commands, EXECUTE_LOCAL_COMMANDS must be set to 'True' " - "in your config. Do not attempt to bypass the restriction." - ) - current_dir = os.getcwd() + current_dir = Path.cwd() # Change dir into workspace if necessary - if CFG.workspace_path not in current_dir: + if not current_dir.is_relative_to(CFG.workspace_path): os.chdir(CFG.workspace_path) print(f"Executing command '{command_line}' in working directory '{os.getcwd()}'") @@ -154,6 +148,7 @@ def execute_shell_popen(command_line) -> str: Returns: str: Description of the fact that the process started and its id """ + current_dir = os.getcwd() # Change dir into workspace if necessary if CFG.workspace_path not in current_dir: diff --git a/tests/conftest.py b/tests/conftest.py index c5814b0a..e3c590d2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,7 @@ from pathlib import Path import pytest +from pytest_mock import MockerFixture from autogpt.api_manager import ApiManager from autogpt.config import Config @@ -10,7 +11,7 @@ pytest_plugins = ["tests.integration.agent_factory"] @pytest.fixture() -def workspace_root(tmp_path) -> Path: +def workspace_root(tmp_path: Path) -> Path: return tmp_path / "home/users/monty/auto_gpt_workspace" @@ -21,20 +22,17 @@ def workspace(workspace_root: Path) -> Workspace: @pytest.fixture() -def config(workspace: Workspace) -> Config: +def config(mocker: MockerFixture, workspace: Workspace) -> Config: config = Config() # Do a little setup and teardown since the config object is a singleton - old_ws_path = config.workspace_path - old_file_logger_path = config.file_logger_path - - config.workspace_path = workspace.root - config.file_logger_path = workspace.get_path("file_logger.txt") + mocker.patch.multiple( + config, + workspace_path=workspace.root, + file_logger_path=workspace.get_path("file_logger.txt"), + ) yield config - config.file_logger_path = old_file_logger_path - config.workspace_path = old_ws_path - @pytest.fixture() def api_manager() -> ApiManager: diff --git a/tests/integration/test_execute_code.py b/tests/integration/test_execute_code.py new file mode 100644 index 00000000..2d4e0293 --- /dev/null +++ b/tests/integration/test_execute_code.py @@ -0,0 +1,50 @@ +import random +import string +import tempfile + +import pytest +from pytest_mock import MockerFixture + +import autogpt.commands.execute_code as sut # system under testing +from autogpt.config import Config + + +@pytest.fixture +def config_allow_execute(config: Config, mocker: MockerFixture): + yield mocker.patch.object(config, "execute_local_commands", True) + + +@pytest.fixture +def python_test_file(config: Config, random_string): + temp_file = tempfile.NamedTemporaryFile(dir=config.workspace_path, suffix=".py") + temp_file.write(str.encode(f"print('Hello {random_string}!')")) + temp_file.flush() + + yield temp_file.name + temp_file.close() + + +@pytest.fixture +def random_string(): + return "".join(random.choice(string.ascii_lowercase) for _ in range(10)) + + +def test_execute_python_file(python_test_file: str, random_string: str): + result = sut.execute_python_file(python_test_file) + assert result == f"Hello {random_string}!\n" + + +def test_execute_python_file_invalid(): + assert all( + s in sut.execute_python_file("not_python").lower() + for s in ["error:", "invalid", ".py"] + ) + assert all( + s in sut.execute_python_file("notexist.py").lower() + for s in ["error:", "does not exist"] + ) + + +def test_execute_shell(config_allow_execute, random_string): + result = sut.execute_shell(f"echo 'Hello {random_string}!'") + assert f"Hello {random_string}!" in result