Skip to content

Commit

Permalink
gh-124213: Skip tests failing inside systemd-nspawn --suppress-sync=t…
Browse files Browse the repository at this point in the history
…rue (#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.
  • Loading branch information
mgorny authored Sep 20, 2024
1 parent 1a57772 commit 342e654
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
33 changes: 33 additions & 0 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"without_optimizer",
"force_not_colorized",
"BrokenIter",
"in_systemd_nspawn_sync_suppressed",
]


Expand Down Expand Up @@ -2873,3 +2874,35 @@ def __iter__(self):
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
4 changes: 3 additions & 1 deletion Lib/test/test_mmap.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -839,7 +840,8 @@ def test_flush_return_value(self):
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'))
Expand Down
10 changes: 7 additions & 3 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -2351,9 +2351,13 @@ def test_chmod(self):

@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):
Expand Down
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit 342e654

Please sign in to comment.