From 7d43398a17b2259afeb6a4f812ec7426351be0f5 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Fri, 7 Nov 2025 13:45:10 +0100 Subject: [PATCH] testsuite: improve haiku compatibility haiku does not have os.mknod. and it looks like it does not have hardlinks either. --- src/borg/testsuite/__init__.py | 2 ++ src/borg/testsuite/archiver/__init__.py | 11 ++++++----- src/borg/testsuite/archiver/create_cmd_test.py | 4 ++-- src/borg/testsuite/archiver/extract_cmd_test.py | 1 + 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/borg/testsuite/__init__.py b/src/borg/testsuite/__init__.py index 4cc27f0f2..b117b32b0 100644 --- a/src/borg/testsuite/__init__.py +++ b/src/borg/testsuite/__init__.py @@ -26,6 +26,8 @@ from ..platformflags import is_win32 # Does this version of llfuse support ns precision? have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, "st_mtime_ns") if llfuse else False +has_mknod = hasattr(os, "mknod") + has_lchflags = hasattr(os, "lchflags") or sys.platform.startswith("linux") try: with tempfile.NamedTemporaryFile() as file: diff --git a/src/borg/testsuite/archiver/__init__.py b/src/borg/testsuite/archiver/__init__.py index 2a546f28b..130c1344c 100644 --- a/src/borg/testsuite/archiver/__init__.py +++ b/src/borg/testsuite/archiver/__init__.py @@ -26,7 +26,7 @@ from ...manifest import Manifest from ...platform import get_flags from ...remote import RemoteRepository from ...repository import Repository -from .. import has_lchflags, is_utime_fully_supported, have_fuse_mtime_ns, st_mtime_ns_round, no_selinux +from .. import has_lchflags, has_mknod, is_utime_fully_supported, have_fuse_mtime_ns, st_mtime_ns_round, no_selinux from .. import changedir from .. import are_symlinks_supported, are_hardlinks_supported, are_fifos_supported from ..platform.platform_test import is_win32 @@ -232,10 +232,11 @@ def create_test_files(input_path, create_hardlinks=True): have_root = False else: try: - # Block device - os.mknod("input/bdev", 0o600 | stat.S_IFBLK, os.makedev(10, 20)) - # Char device - os.mknod("input/cdev", 0o600 | stat.S_IFCHR, os.makedev(30, 40)) + if has_mknod: + # Block device + os.mknod("input/bdev", 0o600 | stat.S_IFBLK, os.makedev(10, 20)) + # Char device + os.mknod("input/cdev", 0o600 | stat.S_IFCHR, os.makedev(30, 40)) # File owner os.chown("input/file1", 100, 200) # raises OSError invalid argument on cygwin # File mode diff --git a/src/borg/testsuite/archiver/create_cmd_test.py b/src/borg/testsuite/archiver/create_cmd_test.py index 94deb4211..8e084a8ac 100644 --- a/src/borg/testsuite/archiver/create_cmd_test.py +++ b/src/borg/testsuite/archiver/create_cmd_test.py @@ -17,7 +17,7 @@ from ...manifest import Manifest from ...platform import is_win32, is_darwin from ...repository import Repository from ...helpers import CommandError, BackupPermissionError -from .. import has_lchflags +from .. import has_lchflags, has_mknod from .. import changedir from .. import ( are_symlinks_supported, @@ -84,7 +84,7 @@ def test_basic_functionality(archivers, request): expected.append("input/link1") if are_hardlinks_supported(): expected.append("input/hardlink") - if not have_root: + if not have_root or not has_mknod: # We could not create these device files without (fake)root. expected.remove("input/bdev") expected.remove("input/cdev") diff --git a/src/borg/testsuite/archiver/extract_cmd_test.py b/src/borg/testsuite/archiver/extract_cmd_test.py index a259bde0e..8726b087d 100644 --- a/src/borg/testsuite/archiver/extract_cmd_test.py +++ b/src/borg/testsuite/archiver/extract_cmd_test.py @@ -703,6 +703,7 @@ def test_do_not_fail_when_percent_is_in_file_name(archivers, request): cmd(archiver, "extract", "test", exit_code=EXIT_WARNING) +@pytest.mark.skipif(not are_hardlinks_supported(), reason="hardlinks not supported") def test_extract_continue(archivers, request): archiver = request.getfixturevalue(archivers) CONTENTS1, CONTENTS2, CONTENTS3 = b"contents1" * 100, b"contents2" * 200, b"contents3" * 300