# ========= 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 from collections.abc import AsyncIterator from mirage.commands import COMMANDS as _CMDS from mirage.resource.ram import RAMResource from mirage.types import MountMode, PathSpec from mirage.workspace import Workspace ram_cat = _CMDS["cat"] def _cat_ops(): return ram_cat.__wrapped__.args[0] def _spying_stream(real_stream, pulled: list[str]): def factory(accessor, p: PathSpec, index=None) -> AsyncIterator[bytes]: return _spy_iter(real_stream(accessor, p, index), p.virtual, pulled) return factory async def _spy_iter(source: AsyncIterator[bytes], name: str, pulled: list[str]) -> AsyncIterator[bytes]: first = True async for chunk in source: if first: pulled.append(name) first = False yield chunk def _seeded_ws() -> Workspace: ws = Workspace({"/data": RAMResource()}, mode=MountMode.WRITE) async def seed(): await ws.execute("tee /data/a.txt > /dev/null", stdin=b"a1\na2\na3\n") await ws.execute("tee /data/b.txt > /dev/null", stdin=b"b1\nb2\n") asyncio.run(seed()) return ws def _spy_cat_reads(ws, command, pulled): ops = _cat_ops() real = ops.read_stream object.__setattr__(ops, "read_stream", _spying_stream(real, pulled)) try: return asyncio.run(_run_and_collect(ws, command)) finally: object.__setattr__(ops, "read_stream", real) async def _run_and_collect(ws, command): result = await ws.execute(command) out = await result.stdout_str() await ws.close() return out def test_multi_cat_head_skips_second_file(): ws = _seeded_ws() pulled: list[str] = [] out = _spy_cat_reads(ws, "cat /data/a.txt /data/b.txt | head -n 1", pulled) assert out == "a1\n" assert pulled == ["/data/a.txt"] def test_multi_cat_full_reads_both_files(): ws = _seeded_ws() pulled: list[str] = [] out = _spy_cat_reads(ws, "cat /data/a.txt /data/b.txt", pulled) assert out == "a1\na2\na3\nb1\nb2\n" assert pulled == ["/data/a.txt", "/data/b.txt"]