Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions autoform_cli/_directory_binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,6 @@ def _open_failure(path: Path, error: OSError) -> OSError:
return OSError("directory root must not be a symbolic link")
if isinstance(error, PermissionError):
return OSError("permission denied while opening the directory root")
if isinstance(error, FileNotFoundError):
return OSError("directory root does not exist")
if isinstance(error, NotADirectoryError):
return OSError("directory root is not a directory")
return OSError("directory root cannot be opened")


Expand Down
105 changes: 27 additions & 78 deletions tests/test_tree_snapshot_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import pytest

from autoform_cli import _directory_binding as directory_binding_module
from autoform_cli import _tree_snapshot as tree_snapshot_module
from autoform_cli._tree_snapshot import (
BoundDirectoryTree,
Expand All @@ -21,6 +20,17 @@
TreeSnapshotError,
bind_directory_tree,
)
from tests.test_lean_sources import _require_descriptor_capture, _use_portable_capture


def _forbid_unbounded_listdir(monkeypatch: pytest.MonkeyPatch) -> None:
"""Disable streaming enumeration and fail if the capture falls back to `os.listdir`."""

def unexpected_listdir(*_args, **_kwargs):
raise AssertionError("unexpected unbounded os.listdir call")

monkeypatch.setattr(tree_snapshot_module, "_DESCRIPTOR_SCANDIR_SUPPORTED", False)
monkeypatch.setattr(tree_snapshot_module.os, "listdir", unexpected_listdir)


def _capture(
Expand All @@ -30,17 +40,10 @@ def _capture(
portable: bool,
monkeypatch: pytest.MonkeyPatch,
) -> TreeSnapshot:
if not portable and not (
directory_binding_module.DIRECTORY_BINDING_SUPPORTED
and tree_snapshot_module._DESCRIPTOR_CAPTURE_SUPPORTED
):
pytest.skip("directory descriptor capture is unavailable")
if portable:
monkeypatch.setattr(
directory_binding_module,
"DIRECTORY_BINDING_SUPPORTED",
False,
)
_use_portable_capture(monkeypatch)
else:
_require_descriptor_capture()
with bind_directory_tree(root, selection=selection) as bound:
return bound.capture()

Expand Down Expand Up @@ -139,16 +142,9 @@ def test_capture_and_close_are_serialized(
portable: bool,
) -> None:
if portable:
monkeypatch.setattr(
directory_binding_module,
"DIRECTORY_BINDING_SUPPORTED",
False,
)
elif not (
directory_binding_module.DIRECTORY_BINDING_SUPPORTED
and tree_snapshot_module._DESCRIPTOR_CAPTURE_SUPPORTED
):
pytest.skip("directory descriptor capture is unavailable")
_use_portable_capture(monkeypatch)
else:
_require_descriptor_capture()
root = tmp_path / "tree"
root.mkdir()
(root / "payload").write_bytes(b"payload")
Expand Down Expand Up @@ -538,20 +534,11 @@ def test_descriptor_fallback_fails_before_unbounded_listdir(
monkeypatch: pytest.MonkeyPatch,
limits: TreeCaptureLimits,
) -> None:
if not (
directory_binding_module.DIRECTORY_BINDING_SUPPORTED
and tree_snapshot_module._DESCRIPTOR_CAPTURE_SUPPORTED
):
pytest.skip("directory descriptor capture is unavailable")
_require_descriptor_capture()
root = tmp_path / "tree"
root.mkdir()
(root / "payload").write_bytes(b"payload")
monkeypatch.setattr(tree_snapshot_module, "_DESCRIPTOR_SCANDIR_SUPPORTED", False)

def unexpected_listdir(*_args, **_kwargs):
raise AssertionError("finite structural limits must not call os.listdir")

monkeypatch.setattr(tree_snapshot_module.os, "listdir", unexpected_listdir)
_forbid_unbounded_listdir(monkeypatch)

with pytest.raises(TreeSnapshotError, match="bounded directory enumeration"):
_capture(
Expand All @@ -566,21 +553,12 @@ def test_expected_child_precheck_fails_before_unbounded_listdir(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
if not (
directory_binding_module.DIRECTORY_BINDING_SUPPORTED
and tree_snapshot_module._DESCRIPTOR_CAPTURE_SUPPORTED
):
pytest.skip("directory descriptor capture is unavailable")
_require_descriptor_capture()
root = tmp_path / "tree"
child = root / "child"
child.mkdir(parents=True)
identity = (child.stat().st_dev, child.stat().st_ino)
monkeypatch.setattr(tree_snapshot_module, "_DESCRIPTOR_SCANDIR_SUPPORTED", False)

def unexpected_listdir(*_args, **_kwargs):
raise AssertionError("bounded expected-child checks must not call os.listdir")

monkeypatch.setattr(tree_snapshot_module.os, "listdir", unexpected_listdir)
_forbid_unbounded_listdir(monkeypatch)

with pytest.raises(TreeSnapshotError, match="bounded directory enumeration"):
BoundDirectoryTree(
Expand All @@ -594,22 +572,13 @@ def test_expected_child_postcheck_uses_capture_override_limits(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
if not (
directory_binding_module.DIRECTORY_BINDING_SUPPORTED
and tree_snapshot_module._DESCRIPTOR_CAPTURE_SUPPORTED
):
pytest.skip("directory descriptor capture is unavailable")
_require_descriptor_capture()
root = tmp_path / "tree"
child = root / "child"
child.mkdir(parents=True)
identity = (child.stat().st_dev, child.stat().st_ino)
bound = BoundDirectoryTree(root, expected_children={"child": identity})
monkeypatch.setattr(tree_snapshot_module, "_DESCRIPTOR_SCANDIR_SUPPORTED", False)

def unexpected_listdir(*_args, **_kwargs):
raise AssertionError("bounded expected-child checks must not call os.listdir")

monkeypatch.setattr(tree_snapshot_module.os, "listdir", unexpected_listdir)
_forbid_unbounded_listdir(monkeypatch)
try:
with pytest.raises(TreeSnapshotError, match="bounded directory enumeration"):
bound.capture(
Expand All @@ -623,11 +592,7 @@ def test_expected_child_postcheck_fails_before_unbounded_listdir(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
if not (
directory_binding_module.DIRECTORY_BINDING_SUPPORTED
and tree_snapshot_module._DESCRIPTOR_CAPTURE_SUPPORTED
):
pytest.skip("directory descriptor capture is unavailable")
_require_descriptor_capture()
root = tmp_path / "tree"
child = root / "child"
child.mkdir(parents=True)
Expand All @@ -640,17 +605,9 @@ def test_expected_child_postcheck_fails_before_unbounded_listdir(
)
original_capture = tree_snapshot_module.capture_directory_descriptor

def unexpected_listdir(*_args, **_kwargs):
raise AssertionError("bounded expected-child checks must not call os.listdir")

def capture_then_disable_streaming(*args, **kwargs):
snapshot = original_capture(*args, **kwargs)
monkeypatch.setattr(
tree_snapshot_module,
"_DESCRIPTOR_SCANDIR_SUPPORTED",
False,
)
monkeypatch.setattr(tree_snapshot_module.os, "listdir", unexpected_listdir)
_forbid_unbounded_listdir(monkeypatch)
return snapshot

monkeypatch.setattr(
Expand All @@ -669,11 +626,7 @@ def test_descriptor_and_portable_limits_capture_the_same_snapshot(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
if not (
directory_binding_module.DIRECTORY_BINDING_SUPPORTED
and tree_snapshot_module._DESCRIPTOR_CAPTURE_SUPPORTED
):
pytest.skip("directory descriptor capture is unavailable")
_require_descriptor_capture()
root = tmp_path / "tree"
(root / "nested").mkdir(parents=True)
(root / "nested" / "included").write_bytes(b"data")
Expand Down Expand Up @@ -728,11 +681,7 @@ def is_reparse(metadata) -> bool:
def unsupported_readlink(_path) -> str:
raise ValueError("private unsupported reparse tag")

monkeypatch.setattr(
directory_binding_module,
"DIRECTORY_BINDING_SUPPORTED",
False,
)
_use_portable_capture(monkeypatch)
monkeypatch.setattr(tree_snapshot_module, "_is_reparse_point", is_reparse)
monkeypatch.setattr(tree_snapshot_module.os, "readlink", unsupported_readlink)

Expand Down
Loading