Add full test suite with pytest
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import stat
|
||||
from pathlib import Path
|
||||
|
||||
from chguard.restore import apply_restore, plan_restore
|
||||
|
||||
|
||||
def test_plan_restore_reports_mode_owner_missing_and_type_changes(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
config = root / "config.txt"
|
||||
config.write_text("config", encoding="utf-8")
|
||||
config.chmod(0o644)
|
||||
logs = root / "logs"
|
||||
logs.write_text("not a directory", encoding="utf-8")
|
||||
|
||||
current = config.lstat()
|
||||
rows = [
|
||||
("config.txt", "file", 0o600, current.st_uid + 1, current.st_gid),
|
||||
("missing.txt", "file", 0o644, current.st_uid, current.st_gid),
|
||||
("logs", "dir", 0o755, current.st_uid, current.st_gid),
|
||||
]
|
||||
|
||||
changes = plan_restore(
|
||||
root=root,
|
||||
rows=rows,
|
||||
restore_permissions=True,
|
||||
restore_owner=True,
|
||||
)
|
||||
|
||||
kinds_by_path = {(change.path.name, change.kind) for change in changes}
|
||||
assert ("config.txt", "mode") in kinds_by_path
|
||||
assert ("config.txt", "owner") in kinds_by_path
|
||||
assert ("missing.txt", "missing") in kinds_by_path
|
||||
assert ("logs", "type") in kinds_by_path
|
||||
|
||||
|
||||
def test_plan_restore_marks_unselected_scope_as_not_applicable(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
config = root / "config.txt"
|
||||
config.write_text("config", encoding="utf-8")
|
||||
config.chmod(0o644)
|
||||
st = config.lstat()
|
||||
|
||||
changes = plan_restore(
|
||||
root=root,
|
||||
rows=[("config.txt", "file", 0o600, st.st_uid, st.st_gid)],
|
||||
restore_permissions=False,
|
||||
restore_owner=True,
|
||||
)
|
||||
|
||||
assert len(changes) == 1
|
||||
assert changes[0].kind == "mode"
|
||||
assert not changes[0].will_apply
|
||||
|
||||
|
||||
def test_apply_restore_changes_mode_without_changing_contents(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
config = root / "config.txt"
|
||||
config.write_text("config", encoding="utf-8")
|
||||
config.chmod(0o644)
|
||||
st = config.lstat()
|
||||
|
||||
apply_restore(
|
||||
root=root,
|
||||
rows=[("config.txt", "file", 0o600, st.st_uid, st.st_gid)],
|
||||
restore_permissions=True,
|
||||
restore_owner=False,
|
||||
)
|
||||
|
||||
assert stat.S_IMODE(config.lstat().st_mode) == 0o600
|
||||
assert config.read_text(encoding="utf-8") == "config"
|
||||
|
||||
|
||||
def test_apply_restore_skips_missing_and_type_mismatch(tmp_path: Path) -> None:
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
config = root / "config.txt"
|
||||
config.write_text("config", encoding="utf-8")
|
||||
config.chmod(0o644)
|
||||
st = config.lstat()
|
||||
|
||||
apply_restore(
|
||||
root=root,
|
||||
rows=[
|
||||
("missing.txt", "file", 0o600, st.st_uid, st.st_gid),
|
||||
("config.txt", "dir", 0o600, st.st_uid, st.st_gid),
|
||||
],
|
||||
restore_permissions=True,
|
||||
restore_owner=False,
|
||||
)
|
||||
|
||||
assert not (root / "missing.txt").exists()
|
||||
assert stat.S_IMODE(config.lstat().st_mode) == 0o644
|
||||
assert os.listdir(root) == ["config.txt"]
|
||||
Reference in New Issue
Block a user