]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-104280: Add test cases for DTrace probes (GH-107125) (#107492)
authorŁukasz Langa <lukasz@langa.pl>
Mon, 31 Jul 2023 09:40:20 +0000 (09:40 +0000)
committerGitHub <noreply@github.com>
Mon, 31 Jul 2023 09:40:20 +0000 (11:40 +0200)
(cherry picked from commit a1c737b73d3658be0e1d072a340d42e3d96373c6)

Co-authored-by: Furkan Onder <furkanonder@protonmail.com>
Lib/test/test_dtrace.py

index 4b971deacc1a5c28a2ef3390c4e04b5b5deaf32d..092a050fd1d976f9067e699ecc9bf31ac4895b71 100644 (file)
@@ -3,6 +3,7 @@ import os.path
 import re
 import subprocess
 import sys
+import sysconfig
 import types
 import unittest
 
@@ -173,6 +174,75 @@ class SystemTapOptimizedTests(TraceTests, unittest.TestCase):
     backend = SystemTapBackend()
     optimize_python = 2
 
+class CheckDtraceProbes(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        if sysconfig.get_config_var('WITH_DTRACE'):
+            readelf_major_version, readelf_minor_version = cls.get_readelf_version()
+            if support.verbose:
+                print(f"readelf version: {readelf_major_version}.{readelf_minor_version}")
+        else:
+            raise unittest.SkipTest("CPython must be configured with the --with-dtrace option.")
+
+
+    @staticmethod
+    def get_readelf_version():
+        try:
+            cmd = ["readelf", "--version"]
+            proc = subprocess.Popen(
+                cmd,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE,
+                universal_newlines=True,
+            )
+            with proc:
+                version, stderr = proc.communicate()
+
+            if proc.returncode:
+                raise Exception(
+                    f"Command {' '.join(cmd)!r} failed "
+                    f"with exit code {proc.returncode}: "
+                    f"stdout={version!r} stderr={stderr!r}"
+                )
+        except OSError:
+            raise unittest.SkipTest("Couldn't find readelf on the path")
+
+        # Regex to parse:
+        # 'GNU readelf (GNU Binutils) 2.40.0\n' -> 2.40
+        match = re.search(r"^(?:GNU) readelf.*?\b(\d+)\.(\d+)", version)
+        if match is None:
+            raise unittest.SkipTest(f"Unable to parse readelf version: {version}")
+
+        return int(match.group(1)), int(match.group(2))
+
+    def get_readelf_output(self):
+        command = ["readelf", "-n", sys.executable]
+        stdout, _ = subprocess.Popen(
+            command,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT,
+            universal_newlines=True,
+        ).communicate()
+        return stdout
+
+    def test_check_probes(self):
+        readelf_output = self.get_readelf_output()
+
+        available_probe_names = [
+            "Name: import__find__load__done",
+            "Name: import__find__load__start",
+            "Name: audit",
+            "Name: gc__start",
+            "Name: gc__done",
+            "Name: function__entry",
+            "Name: function__return",
+            "Name: line",
+        ]
+
+        for probe_name in available_probe_names:
+            with self.subTest(probe_name=probe_name):
+                self.assertIn(probe_name, readelf_output)
+
 
 if __name__ == '__main__':
     unittest.main()