Files
wehub-resource-sync bcbd1bdb22
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:44 +08:00

168 lines
5.0 KiB
Python

import pytest
pytest.importorskip("claude_agent_sdk")
from mirage import MountMode, RAMResource, Workspace # noqa: E402
from mirage.agents.claude_agent_sdk.server import _MirageTools # noqa: E402
@pytest.fixture
def workspace():
return Workspace({"/": RAMResource()}, mode=MountMode.WRITE)
@pytest.fixture
def tools(workspace):
return _MirageTools(workspace)
@pytest.mark.asyncio
async def test_execute_command_echo(tools):
result = await tools.execute_command({"command": "echo hello"})
assert "hello" in result["content"][0]["text"]
assert result.get("is_error") is not True
@pytest.mark.asyncio
async def test_execute_command_pipe(tools, workspace):
await workspace.ops.write("/pipe.txt", b"aaa\nbbb\naaa\n")
result = await tools.execute_command(
{"command": "cat /pipe.txt | sort | uniq | wc -l"})
assert "2" in result["content"][0]["text"]
@pytest.mark.asyncio
async def test_read_file(tools, workspace):
await workspace.ops.write("/hello.txt", b"line1\nline2\nline3\n")
result = await tools.read({"path": "/hello.txt"})
text = result["content"][0]["text"]
assert "line1" in text
assert "line2" in text
assert result.get("is_error") is not True
@pytest.mark.asyncio
async def test_read_file_with_offset_and_limit(tools, workspace):
await workspace.ops.write("/multi.txt", b"a\nb\nc\nd\ne\n")
result = await tools.read({"path": "/multi.txt", "offset": 1, "limit": 2})
text = result["content"][0]["text"]
assert "b" in text
assert "c" in text
assert "a" not in text
assert "d" not in text
@pytest.mark.asyncio
async def test_read_file_not_found(tools):
result = await tools.read({"path": "/nonexistent.txt"})
assert result["is_error"] is True
assert "not found" in result["content"][0]["text"]
@pytest.mark.asyncio
async def test_write_file(tools, workspace):
result = await tools.write({"path": "/new.txt", "content": "hello world"})
assert result.get("is_error") is not True
data = await workspace.ops.read("/new.txt")
assert data == b"hello world"
@pytest.mark.asyncio
async def test_write_file_already_exists(tools, workspace):
await workspace.ops.write("/exists.txt", b"first")
result = await tools.write({"path": "/exists.txt", "content": "second"})
assert result["is_error"] is True
assert "already exists" in result["content"][0]["text"]
@pytest.mark.asyncio
async def test_edit_file(tools, workspace):
await workspace.ops.write("/edit.txt", b"foo bar baz")
result = await tools.edit({
"path": "/edit.txt",
"old_string": "bar",
"new_string": "qux"
})
assert result.get("is_error") is not True
data = await workspace.ops.read("/edit.txt")
assert data == b"foo qux baz"
@pytest.mark.asyncio
async def test_edit_file_not_found(tools):
result = await tools.edit({
"path": "/missing.txt",
"old_string": "x",
"new_string": "y"
})
assert result["is_error"] is True
assert "not found" in result["content"][0]["text"]
@pytest.mark.asyncio
async def test_edit_string_not_found(tools, workspace):
await workspace.ops.write("/nostr.txt", b"hello world")
result = await tools.edit({
"path": "/nostr.txt",
"old_string": "xyz",
"new_string": "abc"
})
assert result["is_error"] is True
assert "not found" in result["content"][0]["text"]
@pytest.mark.asyncio
async def test_edit_multiple_occurrences_without_replace_all(tools, workspace):
await workspace.ops.write("/multi.txt", b"aa bb aa")
result = await tools.edit({
"path": "/multi.txt",
"old_string": "aa",
"new_string": "cc"
})
assert result["is_error"] is True
assert "replace_all" in result["content"][0]["text"]
@pytest.mark.asyncio
async def test_edit_replace_all(tools, workspace):
await workspace.ops.write("/all.txt", b"aa bb aa")
result = await tools.edit({
"path": "/all.txt",
"old_string": "aa",
"new_string": "cc",
"replace_all": True
})
assert result.get("is_error") is not True
data = await workspace.ops.read("/all.txt")
assert data == b"cc bb cc"
@pytest.mark.asyncio
async def test_write_creates_parent_dirs(tools, workspace):
result = await tools.write({
"path": "/nested/deep/file.txt",
"content": "hi"
})
assert result.get("is_error") is not True
data = await workspace.ops.read("/nested/deep/file.txt")
assert data == b"hi"
@pytest.mark.asyncio
async def test_ls(tools, workspace):
await tools.write({"path": "/dir/a.txt", "content": "a"})
await tools.write({"path": "/dir/b.txt", "content": "b"})
result = await tools.ls({"path": "/dir"})
text = result["content"][0]["text"]
assert "a.txt" in text
assert "b.txt" in text
@pytest.mark.asyncio
async def test_grep(tools, workspace):
await workspace.ops.write("/search.txt",
b"hello world\ngoodbye world\nhello again\n")
result = await tools.grep({"pattern": "hello", "path": "/"})
text = result["content"][0]["text"]
assert "hello" in text