# ========= 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, PathSpec from mirage.utils.key_prefix import mount_key from mirage.workspace import Workspace class _FakeRemote(RAMResource): caches_reads = True index_ttl = 600 def _seed_remote() -> _FakeRemote: remote = _FakeRemote() remote._store.dirs.add("/data") remote._store.files["/data/a.txt"] = b"a" return remote def test_dispatch_write_invalidates_parent_dir_index(): remote = _seed_remote() ws = Workspace({"/r": (remote, MountMode.WRITE)}, mode=MountMode.WRITE) async def run(): before = await ws.readdir("/r/data") scope = PathSpec( resource_path=mount_key("/r/data/b.txt", "/r"), virtual="/r/data/b.txt", directory="/r/data", resolved=True, ) await ws.dispatch("write", scope, data=b"b") after = await ws.readdir("/r/data") return before, after before, after = asyncio.run(run()) assert "/r/data/a.txt" in before assert "/r/data/b.txt" in after, ( "after dispatch write, readdir should reflect b.txt; " f"got {after!r}") def test_dispatch_unlink_invalidates_parent_dir_index(): remote = _seed_remote() remote._store.files["/data/c.txt"] = b"c" ws = Workspace({"/r": (remote, MountMode.WRITE)}, mode=MountMode.WRITE) async def run(): before = await ws.readdir("/r/data") scope = PathSpec( resource_path=mount_key("/r/data/c.txt", "/r"), virtual="/r/data/c.txt", directory="/r/data", resolved=True, ) await ws.dispatch("unlink", scope) after = await ws.readdir("/r/data") return before, after before, after = asyncio.run(run()) assert "/r/data/c.txt" in before assert "/r/data/c.txt" not in after, ( "after dispatch unlink, readdir should drop c.txt; " f"got {after!r}")