Skip to content

Commit 342e654

Browse files
authored
gh-124213: Skip tests failing inside systemd-nspawn --suppress-sync=true (#124215)
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.
1 parent 1a57772 commit 342e654

File tree

4 files changed

+46
-4
lines changed

4 files changed

+46
-4
lines changed

Lib/test/support/__init__.py

+33
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"without_optimizer",
6262
"force_not_colorized",
6363
"BrokenIter",
64+
"in_systemd_nspawn_sync_suppressed",
6465
]
6566

6667

@@ -2873,3 +2874,35 @@ def __iter__(self):
28732874
if self.iter_raises:
28742875
1/0
28752876
return self
2877+
2878+
2879+
def in_systemd_nspawn_sync_suppressed() -> bool:
2880+
"""
2881+
Test whether the test suite is runing in systemd-nspawn
2882+
with ``--suppress-sync=true``.
2883+
2884+
This can be used to skip tests that rely on ``fsync()`` calls
2885+
and similar not being intercepted.
2886+
"""
2887+
2888+
if not hasattr(os, "O_SYNC"):
2889+
return False
2890+
2891+
try:
2892+
with open("/run/systemd/container", "rb") as fp:
2893+
if fp.read().rstrip() != b"systemd-nspawn":
2894+
return False
2895+
except FileNotFoundError:
2896+
return False
2897+
2898+
# If systemd-nspawn is used, O_SYNC flag will immediately
2899+
# trigger EINVAL. Otherwise, ENOENT will be given instead.
2900+
import errno
2901+
try:
2902+
with os.open(__file__, os.O_RDONLY | os.O_SYNC):
2903+
pass
2904+
except OSError as err:
2905+
if err.errno == errno.EINVAL:
2906+
return True
2907+
2908+
return False

Lib/test/test_mmap.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from test.support import (
22
requires, _2G, _4G, gc_collect, cpython_only, is_emscripten, is_apple,
3+
in_systemd_nspawn_sync_suppressed,
34
)
45
from test.support.import_helper import import_module
56
from test.support.os_helper import TESTFN, unlink
@@ -839,7 +840,8 @@ def test_flush_return_value(self):
839840
mm.write(b'python')
840841
result = mm.flush()
841842
self.assertIsNone(result)
842-
if sys.platform.startswith(('linux', 'android')):
843+
if (sys.platform.startswith(('linux', 'android'))
844+
and not in_systemd_nspawn_sync_suppressed()):
843845
# 'offset' must be a multiple of mmap.PAGESIZE on Linux.
844846
# See bpo-34754 for details.
845847
self.assertRaises(OSError, mm.flush, 1, len(b'python'))

Lib/test/test_os.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -2351,9 +2351,13 @@ def test_chmod(self):
23512351

23522352
@unittest.skipIf(support.is_wasi, "Cannot create invalid FD on WASI.")
23532353
class TestInvalidFD(unittest.TestCase):
2354-
singles = ["fchdir", "dup", "fdatasync", "fstat",
2355-
"fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
2356-
singles_fildes = {"fchdir", "fdatasync", "fsync"}
2354+
singles = ["fchdir", "dup", "fstat", "fstatvfs", "tcgetpgrp", "ttyname"]
2355+
singles_fildes = {"fchdir"}
2356+
# systemd-nspawn --suppress-sync=true does not verify fd passed
2357+
# fdatasync() and fsync(), and always returns success
2358+
if not support.in_systemd_nspawn_sync_suppressed():
2359+
singles += ["fdatasync", "fsync"]
2360+
singles_fildes |= {"fdatasync", "fsync"}
23572361
#singles.append("close")
23582362
#We omit close because it doesn't raise an exception on some platforms
23592363
def get_single(f):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Detect whether the test suite is running inside a systemd-nspawn container
2+
with ``--suppress-sync=true`` option, and skip the ``test_os``
3+
and ``test_mmap`` tests that are failing in this scenario.

0 commit comments

Comments
 (0)