Skip to content

Commit 41ca93f

Browse files
vstinnerkulikjak
andauthored
[3.14] gh-98894: Fix test_dtrace on Solaris (#154803) (#159605)
gh-98894: Fix test_dtrace on Solaris (#154803) Fix 'CheckDtraceProbes' tests by reading available probes from the test process itself. (cherry picked from commit 967fb3a) Co-authored-by: Jakub Kulík <Kulikjak@gmail.com>
1 parent 13fc16c commit 41ca93f

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
@@ -107,7 +107,7 @@ def terminate_process_group(proc):
107107
proc.communicate(timeout=TERMINATE_TIMEOUT) # Clean up
108108

109109

110-
def run_readelf(cmd):
110+
def run_command(cmd):
111111
# Force the C locale to disable localization.
112112
env = dict(os.environ, LC_ALL="C")
113113
try:
@@ -119,7 +119,7 @@ def run_readelf(cmd):
119119
env=env,
120120
)
121121
except OSError:
122-
raise unittest.SkipTest("Couldn't find readelf on the path")
122+
raise unittest.SkipTest(f"Couldn't find {cmd[0]!r} on the path")
123123

124124
with proc:
125125
stdout, stderr = proc.communicate()
@@ -340,14 +340,20 @@ class SystemTapOptimizedTests(TraceTests, unittest.TestCase):
340340
class CheckDtraceProbes(unittest.TestCase):
341341
@classmethod
342342
def setUpClass(cls):
343+
if sys.platform == "sunos5":
344+
# Solaris does not expose available probes through readable ELF
345+
# section; it uses DTrace itself instead.
346+
DTraceBackend().assert_usable()
347+
return
348+
343349
readelf_major_version, readelf_minor_version = cls.get_readelf_version()
344350
if support.verbose:
345351
print(f"readelf version: {readelf_major_version}.{readelf_minor_version}")
346352

347353

348354
@staticmethod
349355
def get_readelf_version():
350-
version = run_readelf(["readelf", "--version"])
356+
version = run_command(["readelf", "--version"])
351357

352358
# Regex to parse:
353359
# 'GNU readelf (GNU Binutils) 2.40.0\n' -> 2.40
@@ -357,38 +363,50 @@ def get_readelf_version():
357363

358364
return int(match.group(1)), int(match.group(2))
359365

360-
def get_readelf_output(self):
361-
return run_readelf(["readelf", "-n", get_probe_binary()])
366+
def get_probe_output(self):
367+
if sys.platform == "sunos5":
368+
# Get probes available in this process.
369+
return run_command(
370+
["dtrace", "-l", "-P", f"python{os.getpid()}"]
371+
)
372+
373+
return run_command(["readelf", "-n", get_probe_binary()])
374+
375+
def assert_probe_present(self, probe_name, output):
376+
if sys.platform == "sunos5":
377+
self.assertIn(probe_name.replace("__", "-"), output)
378+
else:
379+
self.assertIn(f"Name: {probe_name}", output)
362380

363381
def test_check_probes(self):
364-
readelf_output = self.get_readelf_output()
382+
probe_output = self.get_probe_output()
365383

366384
available_probe_names = [
367-
"Name: import__find__load__done",
368-
"Name: import__find__load__start",
369-
"Name: audit",
370-
"Name: gc__start",
371-
"Name: gc__done",
385+
"import__find__load__done",
386+
"import__find__load__start",
387+
"audit",
388+
"gc__start",
389+
"gc__done",
372390
]
373391

374392
for probe_name in available_probe_names:
375393
with self.subTest(probe_name=probe_name):
376-
self.assertIn(probe_name, readelf_output)
394+
self.assert_probe_present(probe_name, probe_output)
377395

378396
@unittest.expectedFailure
379397
def test_missing_probes(self):
380-
readelf_output = self.get_readelf_output()
398+
probe_output = self.get_probe_output()
381399

382400
# Missing probes will be added in the future.
383401
missing_probe_names = [
384-
"Name: function__entry",
385-
"Name: function__return",
386-
"Name: line",
402+
"function__entry",
403+
"function__return",
404+
"line",
387405
]
388406

389407
for probe_name in missing_probe_names:
390408
with self.subTest(probe_name=probe_name):
391-
self.assertIn(probe_name, readelf_output)
409+
self.assert_probe_present(probe_name, probe_output)
392410

393411

394412
if __name__ == '__main__':

0 commit comments

Comments
 (0)