chore: import upstream snapshot with attribution
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

This commit is contained in:
wehub-resource-sync
2026-07-13 12:30:44 +08:00
commit bcbd1bdb22
5748 changed files with 562488 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
+113
View File
@@ -0,0 +1,113 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import boto3
import pytest
from moto import mock_aws
from mirage.resource.disk import DiskResource
from mirage.resource.ram import RAMResource
from mirage.resource.s3.s3 import S3Config, S3Resource
from mirage.types import MountMode
from mirage.workspace.mount import MountRegistry
def _ram_write(p: RAMResource, path: str, data: bytes) -> None:
"""Write file to RAMResource store directly (sync, for test setup)."""
key = "/" + path.strip("/")
parts = key.strip("/").split("/")
for i in range(len(parts) - 1):
p._store.dirs.add("/" + "/".join(parts[:i + 1]))
p._store.files[key] = data
@pytest.fixture
def ram_resource():
"""A RAMResource with test data."""
p = RAMResource()
_ram_write(p, "/hello.txt", b"hello world\n")
_ram_write(p, "/nums.txt", b"3\n1\n2\n")
_ram_write(p, "/sub/nested.txt", b"nested\n")
return p
@pytest.fixture
def empty_resource():
"""An empty RAMResource."""
return RAMResource()
@pytest.fixture
def disk_resource(tmp_path):
"""A DiskResource backed by a temporary directory."""
data_dir = tmp_path / "disk_data"
data_dir.mkdir()
(data_dir / "readme.txt").write_bytes(b"disk file\n")
sub = data_dir / "sub"
sub.mkdir()
(sub / "deep.txt").write_bytes(b"deep content\n")
return DiskResource(root=str(data_dir))
@pytest.fixture
def s3_resource():
"""An S3Resource backed by moto mock."""
with mock_aws():
conn = boto3.client("s3", region_name="us-east-1")
conn.create_bucket(Bucket="test-bucket")
conn.put_object(Bucket="test-bucket",
Key="data/report.csv",
Body=b"col1,col2\n1,2\n")
conn.put_object(Bucket="test-bucket",
Key="data/summary.txt",
Body=b"summary\n")
config = S3Config(
bucket="test-bucket",
region="us-east-1",
endpoint_url=None,
)
yield S3Resource(config)
@pytest.fixture
def registry(ram_resource):
"""MountRegistry with /data/ mounted to RAMResource."""
reg = MountRegistry()
reg.mount("/data/", ram_resource, MountMode.WRITE)
return reg
@pytest.fixture
def multi_registry(s3_resource, disk_resource, ram_resource):
"""MountRegistry with S3, disk, and RAM mounts."""
reg = MountRegistry()
reg.mount("/s3/", s3_resource, MountMode.READ)
reg.mount("/disk/", disk_resource, MountMode.WRITE)
reg.mount("/ram/", ram_resource, MountMode.WRITE)
return reg
@pytest.fixture
def nested_registry():
"""MountRegistry with nested prefixes."""
p1 = RAMResource()
p1._store.files["/file.txt"] = b"outer\n"
p2 = RAMResource()
p2._store.files["/deep.txt"] = b"inner\n"
reg = MountRegistry()
reg.mount("/data/", p1, MountMode.WRITE)
reg.mount("/data/sub/", p2, MountMode.WRITE)
return reg
+199
View File
@@ -0,0 +1,199 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import asyncio
import pytest
from mirage.resource.ram import RAMResource
from mirage.types import MountMode, PathSpec
from mirage.workspace.mount import MountRegistry
from mirage.workspace.mount.mount import MountEntry
def _run(coro):
return asyncio.run(coro)
# ── prefix validation ──────────────────────────
def test_mount_accepts_root_prefix():
m = MountEntry("/", RAMResource())
assert m.prefix == "/"
def test_mount_rejects_no_leading_slash():
with pytest.raises(ValueError, match="must start with /"):
MountEntry("data/", RAMResource())
def test_mount_rejects_no_trailing_slash():
with pytest.raises(ValueError, match="must end with /"):
MountEntry("/data", RAMResource())
def test_mount_rejects_double_slash():
with pytest.raises(ValueError, match="must not contain //"):
MountEntry("/data//sub/", RAMResource())
def test_mount_valid_prefix():
m = MountEntry("/data/", RAMResource())
assert m.prefix == "/data/"
# ── read-only enforcement ──────────────────────
def test_read_only_blocks_write_ops():
reg = MountRegistry()
reg.mount("/ro/", RAMResource(), MountMode.READ)
mount = reg.mount_for("/ro/file.txt")
with pytest.raises(PermissionError, match="read-only"):
_run(mount.execute_op("write", "/file.txt", data=b"x"))
def test_write_mode_allows_write_ops():
reg = MountRegistry()
reg.mount("/rw/", RAMResource(), MountMode.WRITE)
mount = reg.mount_for("/rw/file.txt")
_run(mount.execute_op("write", "/new.txt", data=b"hello"))
def test_read_only_blocks_write_cmd():
reg = MountRegistry()
reg.mount("/ro/", RAMResource(), MountMode.READ)
mount = reg.mount_for("/ro/file.txt")
scope = PathSpec(resource_path="ro/newdir",
virtual="/ro/newdir",
directory="/ro/",
resolved=True)
stdout, io = _run(mount.execute_cmd("mkdir", [scope], [], {}))
assert io.exit_code != 0
assert b"read-only" in io.stderr
def test_write_mode_allows_write_cmd():
reg = MountRegistry()
reg.mount("/rw/", RAMResource(), MountMode.WRITE)
mount = reg.mount_for("/rw/file.txt")
scope = PathSpec(resource_path="rw/newdir",
virtual="/rw/newdir",
directory="/rw/",
resolved=True)
stdout, io = _run(mount.execute_cmd("mkdir", [scope], [], {}))
assert io.exit_code == 0
def test_read_only_allows_read_cmd():
reg = MountRegistry()
reg.mount("/ro/", RAMResource(), MountMode.READ)
mount = reg.mount_for("/ro/")
scope = PathSpec(resource_path="ro",
virtual="/ro/",
directory="/ro/",
resolved=False)
stdout, io = _run(mount.execute_cmd("ls", [scope], [], {}))
assert io.exit_code == 0
# ── execute_cmd ────────────────────────────────
def test_execute_cmd_cat(registry):
mount = registry.mount_for("/data/hello.txt")
scope = PathSpec(resource_path="data/hello.txt",
virtual="/data/hello.txt",
directory="/data/",
resolved=True)
stdout, io = _run(mount.execute_cmd("cat", [scope], [], {}))
assert io.exit_code == 0
assert stdout is not None
def test_execute_cmd_not_found(registry):
mount = registry.mount_for("/data/hello.txt")
stdout, io = _run(mount.execute_cmd("nonexistent_cmd", [], [], {}))
assert io.exit_code == 127
assert b"command not found" in io.stderr
def test_execute_cmd_ls(registry):
mount = registry.mount_for("/data/hello.txt")
scope = PathSpec(resource_path="data",
virtual="/data/",
directory="/data/",
resolved=False)
stdout, io = _run(mount.execute_cmd("ls", [scope], [], {}))
assert io.exit_code == 0
def test_execute_cmd_with_flag_kwargs(registry):
mount = registry.mount_for("/data/hello.txt")
scope = PathSpec(resource_path="data/hello.txt",
virtual="/data/hello.txt",
directory="/data/",
resolved=True)
stdout, io = _run(mount.execute_cmd("cat", [scope], [], {"n": True}))
assert io.exit_code == 0
def test_execute_cmd_with_texts(registry):
mount = registry.mount_for("/data/hello.txt")
scope = PathSpec(resource_path="data/hello.txt",
virtual="/data/hello.txt",
directory="/data/",
resolved=True)
stdout, io = _run(mount.execute_cmd("grep", [scope], ["hello"], {}))
assert io.exit_code == 0
# ── execute_op ─────────────────────────────────
def test_execute_op_stat(registry):
mount = registry.mount_for("/data/hello.txt")
result = _run(mount.execute_op("stat", "/hello.txt"))
assert result is not None
assert result.size > 0
def test_execute_op_readdir(registry):
mount = registry.mount_for("/data/")
result = _run(mount.execute_op("readdir", "/"))
assert isinstance(result, list)
assert len(result) > 0
def test_execute_op_no_such_op(registry):
mount = registry.mount_for("/data/hello.txt")
with pytest.raises(AttributeError, match="no op"):
_run(mount.execute_op("nonexistent_op", "/file.txt"))
# ── command resolution ─────────────────────────
def test_resolve_command_exists(registry):
mount = registry.mount_for("/data/hello.txt")
cmd = mount.resolve_command("cat")
assert cmd is not None
assert cmd.name == "cat"
def test_resolve_command_missing(registry):
mount = registry.mount_for("/data/hello.txt")
cmd = mount.resolve_command("nonexistent")
assert cmd is None
@@ -0,0 +1,119 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import pytest
from mirage.workspace.mount.namespace import Namespace
@pytest.fixture
def namespace(registry):
return Namespace(registry)
def test_resolve_delegates_to_registry(namespace, registry):
assert namespace.resolve("/data/hello.txt") == registry.resolve(
"/data/hello.txt")
def test_resolve_follow_noop_without_links(namespace):
assert namespace.resolve(
"/data/hello.txt", follow=True) == namespace.resolve("/data/hello.txt",
follow=False)
def test_resolve_unknown_path_raises(namespace):
with pytest.raises(ValueError, match="no mount"):
namespace.resolve("/unknown/x.txt")
def test_mount_for_delegates_to_registry(namespace, registry):
assert namespace.mount_for("/data/hello.txt") is registry.mount_for(
"/data/hello.txt")
def test_symlink_readlink_roundtrip_verbatim(namespace):
namespace.symlink("/data/link", "/data/hello.txt", 1.0)
assert namespace.is_link("/data/link")
assert namespace.readlink("/data/link") == "/data/hello.txt"
def test_readlink_missing_returns_none(namespace):
assert namespace.readlink("/data/nope") is None
def test_symlink_stores_relative_target_verbatim(namespace):
namespace.symlink("/data/link", "hello.txt", 1.0)
assert namespace.readlink("/data/link") == "hello.txt"
def test_unlink_removes_link(namespace):
namespace.symlink("/data/link", "/data/hello.txt", 1.0)
assert namespace.unlink("/data/link") is True
assert namespace.is_link("/data/link") is False
assert namespace.unlink("/data/link") is False
def test_rename_moves_link(namespace):
namespace.symlink("/data/a", "/data/hello.txt", 1.0)
assert namespace.rename("/data/a", "/data/b") is True
assert namespace.is_link("/data/a") is False
assert namespace.readlink("/data/b") == "/data/hello.txt"
def test_resolve_follows_link_to_target_mount(namespace):
namespace.symlink("/data/link", "/data/hello.txt", 1.0)
assert namespace.resolve(
"/data/link", follow=True) == namespace.resolve("/data/hello.txt")
def test_resolve_no_follow_keeps_link_path(namespace, registry):
namespace.symlink("/data/link", "/data/hello.txt", 1.0)
assert namespace.resolve("/data/link",
follow=False) == registry.resolve("/data/link")
def test_resolve_cycle_raises(namespace):
from mirage.utils.path import CycleError
namespace.symlink("/data/a", "/data/b", 1.0)
namespace.symlink("/data/b", "/data/a", 1.0)
with pytest.raises(CycleError):
namespace.resolve("/data/a", follow=True)
def test_follow_resolves_prefix_links(namespace):
namespace.symlink("/data/link", "/data/real", 1.0)
assert namespace.follow("/data/link/f.txt") == "/data/real/f.txt"
assert namespace.follow("/data/other") == "/data/other"
def test_follow_identity_without_links(namespace):
assert namespace.follow("/data/x") == "/data/x"
def test_links_under_returns_direct_children_only(namespace):
namespace.symlink("/data/a", "/t1", 1.0)
namespace.symlink("/data/sub/b", "/t2", 1.0)
namespace.symlink("/other/c", "/t3", 1.0)
assert namespace.links_under("/data") == {"a": "/t1"}
assert namespace.links_under("/data/sub") == {"b": "/t2"}
def test_purge_under_drops_nested_entries(namespace):
namespace.symlink("/data/sub/a", "/t1", 1.0)
namespace.symlink("/data/sub/deep/b", "/t2", 1.0)
namespace.symlink("/data/keep", "/t3", 1.0)
assert namespace.purge_under("/data/sub") == 2
assert namespace.is_link("/data/keep") is True
assert namespace.is_link("/data/sub/a") is False
@@ -0,0 +1,89 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import pytest
from mirage import MountMode, Workspace
from mirage.commands.builtin.utils.safeguard import SafeguardExceededError
from mirage.resource.ram import RAMResource
from mirage.types import CommandSafeguard, OnExceed
async def _read_long(accessor, scope, *args, **kwargs):
return b"hello world"
async def _read_lines(accessor, scope, *args, **kwargs):
return b"a\nb\nc\nd\n"
async def _read_short(accessor, scope, *args, **kwargs):
return b"hi"
async def _ws_mount():
ws = Workspace({"/data": RAMResource()}, mode=MountMode.WRITE)
await ws.execute("echo hi > /data/f.txt")
mount = next(m for m in ws._registry._mounts if m.prefix == "/data/")
return mount
@pytest.mark.asyncio
async def test_vfs_read_truncates_to_max_bytes(monkeypatch):
mount = await _ws_mount()
mount.command_safeguards["read"] = CommandSafeguard(max_bytes=5)
monkeypatch.setattr(mount._ops[("read", None)], "fn", _read_long)
assert await mount.execute_op("read", "/data/f.txt") == b"hello"
@pytest.mark.asyncio
async def test_vfs_read_truncates_to_max_lines(monkeypatch):
mount = await _ws_mount()
mount.command_safeguards["read"] = CommandSafeguard(max_lines=2)
monkeypatch.setattr(mount._ops[("read", None)], "fn", _read_lines)
assert await mount.execute_op("read", "/data/f.txt") == b"a\nb\n"
@pytest.mark.asyncio
async def test_vfs_read_on_exceed_error_raises(monkeypatch):
mount = await _ws_mount()
mount.command_safeguards["read"] = CommandSafeguard(
max_bytes=5, on_exceed=OnExceed.ERROR)
monkeypatch.setattr(mount._ops[("read", None)], "fn", _read_long)
with pytest.raises(SafeguardExceededError):
await mount.execute_op("read", "/data/f.txt")
@pytest.mark.asyncio
async def test_vfs_read_within_limit_untouched(monkeypatch):
mount = await _ws_mount()
mount.command_safeguards["read"] = CommandSafeguard(max_bytes=100)
monkeypatch.setattr(mount._ops[("read", None)], "fn", _read_short)
assert await mount.execute_op("read", "/data/f.txt") == b"hi"
@pytest.mark.asyncio
async def test_vfs_unconfigured_read_untouched(monkeypatch):
mount = await _ws_mount()
monkeypatch.setattr(mount._ops[("read", None)], "fn", _read_long)
assert await mount.execute_op("read", "/data/f.txt") == b"hello world"
@pytest.mark.asyncio
async def test_vfs_stat_not_capped_by_byte_limit(monkeypatch):
mount = await _ws_mount()
mount.command_safeguards["stat"] = CommandSafeguard(max_bytes=1)
result = await mount.execute_op("stat", "/data/f.txt")
assert result is not None
assert not isinstance(result, (bytes, bytearray))
@@ -0,0 +1,56 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import asyncio
import pytest
from mirage import MountMode, Workspace
from mirage.commands.builtin.utils.safeguard import CommandTimeoutError
from mirage.resource.ram import RAMResource
from mirage.types import CommandSafeguard
async def _slow_op(accessor, scope, *args, **kwargs):
await asyncio.sleep(5)
return None
async def _slowish_op(accessor, scope, *args, **kwargs):
await asyncio.sleep(0.2)
return "ok"
async def _ws_mount():
ws = Workspace({"/data": RAMResource()}, mode=MountMode.WRITE)
await ws.execute("echo hi > /data/f.txt")
mount = next(m for m in ws._registry._mounts if m.prefix == "/data/")
return mount
@pytest.mark.asyncio
async def test_vfs_op_honors_per_mount_timeout(monkeypatch):
mount = await _ws_mount()
mount.command_safeguards["stat"] = CommandSafeguard(timeout_seconds=0.05)
monkeypatch.setattr(mount._ops[("stat", None)], "fn", _slow_op)
with pytest.raises(CommandTimeoutError):
await mount.execute_op("stat", "/data/f.txt")
@pytest.mark.asyncio
async def test_vfs_op_unconfigured_is_not_timed(monkeypatch):
mount = await _ws_mount()
monkeypatch.setattr(mount._ops[("stat", None)], "fn", _slowish_op)
result = await mount.execute_op("stat", "/data/f.txt")
assert result == "ok"
@@ -0,0 +1,389 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import pytest
from mirage.cache.file.ram import RAMFileCacheStore
from mirage.commands.registry import command
from mirage.commands.spec.types import CommandSpec
from mirage.io.types import IOResult
from mirage.resource.base import BaseResource
from mirage.resource.ram import RAMResource
from mirage.resource.ssh import SSHConfig, SSHResource
from mirage.types import MountMode, PathSpec
from mirage.workspace.mount import MountCommandUnsupported, MountRegistry
# ── mount_for ──────────────────────────────────
def test_mount_for_exact(registry):
mount = registry.mount_for("/data/file.txt")
assert mount.prefix == "/data/"
def test_mount_for_nested_path(registry):
mount = registry.mount_for("/data/sub/deep/file.txt")
assert mount.prefix == "/data/"
def test_mount_for_prefix_root(registry):
mount = registry.mount_for("/data")
assert mount.prefix == "/data/"
def test_mount_for_no_match(registry):
with pytest.raises(ValueError, match="no mount"):
registry.mount_for("/unknown/file.txt")
def test_mount_for_dev_default(registry):
mount = registry.mount_for("/dev/null")
assert mount.prefix == "/dev/"
# ── longest prefix match ──────────────────────
def test_nested_prefix_longest_match(nested_registry):
mount = nested_registry.mount_for("/data/sub/deep.txt")
assert mount.prefix == "/data/sub/"
def test_nested_prefix_outer(nested_registry):
mount = nested_registry.mount_for("/data/file.txt")
assert mount.prefix == "/data/"
# ── descendant_mounts ──────────────────────────
def test_descendant_mounts_under_root(multi_registry):
descs = multi_registry.descendant_mounts("/")
prefixes = [m.prefix for m in descs]
# /dev/ is auto-mounted by the registry; ours are /s3/, /disk/, /ram/.
assert "/disk/" in prefixes
assert "/ram/" in prefixes
assert "/s3/" in prefixes
def test_descendant_mounts_under_root_sorted(multi_registry):
descs = multi_registry.descendant_mounts("/")
prefixes = [m.prefix for m in descs]
assert prefixes == sorted(prefixes)
def test_descendant_mounts_at_a_mount_root_is_empty(registry):
# /data/ is a mount; nothing is below it.
assert registry.descendant_mounts("/data") == []
assert registry.descendant_mounts("/data/") == []
def test_descendant_mounts_inside_a_mount_is_empty(registry):
assert registry.descendant_mounts("/data/sub") == []
def test_descendant_mounts_nested(nested_registry):
# Top: /data/, /data/sub/.
descs = nested_registry.descendant_mounts("/")
prefixes = [m.prefix for m in descs]
assert "/data/" in prefixes
assert "/data/sub/" in prefixes
# Below /data/, the only descendant is /data/sub/.
descs2 = nested_registry.descendant_mounts("/data")
assert [m.prefix for m in descs2] == ["/data/sub/"]
# /data/ as a mount root returns its own children only (excludes self).
assert "/data/" not in [m.prefix for m in descs2]
def test_descendant_mounts_excludes_self(nested_registry):
descs = nested_registry.descendant_mounts("/data")
assert all(m.prefix != "/data/" for m in descs)
def test_descendant_mounts_unrelated_path(multi_registry):
# A path in /s3/ has no mount nested below it.
assert multi_registry.descendant_mounts("/s3/data") == []
# ── resolve ────────────────────────────────────
def test_resolve_strips_prefix(registry):
prov, pp, mode = registry.resolve("/data/hello.txt")
assert pp == "/hello.txt"
assert prov.name == "ram"
def test_resolve_root_path(registry):
_, pp, _ = registry.resolve("/data")
assert pp == "/"
def test_resolve_trailing_slash(registry):
_, pp, _ = registry.resolve("/data/sub/")
assert pp.endswith("/")
def test_resolve_mode(registry):
_, _, mode = registry.resolve("/data/file.txt")
assert mode == MountMode.WRITE
def test_resolve_no_match(registry):
with pytest.raises(ValueError):
registry.resolve("/unknown/path")
# ── multi mount (s3 + disk + ram) ──────────────
def test_multi_mount_resolves_s3(multi_registry):
mount = multi_registry.mount_for("/s3/data/report.csv")
assert mount.prefix == "/s3/"
assert mount.resource.name == "s3"
def test_multi_mount_resolves_disk(multi_registry):
mount = multi_registry.mount_for("/disk/readme.txt")
assert mount.prefix == "/disk/"
assert mount.resource.name == "disk"
def test_multi_mount_resolves_ram(multi_registry):
mount = multi_registry.mount_for("/ram/hello.txt")
assert mount.prefix == "/ram/"
assert mount.resource.name == "ram"
def test_multi_mount_modes(multi_registry):
_, _, s3_mode = multi_registry.resolve("/s3/file.txt")
_, _, disk_mode = multi_registry.resolve("/disk/file.txt")
_, _, ram_mode = multi_registry.resolve("/ram/file.txt")
assert s3_mode == MountMode.READ
assert disk_mode == MountMode.WRITE
assert ram_mode == MountMode.WRITE
def test_multi_mount_resource_paths(multi_registry):
_, pp_s3, _ = multi_registry.resolve("/s3/data/report.csv")
_, pp_disk, _ = multi_registry.resolve("/disk/readme.txt")
_, pp_ram, _ = multi_registry.resolve("/ram/hello.txt")
assert pp_s3 == "/data/report.csv"
assert pp_disk == "/readme.txt"
assert pp_ram == "/hello.txt"
# ── mount ──────────────────────────────────────
def test_mount_returns_mount_object():
reg = MountRegistry()
p = RAMResource()
m = reg.mount("/test/", p, MountMode.READ)
assert m.prefix == "/test/"
assert m.resource is p
def test_mount_normalizes_prefix():
reg = MountRegistry()
m = reg.mount("/test/", RAMResource(), MountMode.READ)
assert m.prefix == "/test/"
def test_mount_duplicate_raises(registry):
with pytest.raises(ValueError, match="duplicate"):
registry.mount("/data/", RAMResource())
# ── mounts listing ─────────────────────────────
def test_mounts_returns_all(multi_registry):
prefixes = {m.prefix for m in multi_registry.mounts()}
assert "/s3/" in prefixes
assert "/disk/" in prefixes
assert "/ram/" in prefixes
assert "/dev/" in prefixes
def test_mounts_count(multi_registry):
assert len(multi_registry.mounts()) == 4
# ── group_by_mount ─────────────────────────────
def test_group_by_mount(multi_registry):
groups = multi_registry.group_by_mount(
["/s3/a.txt", "/s3/b.txt", "/disk/c.txt"])
assert len(groups) == 2
s3_group = [g for g in groups if g[0].prefix == "/s3/"][0]
assert len(s3_group[1]) == 2
disk_group = [g for g in groups if g[0].prefix == "/disk/"][0]
assert len(disk_group[1]) == 1
def test_group_by_mount_single(multi_registry):
groups = multi_registry.group_by_mount(["/ram/hello.txt"])
assert len(groups) == 1
# ── get_resource_type ──────────────────────────
def test_get_resource_type_s3(multi_registry):
assert multi_registry.get_resource_type("/s3/file.txt") == "s3"
def test_get_resource_type_disk(multi_registry):
assert multi_registry.get_resource_type("/disk/file.txt") == "disk"
def test_get_resource_type_ram(multi_registry):
assert multi_registry.get_resource_type("/ram/file.txt") == "ram"
def test_get_resource_type_none(multi_registry):
assert multi_registry.get_resource_type(None) is None
def test_get_resource_type_unknown(multi_registry):
assert multi_registry.get_resource_type("/unknown/f") is None
# ── find_resource_by_name ──────────────────────
def test_find_resource_s3(multi_registry):
prov = multi_registry.find_resource_by_name("s3")
assert prov is not None
assert prov.name == "s3"
def test_find_resource_disk(multi_registry):
prov = multi_registry.find_resource_by_name("disk")
assert prov is not None
assert prov.name == "disk"
def test_find_resource_ram(multi_registry):
prov = multi_registry.find_resource_by_name("ram")
assert prov is not None
def test_find_resource_none(multi_registry):
assert multi_registry.find_resource_by_name(None) is None
def test_find_resource_missing(multi_registry):
assert multi_registry.find_resource_by_name("nonexistent") is None
# ── mount_for_command ──────────────────────────
def test_mount_for_command_cat(registry):
mount = registry.mount_for_command("cat")
assert mount is not None
def test_mount_for_command_nonexistent(registry):
assert registry.mount_for_command("nonexistent_cmd") is None
def test_mount_for_command_grep(multi_registry):
mount = multi_registry.mount_for_command("grep")
assert mount is not None
# ── resolve_mount cache redirect ───────────────
def _remote_registry_with_cache():
reg = MountRegistry()
reg.mount("/ssh/", SSHResource(SSHConfig(host="example", root="/srv")),
MountMode.WRITE)
cache = RAMFileCacheStore()
reg.attach_file_cache(cache)
return reg, cache
@pytest.mark.asyncio
async def test_resolve_mount_keeps_cached_read_on_real_mount():
# Warm reads are served in place by with_read_cache, so a cached
# read-only command stays on its real mount (keeping its safeguards and
# custom handlers) instead of being redirected to the cache mount.
reg, cache = _remote_registry_with_cache()
await cache.set("/ssh/a.txt", b"hi")
scope = PathSpec(resource_path="ssh/a.txt",
virtual="/ssh/a.txt",
directory="/ssh",
resolved=True)
mount = await reg.resolve_mount("cat", [scope], "/ssh")
assert mount.prefix == "/ssh/"
@pytest.mark.asyncio
async def test_resolve_mount_keeps_cached_write_on_remote():
reg, cache = _remote_registry_with_cache()
await cache.set("/ssh/a.txt", b"hi")
scope = PathSpec(resource_path="ssh/a.txt",
virtual="/ssh/a.txt",
directory="/ssh",
resolved=True)
mount = await reg.resolve_mount("rm", [scope], "/ssh")
assert mount.prefix == "/ssh/"
class _LimitedResource(BaseResource):
name = "limited"
class _FallbackResource(BaseResource):
name = "fallback"
@command("fallback-only", resource="fallback", spec=CommandSpec())
async def _fallback_only(_store, paths, *texts, **kw):
return b"fallback", IOResult()
def _path_bound_registry_with_default():
reg = MountRegistry()
reg.mount("/limited/", _LimitedResource(), MountMode.WRITE)
fallback = _FallbackResource()
fallback.register(_fallback_only)
reg.mount("/", fallback, MountMode.WRITE)
return reg
@pytest.mark.asyncio
async def test_resolve_mount_rejects_path_bound_unsupported_command():
reg = _path_bound_registry_with_default()
scope = PathSpec(resource_path="limited/file.txt",
virtual="/limited/file.txt",
directory="/limited",
resolved=True)
with pytest.raises(
MountCommandUnsupported,
match="fallback-only: /limited/file.txt: Operation not supported"):
await reg.resolve_mount("fallback-only", [scope], "/limited")
@pytest.mark.asyncio
async def test_resolve_mount_allows_default_without_path_binding():
reg = _path_bound_registry_with_default()
mount = await reg.resolve_mount("fallback-only", [], "/limited")
assert mount is not None
assert mount.prefix == "/"
@@ -0,0 +1,39 @@
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
from mirage.resource.ssh import SSHConfig, SSHResource
from mirage.types import MountMode
from mirage.workspace.mount.registry import MountRegistry
def test_ssh_mount_registration():
registry = MountRegistry()
cfg = SSHConfig(host="dev", root="/home/ubuntu")
resource = SSHResource(cfg)
registry.mount("/ssh/", resource, mode=MountMode.WRITE)
mount = registry.mount_for("/ssh/some/file.txt")
assert mount is not None
assert mount.resource.name == "ssh"
def test_ssh_mount_command_resolution():
registry = MountRegistry()
cfg = SSHConfig(host="dev")
resource = SSHResource(cfg)
registry.mount("/remote/", resource, mode=MountMode.WRITE)
mount = registry.mount_for("/remote/test.py")
assert mount is not None
cmd = mount.resolve_command("cat", None)
assert cmd is not None
assert cmd.resource == "ssh"