diff --git a/.gitattributes b/.gitattributes index be7e7a8ba..73de4c566 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,21 +1,21 @@ +tests/_data/filesystems/cpio/initrd.img-6.1.0-15-amd64 filter=lfs diff=lfs merge=lfs -text +tests/_data/filesystems/cpio/initrd.img-6.1.0-17-amd64 filter=lfs diff=lfs merge=lfs -text +tests/_data/loaders/tar/test-anon-filesystems.tar filter=lfs diff=lfs merge=lfs -text tests/_data/loaders/tar/uppercase_driveletter.tar filter=lfs diff=lfs merge=lfs -text -tests/_data/plugins/apps/browser/iexplore/WebCacheV01.dat.gz filter=lfs diff=lfs merge=lfs -text -tests/_data/plugins/apps/browser/firefox/places.sqlite filter=lfs diff=lfs merge=lfs -text -tests/_data/plugins/apps/browser/firefox/cookies.sqlite filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/apps/browser/chrome/History.sqlite filter=lfs diff=lfs merge=lfs -text -tests/_data/plugins/apps/browser/edge/History.sqlite filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/apps/browser/chromium/Cookies.sqlite filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/apps/browser/chromium/History.sqlite filter=lfs diff=lfs merge=lfs -text -tests/_data/plugins/os/windows/dpapi/** filter=lfs diff=lfs merge=lfs -text -tests/_data/plugins/os/windows/notifications/appdb.dat.v3.gz filter=lfs diff=lfs merge=lfs -text -tests/_data/plugins/os/windows/notifications/wpndatabase.db filter=lfs diff=lfs merge=lfs -text -tests/_data/volumes/bde/enc-volume.bin filter=lfs diff=lfs merge=lfs -text -tests/_data/volumes/md/md-nested.bin.gz filter=lfs diff=lfs merge=lfs -text -tests/_data/loaders/tar/test-anon-filesystems.tar filter=lfs diff=lfs merge=lfs -text +tests/_data/plugins/apps/browser/edge/History.sqlite filter=lfs diff=lfs merge=lfs -text +tests/_data/plugins/apps/browser/firefox/cookies.sqlite filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/apps/browser/firefox/cookies.sqlite filter=lfs diff=lfs merge=lfs -text +tests/_data/plugins/apps/browser/firefox/places.sqlite filter=lfs diff=lfs merge=lfs -text +tests/_data/plugins/apps/browser/iexplore/WebCacheV01.dat.gz filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/apps/container/docker/docker.tgz filter=lfs diff=lfs merge=lfs -text -tests/_data/loaders/cpio/initrd.img-6.1.0-15-amd64 filter=lfs diff=lfs merge=lfs -text -tests/_data/loaders/cpio/initrd.img-6.1.0-17-amd64 filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/os/unix/locate/locatedb filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/os/unix/locate/mlocate.db filter=lfs diff=lfs merge=lfs -text tests/_data/plugins/os/unix/locate/plocate.db filter=lfs diff=lfs merge=lfs -text +tests/_data/plugins/os/windows/dpapi/** filter=lfs diff=lfs merge=lfs -text +tests/_data/plugins/os/windows/notifications/appdb.dat.v3.gz filter=lfs diff=lfs merge=lfs -text +tests/_data/plugins/os/windows/notifications/wpndatabase.db filter=lfs diff=lfs merge=lfs -text +tests/_data/volumes/bde/enc-volume.bin filter=lfs diff=lfs merge=lfs -text +tests/_data/volumes/md/md-nested.bin.gz filter=lfs diff=lfs merge=lfs -text diff --git a/dissect/target/filesystem.py b/dissect/target/filesystem.py index 9df001c48..cd1c89684 100644 --- a/dissect/target/filesystem.py +++ b/dissect/target/filesystem.py @@ -1621,6 +1621,7 @@ def open_multi_volume(fhs: list[BinaryIO], *args, **kwargs) -> Filesystem: register("squashfs", "SquashFSFilesystem") register("zip", "ZipFilesystem") register("tar", "TarFilesystem") +register("vmtar", "VmtarFilesystem") register("cpio", "CpioFilesystem") register("ad1", "AD1Filesystem") register("jffs", "JFFSFilesystem") diff --git a/dissect/target/filesystems/vmtar.py b/dissect/target/filesystems/vmtar.py new file mode 100644 index 000000000..eb652ec23 --- /dev/null +++ b/dissect/target/filesystems/vmtar.py @@ -0,0 +1,23 @@ +from typing import BinaryIO, Optional + +from dissect.hypervisor.util import vmtar + +from dissect.target.filesystems.tar import TarFilesystem +from dissect.target.helpers.fsutil import open_decompress + + +class VmtarFilesystem(TarFilesystem): + __type__ = "vmtar" + + def __init__(self, fh: BinaryIO, base: Optional[str] = None, *args, **kwargs): + fh = open_decompress(fileobj=open_decompress(fileobj=fh)) + super().__init__(fh, base, tarinfo=vmtar.VisorTarInfo, *args, **kwargs) + + @staticmethod + def _detect(fh: BinaryIO) -> bool: + """Detect a vmtar file on a given file-like object.""" + # vmtar files can be double compressed (gzip + lzma) + fh = open_decompress(fileobj=open_decompress(fileobj=fh)) + + fh.seek(257) + return fh.read(8) == b"visor \x00" diff --git a/dissect/target/helpers/fsutil.py b/dissect/target/helpers/fsutil.py index cab58d1cc..53a4a85a7 100644 --- a/dissect/target/helpers/fsutil.py +++ b/dissect/target/helpers/fsutil.py @@ -13,6 +13,13 @@ from pathlib import Path from typing import Any, BinaryIO, Iterator, Optional, Sequence, TextIO, Union +try: + import lzma + + HAVE_XZ = True +except ImportError: + HAVE_XZ = False + try: import bz2 @@ -492,7 +499,7 @@ def open_decompress( else: file = fileobj - magic = file.read(4) + magic = file.read(5) file.seek(0) if "b" in mode: @@ -503,6 +510,9 @@ def open_decompress( if magic[:2] == b"\x1f\x8b": return gzip.open(file, mode, encoding=encoding, errors=errors, newline=newline) + if HAVE_XZ and magic[:5] == b"\xfd7zXZ": + return lzma.open(file, mode, encoding=encoding, errors=errors, newline=newline) + if HAVE_BZ2 and magic[:3] == b"BZh" and 0x31 <= magic[3] <= 0x39: # In a valid bz2 header the 4th byte is in the range b'1' ... b'9'. return bz2.open(file, mode, encoding=encoding, errors=errors, newline=newline) diff --git a/tests/_data/loaders/cpio/initrd.img-6.1.0-15-amd64 b/tests/_data/filesystems/cpio/initrd.img-6.1.0-15-amd64 similarity index 100% rename from tests/_data/loaders/cpio/initrd.img-6.1.0-15-amd64 rename to tests/_data/filesystems/cpio/initrd.img-6.1.0-15-amd64 diff --git a/tests/_data/loaders/cpio/initrd.img-6.1.0-17-amd64 b/tests/_data/filesystems/cpio/initrd.img-6.1.0-17-amd64 similarity index 100% rename from tests/_data/loaders/cpio/initrd.img-6.1.0-17-amd64 rename to tests/_data/filesystems/cpio/initrd.img-6.1.0-17-amd64 diff --git a/tests/_data/filesystem/symlink_disk.ext4 b/tests/_data/filesystems/symlink_disk.ext4 similarity index 100% rename from tests/_data/filesystem/symlink_disk.ext4 rename to tests/_data/filesystems/symlink_disk.ext4 diff --git a/tests/_data/filesystems/vmtar/simple.vmtar b/tests/_data/filesystems/vmtar/simple.vmtar new file mode 100644 index 000000000..1b1188692 Binary files /dev/null and b/tests/_data/filesystems/vmtar/simple.vmtar differ diff --git a/tests/filesystems/test_cpio.py b/tests/filesystems/test_cpio.py index 0944d50bb..e7cfc7c5c 100644 --- a/tests/filesystems/test_cpio.py +++ b/tests/filesystems/test_cpio.py @@ -5,7 +5,7 @@ def test_cpio_uncompressed() -> None: - cpio_path = Path(absolute_path("_data/loaders/cpio/initrd.img-6.1.0-17-amd64")) + cpio_path = Path(absolute_path("_data/filesystems/cpio/initrd.img-6.1.0-17-amd64")) with cpio_path.open("rb") as fh: assert CpioFilesystem.detect(fh) @@ -15,7 +15,7 @@ def test_cpio_uncompressed() -> None: def test_cpio_compressed_zstd() -> None: - cpio_path = Path(absolute_path("_data/loaders/cpio/initrd.img-6.1.0-15-amd64")) + cpio_path = Path(absolute_path("_data/filesystems/cpio/initrd.img-6.1.0-15-amd64")) with cpio_path.open("rb") as fh: assert CpioFilesystem.detect(fh) diff --git a/tests/filesystems/test_vmtar.py b/tests/filesystems/test_vmtar.py new file mode 100644 index 000000000..c407fd3fe --- /dev/null +++ b/tests/filesystems/test_vmtar.py @@ -0,0 +1,15 @@ +from pathlib import Path + +from dissect.target.filesystems.vmtar import VmtarFilesystem +from tests._utils import absolute_path + + +def test_filesystems_vmtar() -> None: + vmtar_path = Path(absolute_path("_data/filesystems/vmtar/simple.vmtar")) + + with vmtar_path.open("rb") as fh: + assert VmtarFilesystem.detect(fh) + + fs = VmtarFilesystem(fh) + assert [f.name for f in fs.path("/").iterdir()] == ["hello_world.txt"] + assert fs.get("hello_world.txt").open().read() == b"hello_from_a_tar_file\n" diff --git a/tests/test_filesystem.py b/tests/test_filesystem.py index 8c5e2c84c..df9764b3b 100644 --- a/tests/test_filesystem.py +++ b/tests/test_filesystem.py @@ -1,22 +1,25 @@ +from __future__ import annotations + import os import stat from datetime import datetime, timezone from io import BytesIO +from pathlib import Path from tempfile import NamedTemporaryFile, TemporaryDirectory -from typing import Union +from typing import Any from unittest.mock import Mock, patch import pytest -from _pytest.fixtures import FixtureRequest from dissect.util import ts -from dissect.target import filesystem +from dissect.target import Target, filesystem from dissect.target.exceptions import ( FileNotFoundError, NotADirectoryError, SymlinkRecursionError, ) from dissect.target.filesystem import ( + FilesystemEntry, MappedFile, NotASymlinkError, RootFilesystem, @@ -41,7 +44,7 @@ @pytest.fixture -def vfs(): +def vfs() -> VirtualFilesystem: vfs = VirtualFilesystem() vfs.map_file_entry("/path/to/some/file", VirtualFile(vfs, "path/to/some/file", None)) @@ -55,7 +58,7 @@ def vfs(): return vfs -def test_get(vfs): +def test_get(vfs: VirtualFilesystem) -> None: assert vfs.get("dirlink1").name == "dirlink1" assert vfs.get("dirlink1").is_symlink() assert vfs.get("dirlink1").is_dir() @@ -87,7 +90,7 @@ def test_get(vfs): assert vfs.get("filelink2").stat() == vfs.get("/path/to/some/file").stat() -def test_symlink_across_layers(target_bare): +def test_symlink_across_layers(target_bare: Target) -> None: vfs1 = VirtualFilesystem() vfs1.makedirs("/path/to/symlink/") vfs1.symlink("../target", "/path/to/symlink/target") @@ -106,7 +109,7 @@ def test_symlink_across_layers(target_bare): assert target_dir.stat() == target_entry.entries[0].stat() -def test_symlink_files_across_layers(target_bare): +def test_symlink_files_across_layers(target_bare: Target) -> None: vfs1 = VirtualFilesystem() vfs1.makedirs("/path/to/symlink/") vfs1.symlink("../target", "/path/to/symlink/target") @@ -126,7 +129,7 @@ def test_symlink_files_across_layers(target_bare): assert target_dir.stat() == target_entry.stat() -def test_symlink_to_symlink_across_layers(target_bare): +def test_symlink_to_symlink_across_layers(target_bare: Target) -> None: vfs1 = VirtualFilesystem() vfs1.makedirs("/path/to/symlink/") target_dir = vfs1.makedirs("/path/target") @@ -146,7 +149,7 @@ def test_symlink_to_symlink_across_layers(target_bare): assert target_dir.stat() == target_entry.stat() -def test_recursive_symlink_across_layers(target_bare): +def test_recursive_symlink_across_layers(target_bare: Target) -> None: vfs1 = VirtualFilesystem() vfs1.makedirs("/path/to/symlink/") vfs1.symlink("../target", "/path/to/symlink/target") @@ -164,7 +167,7 @@ def test_recursive_symlink_across_layers(target_bare): target_bare.fs.get("/path/to/symlink/target/").readlink_ext() -def test_symlink_across_3_layers(target_bare): +def test_symlink_across_3_layers(target_bare: Target) -> None: vfs1 = VirtualFilesystem() vfs1.makedirs("/path/to/symlink/") vfs1.symlink("../target", "/path/to/symlink/target") @@ -192,7 +195,7 @@ def test_symlink_across_3_layers(target_bare): assert stat_a == stat_b -def test_recursive_symlink_open_across_layers(target_bare): +def test_recursive_symlink_open_across_layers(target_bare: Target) -> None: vfs1 = VirtualFilesystem() vfs1.makedirs("/path/to/symlink/") vfs1.symlink("../target", "/path/to/symlink/target") @@ -210,8 +213,8 @@ def test_recursive_symlink_open_across_layers(target_bare): target_bare.fs.get("/path/to/symlink/target/").open() -def test_recursive_symlink_dev(target_bare): - fs1 = ExtFilesystem(fh=open(absolute_path("_data/filesystem/symlink_disk.ext4"), "rb")) +def test_recursive_symlink_dev(target_bare: Target) -> None: + fs1 = ExtFilesystem(fh=open(absolute_path("_data/filesystems/symlink_disk.ext4"), "rb")) target_bare.fs.mount(fs=fs1, path="/") with pytest.raises(SymlinkRecursionError): @@ -243,7 +246,7 @@ def test_recursive_symlink_dev(target_bare): ), ], ) -def test_link_resolve(entry, link_dict): +def test_link_resolve(entry: type[FilesystemEntry], link_dict: dict[str, Any]) -> None: """Test wether each filesystem resolves a link as intended.""" if entry is None: pytest.skip("dissect.vmfs is required") @@ -271,7 +274,7 @@ def test_link_resolve(entry, link_dict): assert link.readlink_ext() == actual_file -def test_virtual_symlink_to_dir_get(vfs): +def test_virtual_symlink_to_dir_get(vfs: VirtualFilesystem) -> None: some_file = vfs.get("/path/to/some/file") symlink = vfs.get("/dirlink1") @@ -280,13 +283,13 @@ def test_virtual_symlink_to_dir_get(vfs): assert some_file is some_file2 -def test_virtual_symlink_to_file_get(vfs): +def test_virtual_symlink_to_file_get(vfs: VirtualFilesystem) -> None: symlink = vfs.get("/filelink1") with pytest.raises(NotADirectoryError): symlink.get("does_not_exist") -def test_virtual_symlink_to_symlink_get(vfs): +def test_virtual_symlink_to_symlink_get(vfs: VirtualFilesystem) -> None: some_file = vfs.get("/path/to/some/file") symlink = vfs.get("/dirlink2") @@ -310,7 +313,7 @@ def test_virtual_symlink_to_symlink_get(vfs): "/dirlink1", ], ) -def test_virtual_entry_get_self(vfs, path, entry_name): +def test_virtual_entry_get_self(vfs: VirtualFilesystem, path: str, entry_name: str) -> None: some_entry = vfs.get(entry_name) some_entry2 = some_entry.get(path) @@ -348,7 +351,7 @@ def test_virtual_filesystem_get(): ("/", "/dirlink2/../../../"), ], ) -def test_virtual_filesystem_get_equal_vfs_paths(vfs, vfs_path1, vfs_path2): +def test_virtual_filesystem_get_equal_vfs_paths(vfs: VirtualFilesystem, vfs_path1: str, vfs_path2: str) -> None: assert vfs.get(vfs_path1) is vfs.get(vfs_path2) @@ -363,7 +366,7 @@ def test_virtual_filesystem_get_equal_vfs_paths(vfs, vfs_path1, vfs_path2): ("/dirlink1", "/dirlink2"), ], ) -def test_virtual_filesystem_get_unequal_vfs_paths(vfs, vfs_path1, vfs_path2): +def test_virtual_filesystem_get_unequal_vfs_paths(vfs: VirtualFilesystem, vfs_path1: str, vfs_path2: str) -> None: assert vfs.get(vfs_path1) is not vfs.get(vfs_path2) @@ -376,12 +379,14 @@ def test_virtual_filesystem_get_unequal_vfs_paths(vfs, vfs_path1, vfs_path2): ("/path/to/other/path/to/some/non-exisiting-file", FileNotFoundError), ], ) -def test_virtual_filesystem_get_erroring_vfs_paths(vfs, vfs_path, exception): +def test_virtual_filesystem_get_erroring_vfs_paths( + vfs: VirtualFilesystem, vfs_path: str, exception: type[Exception] +) -> None: with pytest.raises(exception): vfs.get(vfs_path) -def test_virtual_filesystem_get_case_sensitive(): +def test_virtual_filesystem_get_case_sensitive() -> None: vfs = VirtualFilesystem() vfs.map_file_entry("/path/to/some/file_lower_case", VirtualFile(vfs, "file_lower_case", None)) vfs.map_file_entry("/path/TO/some/FILE_UPPER_CASE", VirtualFile(vfs, "FILE_UPPER_CASE", None)) @@ -394,7 +399,7 @@ def test_virtual_filesystem_get_case_sensitive(): assert vfs.get("/path/TO/some/file_upper_case") -def test_virtual_filesystem_get_case_insensitive(): +def test_virtual_filesystem_get_case_insensitive() -> None: vfs = VirtualFilesystem(case_sensitive=False) vfs.map_file_entry("/path/to/some/file_lower_case", VirtualFile(vfs, "file_lower_case", None)) vfs.map_file_entry("/path/TO/some/FILE_UPPER_CASE", VirtualFile(vfs, "FILE_UPPER_CASE", None)) @@ -418,7 +423,7 @@ def test_virtual_filesystem_get_case_insensitive(): ), ], ) -def test_virtual_filesystem_makedirs(paths): +def test_virtual_filesystem_makedirs(paths: str) -> None: vfs = VirtualFilesystem() for vfspath in paths: @@ -433,7 +438,7 @@ def test_virtual_filesystem_makedirs(paths): assert vfs_entry.path == partial_path.strip("/") -def test_virtual_filesystem_makedirs_root(): +def test_virtual_filesystem_makedirs_root() -> None: vfs = VirtualFilesystem() vfspath = "/" @@ -444,7 +449,7 @@ def test_virtual_filesystem_makedirs_root(): assert vfs_entry is vfs.root -def test_virtual_filesystem_map_fs(vfs): +def test_virtual_filesystem_map_fs(vfs: VirtualFilesystem) -> None: root_vfs = VirtualFilesystem() map_path = "/some/dir/" file_path = "/path/to/some/file" @@ -461,11 +466,11 @@ def test_virtual_filesystem_map_fs(vfs): root_vfs.get(file_path) -def test_virtual_filesystem_mount(vfs): +def test_virtual_filesystem_mount(vfs: VirtualFilesystem) -> None: assert vfs.mount == vfs.map_fs -def test_virtual_filesystem_map_dir(tmp_path): +def test_virtual_filesystem_map_dir(tmp_path: Path) -> None: vfs = VirtualFilesystem() vfs_path = "/map/point/" with ( @@ -511,7 +516,7 @@ def test_virtual_filesystem_map_dir(tmp_path): "/path///to/file", ], ) -def test_virtual_filesystem_map_file(vfs_path): +def test_virtual_filesystem_map_file(vfs_path: str) -> None: vfs = VirtualFilesystem() real_path = "/tmp/foo" @@ -525,7 +530,7 @@ def test_virtual_filesystem_map_file(vfs_path): assert vfs_entry.entry == real_path -def test_virtual_filesystem_map_file_as_dir(): +def test_virtual_filesystem_map_file_as_dir() -> None: vfs = VirtualFilesystem() real_path = "/tmp/foo" @@ -541,7 +546,7 @@ def test_virtual_filesystem_map_file_as_dir(): "/path///to/file", ], ) -def test_virtual_filesystem_map_file_fh(vfs_path): +def test_virtual_filesystem_map_file_fh(vfs_path: str) -> None: vfs = VirtualFilesystem() fh = Mock() @@ -555,7 +560,7 @@ def test_virtual_filesystem_map_file_fh(vfs_path): assert vfs_entry.entry is fh -def test_virtual_filesystem_map_file_fh_as_dir(): +def test_virtual_filesystem_map_file_fh_as_dir() -> None: vfs = VirtualFilesystem() fh = Mock() @@ -578,7 +583,7 @@ def test_virtual_filesystem_map_file_fh_as_dir(): "/", ], ) -def test_virtual_filesystem_map_file_entry(vfs_path): +def test_virtual_filesystem_map_file_entry(vfs_path: str) -> None: vfs = VirtualFilesystem() entry_path = fsutil.normalize(vfs_path, alt_separator=vfs.alt_separator).strip("/") dir_entry = VirtualDirectory(vfs, entry_path) @@ -622,7 +627,7 @@ def test_virtual_filesystem_map_file_entry(vfs_path): ), ], ) -def test_virtual_filesystem_link(vfs_path, link_path): +def test_virtual_filesystem_link(vfs_path: str, link_path: str) -> None: vfs = VirtualFilesystem() entry_path = fsutil.normalize(vfs_path, alt_separator=vfs.alt_separator).strip("/") file_object = Mock() @@ -709,7 +714,7 @@ def test_virtual_filesystem_stat( vfs: VirtualFilesystem, src_entry: str, dst_entry: str, - request: FixtureRequest, + request: pytest.FixtureRequest, ) -> None: src_entry = request.getfixturevalue(src_entry) dst_entry = request.getfixturevalue(dst_entry) @@ -727,7 +732,7 @@ def test_virtual_filesystem_stat( "filelink_entry", ], ) -def test_virtual_filesystem_lstat(vfs: VirtualFilesystem, entry: str, request: FixtureRequest) -> None: +def test_virtual_filesystem_lstat(vfs: VirtualFilesystem, entry: str, request: pytest.FixtureRequest) -> None: entry = request.getfixturevalue(entry) assert vfs.lstat(entry.path) == entry.lstat() @@ -747,7 +752,7 @@ def test_virtual_filesystem_is_dir( vfs: VirtualFilesystem, src_entry: str, dst_entry: str, - request: FixtureRequest, + request: pytest.FixtureRequest, ) -> None: src_entry = request.getfixturevalue(src_entry) dst_entry = request.getfixturevalue(dst_entry) @@ -771,7 +776,7 @@ def test_virtual_filesystem_is_file( vfs: VirtualFilesystem, src_entry: str, dst_entry: str, - request: FixtureRequest, + request: pytest.FixtureRequest, ) -> None: src_entry = request.getfixturevalue(src_entry) dst_entry = request.getfixturevalue(dst_entry) @@ -815,7 +820,7 @@ def test_virutal_directory_is_dir(virt_dir: VirtualDirectory) -> None: assert virt_dir.is_dir(follow_symlinks=False) -def test_virutal_directory_is_file(virt_dir: VirtualDirectory): +def test_virutal_directory_is_file(virt_dir: VirtualDirectory) -> None: assert not virt_dir.is_file(follow_symlinks=True) assert not virt_dir.is_file(follow_symlinks=False) @@ -844,7 +849,7 @@ def test_virutal_file_is_file(virt_file: VirtualFile) -> None: assert virt_file.is_file(follow_symlinks=False) -def test_virtual_symlink_stat(filelink_entry: VirtualSymlink, file_entry: Union[VirtualFile, VirtualDirectory]) -> None: +def test_virtual_symlink_stat(filelink_entry: VirtualSymlink, file_entry: VirtualFile | VirtualDirectory) -> None: assert filelink_entry.stat(follow_symlinks=False) == filelink_entry.lstat() assert filelink_entry.stat(follow_symlinks=True) == file_entry.stat() @@ -860,7 +865,7 @@ def test_virtual_symlink_lstat(filelink_entry: VirtualSymlink) -> None: ("filelink_entry", False), ), ) -def test_virtual_symlink_is_dir(virt_link: str, is_dir: bool, request: FixtureRequest) -> None: +def test_virtual_symlink_is_dir(virt_link: str, is_dir: bool, request: pytest.FixtureRequest) -> None: virt_link = request.getfixturevalue(virt_link) assert virt_link.is_dir(follow_symlinks=False) is False @@ -874,7 +879,7 @@ def test_virtual_symlink_is_dir(virt_link: str, is_dir: bool, request: FixtureRe ("filelink_entry", True), ), ) -def test_virtual_symlink_is_file(virt_link: str, is_file: bool, request: FixtureRequest) -> None: +def test_virtual_symlink_is_file(virt_link: str, is_file: bool, request: pytest.FixtureRequest) -> None: virt_link = request.getfixturevalue(virt_link) assert virt_link.is_file(follow_symlinks=False) is False @@ -997,7 +1002,7 @@ def root_filelink_entry(rootfs: RootFilesystem) -> VirtualSymlink: ("root_filelink_entry", "root_file_entry"), ], ) -def test_root_filesystem_entry_stat(src_entry: str, dst_entry: str, request: FixtureRequest) -> None: +def test_root_filesystem_entry_stat(src_entry: str, dst_entry: str, request: pytest.FixtureRequest) -> None: src_entry = request.getfixturevalue(src_entry) dst_entry = request.getfixturevalue(dst_entry) @@ -1013,7 +1018,7 @@ def test_root_filesystem_entry_stat(src_entry: str, dst_entry: str, request: Fix ("root_file_entry", stat.S_IFREG), ], ) -def test_root_filesystem_entry_lstat(entry: str, st_mode: int, request: FixtureRequest) -> None: +def test_root_filesystem_entry_lstat(entry: str, st_mode: int, request: pytest.FixtureRequest) -> None: entry = request.getfixturevalue(entry) assert entry.lstat().st_mode == st_mode @@ -1028,7 +1033,9 @@ def test_root_filesystem_entry_lstat(entry: str, st_mode: int, request: FixtureR ("root_filelink_entry", False, False), ], ) -def test_root_filesystem_entry_is_dir(entry: str, src_is_dir: bool, dst_is_dir: bool, request: FixtureRequest) -> None: +def test_root_filesystem_entry_is_dir( + entry: str, src_is_dir: bool, dst_is_dir: bool, request: pytest.FixtureRequest +) -> None: entry = request.getfixturevalue(entry) assert entry.is_dir(follow_symlinks=False) == src_is_dir @@ -1048,7 +1055,7 @@ def test_root_filesystem_entry_is_file( entry: str, src_is_file: bool, dst_is_file: bool, - request: FixtureRequest, + request: pytest.FixtureRequest, ) -> None: entry = request.getfixturevalue(entry)