43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
import pytest
|
|
|
|
from duck_core.tools.file_read import FileReadTool
|
|
from duck_core.tools.file_write import FileWriteTool
|
|
from duck_core.tools.gateway import ToolGateway
|
|
from duck_core.tools.shell_exec_safe import ShellExecSafeTool
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_file_tools_stay_inside_workspace(tmp_path):
|
|
write = FileWriteTool(str(tmp_path))
|
|
read = FileReadTool(str(tmp_path))
|
|
|
|
result = await write.run({"path": "tmp/note.txt", "content": "hello duck"})
|
|
loaded = await read.run({"path": "tmp/note.txt"})
|
|
escaped = await read.run({"path": "../outside.txt"})
|
|
|
|
assert result.ok is True
|
|
assert loaded.output == "hello duck"
|
|
assert escaped.ok is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shell_tool_blocks_dangerous_commands(tmp_path):
|
|
shell = ShellExecSafeTool(str(tmp_path))
|
|
|
|
allowed = await shell.run({"command": "pwd"})
|
|
blocked = await shell.run({"command": "rm -rf ."})
|
|
|
|
assert allowed.ok is True
|
|
assert blocked.ok is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_tool_gateway_runs_allowed_directive(tmp_path):
|
|
gateway = ToolGateway.default(str(tmp_path))
|
|
result = await gateway.run_action(
|
|
{"tool": "file_write", "args": {"path": "a.txt", "content": "x"}}
|
|
)
|
|
|
|
assert result.ok is True
|
|
assert result.metadata["path"].endswith("a.txt")
|