# ========= 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 mirage.resource.ram import RAMResource from mirage.types import MountMode from mirage.workspace import Workspace def _make_ws(): src = RAMResource() dst = RAMResource() src._store.dirs.update({"/dir", "/dir/sub", "/dir/empty"}) src._store.files["/dir/a.txt"] = b"aaa\n" src._store.files["/dir/sub/b.txt"] = b"bbb\n" ws = Workspace( { "/a": (src, MountMode.WRITE), "/b": (dst, MountMode.WRITE), }, ) return ws, src, dst def _run(ws, cmd): async def _inner(): io = await ws.execute(cmd) return await io.stdout_str(), await io.stderr_str(), io.exit_code return asyncio.run(_inner()) def test_cp_recursive_copies_tree(): ws, _src, dst = _make_ws() _out, _err, code = _run(ws, "cp -r /a/dir /b/copied") assert code == 0 assert dst._store.files["/copied/a.txt"] == b"aaa\n" assert dst._store.files["/copied/sub/b.txt"] == b"bbb\n" assert "/copied/sub" in dst._store.dirs assert "/copied/empty" in dst._store.dirs def test_cp_recursive_into_existing_dir(): ws, _src, dst = _make_ws() dst._store.dirs.add("/into") _out, _err, code = _run(ws, "cp -r /a/dir /b/into") assert code == 0 assert dst._store.files["/into/dir/a.txt"] == b"aaa\n" assert dst._store.files["/into/dir/sub/b.txt"] == b"bbb\n" def test_cp_directory_without_recursive_fails(): ws, _src, dst = _make_ws() _out, err, code = _run(ws, "cp /a/dir /b/copied") assert code == 1 assert "omitting directory" in err assert "/copied" not in dst._store.dirs assert not any(k.startswith("/copied") for k in dst._store.files) def test_mv_recursive_moves_tree_and_removes_source(): ws, src, dst = _make_ws() _out, _err, code = _run(ws, "mv /a/dir /b/moved") assert code == 0 assert dst._store.files["/moved/a.txt"] == b"aaa\n" assert dst._store.files["/moved/sub/b.txt"] == b"bbb\n" assert "/dir" not in src._store.dirs assert "/dir/a.txt" not in src._store.files assert "/dir/sub/b.txt" not in src._store.files def test_cp_recursive_no_clobber_skips_existing(): # /b/into exists, so `cp -r /a/dir /b/into` maps to /b/into/dir. Pre-seed # that mapped tree with an existing a.txt so -n must skip it. ws, _src, dst = _make_ws() dst._store.dirs.update({"/into", "/into/dir"}) dst._store.files["/into/dir/a.txt"] = b"keep\n" _out, _err, code = _run(ws, "cp -rn /a/dir /b/into") assert code == 0 assert dst._store.files["/into/dir/a.txt"] == b"keep\n" assert dst._store.files["/into/dir/sub/b.txt"] == b"bbb\n"