Skip to content

Commit 967fb3a

Browse files
kulikjakvstinner
andauthored
gh-98894: Fix test_dtrace on Solaris (#154803)
Fix 'CheckDtraceProbes' tests by reading available probes from the test process itself. Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent c84d4b5 commit 967fb3a

1 file changed

Lines changed: 35 additions & 17 deletions

File tree

‎Lib/test/test_dtrace.py‎

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def terminate_process_group(proc):
113113
proc.communicate(timeout=TERMINATE_TIMEOUT) # Clean up
114114

115115

116-
def run_readelf(cmd):
116+
def run_command(cmd):
117117
# Force the C locale to disable localization.
118118
env = dict(os.environ, LC_ALL="C")
119119
try:
@@ -125,7 +125,7 @@ def run_readelf(cmd):
125125
env=env,
126126
)
127127
except OSError:
128-
raise unittest.SkipTest("Couldn't find readelf on the path")
128+
raise unittest.SkipTest(f"Couldn't find {cmd[0]!r} on the path")
129129

130130
with proc:
131131
stdout, stderr = proc.communicate()
@@ -528,14 +528,20 @@ class BPFTraceOptimizedTests(TraceTests, unittest.TestCase):
528528
class CheckDtraceProbes(unittest.TestCase):
529529
@classmethod
530530
def setUpClass(cls):
531+
if sys.platform == "sunos5":
532+
# Solaris does not expose available probes through readable ELF
533+
# section; it uses DTrace itself instead.
534+
DTraceBackend().assert_usable()
535+
return
536+
531537
readelf_major_version, readelf_minor_version = cls.get_readelf_version()
532538
if support.verbose:
533539
print(f"readelf version: {readelf_major_version}.{readelf_minor_version}")
534540

535541

536542
@staticmethod
537543
def get_readelf_version():
538-
version = run_readelf(["readelf", "--version"])
544+
version = run_command(["readelf", "--version"])
539545

540546
# Regex to parse:
541547
# 'GNU readelf (GNU Binutils) 2.40.0\n' -> 2.40
@@ -545,38 +551,50 @@ def get_readelf_version():
545551

546552
return int(match.group(1)), int(match.group(2))
547553

548-
def get_readelf_output(self):
549-
return run_readelf(["readelf", "-n", get_probe_binary()])
554+
def get_probe_output(self):
555+
if sys.platform == "sunos5":
556+
# Get probes available in this process.
557+
return run_command(
558+
["dtrace", "-l", "-P", f"python{os.getpid()}"]
559+
)
560+
561+
return run_command(["readelf", "-n", get_probe_binary()])
562+
563+
def assert_probe_present(self, probe_name, output):
564+
if sys.platform == "sunos5":
565+
self.assertIn(probe_name.replace("__", "-"), output)
566+
else:
567+
self.assertIn(f"Name: {probe_name}", output)
550568

551569
def test_check_probes(self):
552-
readelf_output = self.get_readelf_output()
570+
probe_output = self.get_probe_output()
553571

554572
available_probe_names = [
555-
"Name: import__find__load__done",
556-
"Name: import__find__load__start",
557-
"Name: audit",
558-
"Name: gc__start",
559-
"Name: gc__done",
560-
"Name: function__entry",
561-
"Name: function__return",
573+
"import__find__load__done",
574+
"import__find__load__start",
575+
"audit",
576+
"gc__start",
577+
"gc__done",
578+
"function__entry",
579+
"function__return",
562580
]
563581

564582
for probe_name in available_probe_names:
565583
with self.subTest(probe_name=probe_name):
566-
self.assertIn(probe_name, readelf_output)
584+
self.assert_probe_present(probe_name, probe_output)
567585

568586
@unittest.expectedFailure
569587
def test_missing_probes(self):
570-
readelf_output = self.get_readelf_output()
588+
probe_output = self.get_probe_output()
571589

572590
# Missing probes will be added in the future.
573591
missing_probe_names = [
574-
"Name: line",
592+
"line",
575593
]
576594

577595
for probe_name in missing_probe_names:
578596
with self.subTest(probe_name=probe_name):
579-
self.assertIn(probe_name, readelf_output)
597+
self.assert_probe_present(probe_name, probe_output)
580598

581599

582600
if __name__ == '__main__':

0 commit comments

Comments
 (0)