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
218 lines
5.9 KiB
Python
218 lines
5.9 KiB
Python
import pytest
|
|
|
|
from mirage.commands.builtin.generic.basename import basename
|
|
from mirage.commands.builtin.generic.dirname import dirname
|
|
from mirage.commands.builtin.generic.mktemp import mktemp
|
|
from mirage.commands.builtin.generic.readlink import readlink
|
|
from mirage.commands.builtin.generic.realpath import realpath
|
|
from mirage.types import FileStat, PathSpec
|
|
from mirage.utils.key_prefix import mount_key
|
|
|
|
|
|
def _spec(original: str, prefix: str = "") -> PathSpec:
|
|
return PathSpec(resource_path=mount_key(original, prefix),
|
|
virtual=original,
|
|
directory=original,
|
|
resolved=True)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_basename_single():
|
|
out, _ = await basename("/a/b/c.txt")
|
|
assert out == b"c.txt\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_basename_suffix():
|
|
out, _ = await basename("/a/b.txt", ".txt")
|
|
assert out == b"b\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_basename_empty():
|
|
out, _ = await basename()
|
|
assert out == b"\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_dirname_single():
|
|
out, _ = await dirname("/a/b/c.txt")
|
|
assert out == b"/a/b\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_dirname_no_slash():
|
|
out, _ = await dirname("foo")
|
|
assert out == b".\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_dirname_multiple():
|
|
out, _ = await dirname("/a/b", "/x/y/z")
|
|
assert out == b"/a\n/x/y\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_realpath_normalizes():
|
|
|
|
async def stat_fn(accessor, path):
|
|
return FileStat(name="x")
|
|
|
|
out, _ = await realpath([_spec("/a/./b/../c")], stat_fn=stat_fn)
|
|
assert out == b"/a/c\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_realpath_exists_check_passes():
|
|
|
|
async def stat_fn(accessor, path):
|
|
return FileStat(name="x")
|
|
|
|
out, _ = await realpath([_spec("/a/b")], stat_fn=stat_fn, e=True)
|
|
assert out == b"/a/b\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_realpath_exists_check_fails():
|
|
|
|
async def stat_fn(accessor, path):
|
|
raise FileNotFoundError
|
|
|
|
with pytest.raises(FileNotFoundError, match="realpath"):
|
|
await realpath([_spec("/missing")], stat_fn=stat_fn, e=True)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_realpath_multiple():
|
|
|
|
async def stat_fn(accessor, path):
|
|
return FileStat(name="x")
|
|
|
|
out, _ = await realpath([_spec("/a"), _spec("/b/../c")], stat_fn=stat_fn)
|
|
assert out == b"/a\n/c\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_readlink_simple():
|
|
out, _ = await readlink([_spec("/a/b")])
|
|
assert out == b"/a/b\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_readlink_with_prefix():
|
|
out, _ = await readlink([_spec("/mnt/b", prefix="/mnt")])
|
|
assert out == b"/mnt/b\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_readlink_normalize_with_f():
|
|
out, _ = await readlink([_spec("/a/./b")], f=True)
|
|
assert out == b"/a/b\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_readlink_no_newline():
|
|
out, _ = await readlink([_spec("/a/b")], n=True)
|
|
assert out == b"/a/b"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_readlink_missing_operand():
|
|
with pytest.raises(ValueError, match="missing operand"):
|
|
await readlink([])
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_mktemp_creates_file():
|
|
mkdir_calls: list[tuple] = []
|
|
write_calls: list[tuple] = []
|
|
|
|
async def mkdir_fn(accessor, path, parents=False):
|
|
mkdir_calls.append((path, parents))
|
|
|
|
async def write_bytes_fn(accessor, path, data):
|
|
write_calls.append((path, data))
|
|
|
|
out, _ = await mktemp(mkdir_fn=mkdir_fn,
|
|
write_bytes_fn=write_bytes_fn,
|
|
t=True)
|
|
text = out.decode()
|
|
assert text.startswith("/tmp/tmp.")
|
|
assert text.endswith("\n")
|
|
assert mkdir_calls == [("/tmp", True)]
|
|
assert len(write_calls) == 1
|
|
assert write_calls[0][1] == b""
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_mktemp_creates_directory():
|
|
mkdir_calls: list[tuple] = []
|
|
write_calls: list[tuple] = []
|
|
|
|
async def mkdir_fn(accessor, path, parents=False):
|
|
mkdir_calls.append((path, parents))
|
|
|
|
async def write_bytes_fn(accessor, path, data):
|
|
write_calls.append((path, data))
|
|
|
|
out, _ = await mktemp(mkdir_fn=mkdir_fn,
|
|
write_bytes_fn=write_bytes_fn,
|
|
d=True,
|
|
t=True)
|
|
text = out.decode().rstrip("\n")
|
|
assert mkdir_calls == [("/tmp", True), (text, False)]
|
|
assert write_calls == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_mktemp_custom_parent():
|
|
mkdir_calls: list[tuple] = []
|
|
|
|
async def mkdir_fn(accessor, path, parents=False):
|
|
mkdir_calls.append((path, parents))
|
|
|
|
async def write_bytes_fn(accessor, path, data):
|
|
pass
|
|
|
|
out, _ = await mktemp(mkdir_fn=mkdir_fn,
|
|
write_bytes_fn=write_bytes_fn,
|
|
p="/var/cache")
|
|
assert out.decode().startswith("/var/cache/tmp.")
|
|
assert mkdir_calls[0] == ("/var/cache", True)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_mktemp_pathspec_parent():
|
|
mkdir_calls: list[tuple] = []
|
|
|
|
async def mkdir_fn(accessor, path, parents=False):
|
|
mkdir_calls.append((path, parents))
|
|
|
|
async def write_bytes_fn(accessor, path, data):
|
|
pass
|
|
|
|
out, _ = await mktemp(mkdir_fn=mkdir_fn,
|
|
write_bytes_fn=write_bytes_fn,
|
|
p=_spec("/scratch"))
|
|
assert out.decode().startswith("/scratch/tmp.")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_mktemp_custom_template():
|
|
mkdir_calls: list[tuple] = []
|
|
write_calls: list[tuple] = []
|
|
|
|
async def mkdir_fn(accessor, path, parents=False):
|
|
mkdir_calls.append((path, parents))
|
|
|
|
async def write_bytes_fn(accessor, path, data):
|
|
write_calls.append((path, data))
|
|
|
|
out, _ = await mktemp("session_XXXXXX",
|
|
mkdir_fn=mkdir_fn,
|
|
write_bytes_fn=write_bytes_fn,
|
|
t=True)
|
|
text = out.decode().rstrip("\n")
|
|
assert text.startswith("/tmp/session_")
|
|
assert len(text) == len("/tmp/session_") + 6
|