@@ -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):
340340class 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
394412if __name__ == '__main__' :
0 commit comments