import os from pathlib import Path import pytest from pkgcore.fs import fs, livefs from pkgcore.fs.contents import contentsSet class TestFsObjs: def check_attrs(self, obj, path, offset=None): if offset is None: st = path.lstat() else: st = (offset / path).lstat() if offset is not None: assert offset.is_absolute(), f"path must be absolute, got {path!r}" assert (obj.mode & 0o7777) == (st.st_mode & 0o7777) assert obj.uid == st.st_uid assert obj.gid == st.st_gid if fs.isreg(obj): if offset is None: assert obj.data.path == str(path) else: assert obj.data.path == str(offset / path) def test_data_source(self): o = livefs.gen_obj("/tmp/etc/passwd", real_location="/etc/passwd") assert o.location, "/tmp/etc/passwd" assert o.data.path, "/etc/passwd" with open("/etc/passwd", "rb") as f: with o.data.bytes_fileobj() as fileobj: assert fileobj.read() == f.read() def test_gen_obj_reg(self, tmp_path): (path := tmp_path / "reg_obj").touch() o = livefs.gen_obj(str(path)) assert fs.isreg(o) self.check_attrs(o, path) o2 = livefs.gen_obj(str(path), inode=None) self.check_attrs(o, path) assert o.inode != o2.inode def test_gen_obj_dir(self, tmp_path): o = livefs.gen_obj(str(tmp_path)) assert fs.isdir(o) self.check_attrs(o, tmp_path) def test_gen_obj_sym(self, tmp_path): (src := tmp_path / "s").touch() (link := tmp_path / "t").symlink_to(src) obj = livefs.gen_obj(str(link)) assert isinstance(obj, fs.fsSymlink) self.check_attrs(obj, link) assert os.readlink(link) == obj.target def test_gen_obj_fifo(self, tmp_path): os.mkfifo(path := tmp_path / "fifo") o = livefs.gen_obj(str(path)) self.check_attrs(o, path) def test_iterscan(self, tmp_path): (path := tmp_path / "iscan").mkdir() files = [path / x for x in ("tmp", "blah", "dar")] for x in files: x.touch() dirs = [path / x for x in ("a", "b", "c")] for x in dirs: x.mkdir() dirs.append(path) for obj in livefs.iter_scan(str(path)): assert isinstance(obj, fs.fsBase) if fs.isreg(obj): assert Path(obj.location) in files elif fs.isdir(obj): assert Path(obj.location) in dirs else: pytest.fail(f"unknown object popped up in testing dir, {obj!r}") self.check_attrs(obj, Path(obj.location)) # do offset verification now. offset = path for obj in livefs.iter_scan(str(path), offset=str(offset)): self.check_attrs(obj, Path(obj.location).relative_to("/"), offset=offset) seen = [] for obj in livefs.iter_scan(str(files[0])): self.check_attrs(obj, Path(obj.location)) seen.append(obj.location) assert [str(files[0])] == sorted(seen) def test_sorted_scan(self, tmp_path): for x in ("tmp", "blah", "dar"): (tmp_path / x).touch() for x in ("a", "b", "c"): (tmp_path / x).mkdir() # regular directory scanning sorted_files = livefs.sorted_scan(str(tmp_path)) assert sorted_files == [str(tmp_path / x) for x in ("blah", "dar", "tmp")] # nonexistent paths nonexistent_path = str(tmp_path / "foobar") assert livefs.sorted_scan(nonexistent_path) == [] assert livefs.sorted_scan(nonexistent_path, nonexistent=True) == [ nonexistent_path ] def test_sorted_scan_hidden(self, tmp_path): for x in (".tmp", "blah"): (tmp_path / x).touch() sorted_files = livefs.sorted_scan(str(tmp_path)) assert [str(tmp_path / x) for x in (".tmp", "blah")] == sorted_files sorted_files = livefs.sorted_scan(str(tmp_path), hidden=False) assert [str(tmp_path / x) for x in ("blah",)] == sorted_files def test_sorted_scan_backup(self, tmp_path): for x in ("blah", "blah~"): (tmp_path / x).touch() sorted_files = livefs.sorted_scan(str(tmp_path)) assert [str(tmp_path / x) for x in ("blah", "blah~")] == sorted_files sorted_files = livefs.sorted_scan(str(tmp_path), backup=False) assert [str(tmp_path / x) for x in ("blah",)] == sorted_files def test_relative_sym(self, tmp_path): (path := tmp_path / "relative-symlink-test").symlink_to("../sym1/blah") o = livefs.gen_obj(str(path)) assert o.target == "../sym1/blah" def test_intersect(self, tmp_path): (tmp_path / "reg").touch() cset = contentsSet([fs.fsFile("reg", strict=False)]) cset = cset.insert_offset(str(tmp_path)) assert contentsSet(livefs.intersect(cset)) == cset cset = contentsSet( [ fs.fsFile("reg/foon", strict=False), fs.fsFile("reg/dar", strict=False), fs.fsDir("reg/dir", strict=False), ] ).insert_offset(str(tmp_path)) assert not list(livefs.intersect(cset)) cset = contentsSet([fs.fsDir("reg", strict=False)]) assert not list(livefs.intersect(cset))