]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-124213: Skip tests failing inside systemd-nspawn --suppress-sync=true (#124215) main
authorMichał Górny <mgorny@gentoo.org>
Fri, 20 Sep 2024 13:37:49 +0000 (15:37 +0200)
committerGitHub <noreply@github.com>
Fri, 20 Sep 2024 13:37:49 +0000 (13:37 +0000)
Add a helper function that checks whether the test suite is running
inside a systemd-nspawn container, and skip the few tests failing
with `--suppress-sync=true` in that case.  The tests are failing because
`--suppress-sync=true` stubs out `fsync()`, `fdatasync()` and `msync()`
calls, and therefore they always return success without checking for
invalid arguments.

Call `os.open(__file__, os.O_RDONLY | os.O_SYNC)` and check the errno to
detect whether `--suppress-sync=true` is actually used, and skip
the tests only in that scenario.

Lib/test/support/__init__.py
Lib/test/test_mmap.py
Lib/test/test_os.py
Misc/NEWS.d/next/Tests/2024-09-18-18-39-21.gh-issue-124213.AQq_xg.rst [new file with mode: 0644]

index dbf479dddff7b349bf547db356d51eaf2573c805..628529b8664c77d1edc82b4ca83482016402a75c 100644 (file)
@@ -61,6 +61,7 @@ __all__ = [
     "without_optimizer",
     "force_not_colorized",
     "BrokenIter",
+    "in_systemd_nspawn_sync_suppressed",
     ]
 
 
@@ -2873,3 +2874,35 @@ class BrokenIter:
         if self.iter_raises:
             1/0
         return self
+
+
+def in_systemd_nspawn_sync_suppressed() -> bool:
+    """
+    Test whether the test suite is runing in systemd-nspawn
+    with ``--suppress-sync=true``.
+
+    This can be used to skip tests that rely on ``fsync()`` calls
+    and similar not being intercepted.
+    """
+
+    if not hasattr(os, "O_SYNC"):
+        return False
+
+    try:
+        with open("/run/systemd/container", "rb") as fp:
+            if fp.read().rstrip() != b"systemd-nspawn":
+                return False
+    except FileNotFoundError:
+        return False
+
+    # If systemd-nspawn is used, O_SYNC flag will immediately
+    # trigger EINVAL.  Otherwise, ENOENT will be given instead.
+    import errno
+    try:
+        with os.open(__file__, os.O_RDONLY | os.O_SYNC):
+            pass
+    except OSError as err:
+        if err.errno == errno.EINVAL:
+            return True
+
+    return False
index a1cf5384ada5b5f1530a26d335e0b07b11010894..b2a299ed1729679ec46f0a8ea296786b6c992d44 100644 (file)
@@ -1,5 +1,6 @@
 from test.support import (
     requires, _2G, _4G, gc_collect, cpython_only, is_emscripten, is_apple,
+    in_systemd_nspawn_sync_suppressed,
 )
 from test.support.import_helper import import_module
 from test.support.os_helper import TESTFN, unlink
@@ -839,7 +840,8 @@ class MmapTests(unittest.TestCase):
         mm.write(b'python')
         result = mm.flush()
         self.assertIsNone(result)
-        if sys.platform.startswith(('linux', 'android')):
+        if (sys.platform.startswith(('linux', 'android'))
+            and not in_systemd_nspawn_sync_suppressed()):
             # 'offset' must be a multiple of mmap.PAGESIZE on Linux.
             # See bpo-34754 for details.
             self.assertRaises(OSError, mm.flush, 1, len(b'python'))
index 1e570c757fccbc6843d9f933be124d35fa7ea0ea..9fa4e406bd2468ecefc41cbb8889a6b5010fb5c8 100644 (file)
@@ -2351,9 +2351,13 @@ class Win32ErrorTests(unittest.TestCase):
 
 @unittest.skipIf(support.is_wasi, "Cannot create invalid FD on WASI.")
 class TestInvalidFD(unittest.TestCase):
-    singles = ["fchdir", "dup", "fdatasync", "fstat",
-               "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
-    singles_fildes = {"fchdir", "fdatasync", "fsync"}
+    singles = ["fchdir", "dup", "fstat", "fstatvfs", "tcgetpgrp", "ttyname"]
+    singles_fildes = {"fchdir"}
+    # systemd-nspawn --suppress-sync=true does not verify fd passed
+    # fdatasync() and fsync(), and always returns success
+    if not support.in_systemd_nspawn_sync_suppressed():
+        singles += ["fdatasync", "fsync"]
+        singles_fildes |= {"fdatasync", "fsync"}
     #singles.append("close")
     #We omit close because it doesn't raise an exception on some platforms
     def get_single(f):
diff --git a/Misc/NEWS.d/next/Tests/2024-09-18-18-39-21.gh-issue-124213.AQq_xg.rst b/Misc/NEWS.d/next/Tests/2024-09-18-18-39-21.gh-issue-124213.AQq_xg.rst
new file mode 100644 (file)
index 0000000..021fbef
--- /dev/null
@@ -0,0 +1,3 @@
+Detect whether the test suite is running inside a systemd-nspawn container
+with ``--suppress-sync=true`` option, and skip the ``test_os``
+and ``test_mmap`` tests that are failing in this scenario.