https://github.com/python/cpython/commit/46f8a7bbdbb02cafaa00f7bb9478d3d27affc57a
commit: 46f8a7bbdbb02cafaa00f7bb9478d3d27affc57a
branch: main
author: Cody Maloney <cmalo...@users.noreply.github.com>
committer: vstinner <vstin...@python.org>
date: 2024-11-22T15:55:32+01:00
summary:

gh-127076: Ignore memory mmap in FileIO testing (#127088)

`mmap`, `munmap`, and `mprotect` are used by CPython for memory
management, which may occur in the middle of the FileIO tests. The
system calls can also be used with files, so `strace` includes them
in its `%file` and `%desc` filters.

Filter out the `mmap` system calls related to memory allocation for the
file tests. Currently FileIO doesn't do `mmap` at all, so didn't add
code to track from `mmap` through `munmap` since it wouldn't be used.
For now if an `mmap` on a fd happens, the call will be included (which
may cause test to fail), and at that time support for tracking the
address throug `munmap` could be added.

files:
A Misc/NEWS.d/next/Tests/2024-11-20-18-49-01.gh-issue-127076.DHnXxo.rst
M Lib/test/support/strace_helper.py
M Lib/test/test_fileio.py

diff --git a/Lib/test/support/strace_helper.py 
b/Lib/test/support/strace_helper.py
index 90281b47274299..eab16ea3e2889f 100644
--- a/Lib/test/support/strace_helper.py
+++ b/Lib/test/support/strace_helper.py
@@ -71,6 +71,27 @@ def sections(self):
 
         return sections
 
+def _filter_memory_call(call):
+    # mmap can operate on a fd or "MAP_ANONYMOUS" which gives a block of 
memory.
+    # Ignore "MAP_ANONYMOUS + the "MAP_ANON" alias.
+    if call.syscall == "mmap" and "MAP_ANON" in call.args[3]:
+        return True
+
+    if call.syscall in ("munmap", "mprotect"):
+        return True
+
+    return False
+
+
+def filter_memory(syscalls):
+    """Filter out memory allocation calls from File I/O calls.
+
+    Some calls (mmap, munmap, etc) can be used on files or to just get a block
+    of memory. Use this function to filter out the memory related calls from
+    other calls."""
+
+    return [call for call in syscalls if not _filter_memory_call(call)]
+
 
 @support.requires_subprocess()
 def strace_python(code, strace_flags, check=True):
@@ -93,8 +114,6 @@ def _make_error(reason, details):
             "-c",
             textwrap.dedent(code),
             __run_using_command=[_strace_binary] + strace_flags,
-            # Don't want to trace our JIT's own mmap and mprotect calls:
-            PYTHON_JIT="0",
         )
     except OSError as err:
         return _make_error("Caught OSError", err)
@@ -145,9 +164,14 @@ def get_events(code, strace_flags, prelude, cleanup):
     return all_sections['code']
 
 
-def get_syscalls(code, strace_flags, prelude="", cleanup=""):
+def get_syscalls(code, strace_flags, prelude="", cleanup="",
+                 ignore_memory=True):
     """Get the syscalls which a given chunk of python code generates"""
     events = get_events(code, strace_flags, prelude=prelude, cleanup=cleanup)
+
+    if ignore_memory:
+        events = filter_memory(events)
+
     return [ev.syscall for ev in events]
 
 
@@ -177,5 +201,5 @@ def requires_strace():
     return unittest.skipUnless(_can_strace(), "Requires working strace")
 
 
-__all__ = ["get_events", "get_syscalls", "requires_strace", "strace_python",
-           "StraceEvent", "StraceResult"]
+__all__ = ["filter_memory", "get_events", "get_syscalls", "requires_strace",
+           "strace_python", "StraceEvent", "StraceResult"]
diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
index d60aabcdf1ae22..e681417e15d34b 100644
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -364,8 +364,7 @@ def testErrnoOnClosedReadinto(self, f):
 
     @strace_helper.requires_strace()
     def test_syscalls_read(self):
-        """Check that the set of system calls produced by the I/O stack is what
-        is expected for various read cases.
+        """Check set of system calls during common I/O patterns
 
         It's expected as bits of the I/O implementation change, this will need
         to change. The goal is to catch changes that unintentionally add
@@ -383,6 +382,11 @@ def check_readall(name, code, prelude="", cleanup="",
                                                       prelude=prelude,
                                                       cleanup=cleanup)
 
+                # Some system calls (ex. mmap) can be used for both File I/O 
and
+                # memory allocation. Filter out the ones used for memory
+                # allocation.
+                syscalls = strace_helper.filter_memory(syscalls)
+
                 # The first call should be an open that returns a
                 # file descriptor (fd). Afer that calls may vary. Once the file
                 # is opened, check calls refer to it by fd as the filename
diff --git 
a/Misc/NEWS.d/next/Tests/2024-11-20-18-49-01.gh-issue-127076.DHnXxo.rst 
b/Misc/NEWS.d/next/Tests/2024-11-20-18-49-01.gh-issue-127076.DHnXxo.rst
new file mode 100644
index 00000000000000..39323604bbef56
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2024-11-20-18-49-01.gh-issue-127076.DHnXxo.rst
@@ -0,0 +1,2 @@
+Filter out memory-related ``mmap``, ``munmap``, and ``mprotect``  calls from
+file-related ones when testing :mod:`io` behavior using strace.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to