aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2024-09-20 15:37:49 +0200
committerMichał Górny <mgorny@gentoo.org>2024-09-23 11:07:47 +0200
commit30a9a8dccdad64bbfcf840ebcf8825c8d13428a6 (patch)
tree76363c8cab265f2b9b1d2a29482ede9d6a1a10ca
parentGH-113655: Lower the C recursion limit for HPPA, PPC64 and SPARC (#124264) (diff)
downloadcpython-30a9a8dccdad64bbfcf840ebcf8825c8d13428a6.tar.gz
cpython-30a9a8dccdad64bbfcf840ebcf8825c8d13428a6.tar.bz2
cpython-30a9a8dccdad64bbfcf840ebcf8825c8d13428a6.zip
gh-124213: Skip tests failing inside systemd-nspawn --suppress-sync=true (#124215)gentoo-3.13.0rc2_p2
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.
-rw-r--r--Lib/test/support/__init__.py33
-rw-r--r--Lib/test/test_mmap.py4
-rw-r--r--Lib/test/test_os.py10
3 files changed, 43 insertions, 4 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index ed23f73e3cf..184a1783855 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -61,6 +61,7 @@ __all__ = [
"without_optimizer",
"force_not_colorized",
"BrokenIter",
+ "in_systemd_nspawn_sync_suppressed",
]
@@ -2699,3 +2700,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
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index a1cf5384ada..b2a299ed172 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -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'))
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index a4a31f5ce45..b2a2dd2f603 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -2305,9 +2305,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):