1"""Tests for sys.audit and sys.addaudithook 2""" 3 4import subprocess 5import sys 6import unittest 7from test import support 8 9if not hasattr(sys, "addaudithook") or not hasattr(sys, "audit"): 10 raise unittest.SkipTest("test only relevant when sys.audit is available") 11 12AUDIT_TESTS_PY = support.findfile("audit-tests.py") 13 14 15class AuditTest(unittest.TestCase): 16 def do_test(self, *args): 17 with subprocess.Popen( 18 [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], 19 encoding="utf-8", 20 stdout=subprocess.PIPE, 21 stderr=subprocess.PIPE, 22 ) as p: 23 p.wait() 24 sys.stdout.writelines(p.stdout) 25 sys.stderr.writelines(p.stderr) 26 if p.returncode: 27 self.fail("".join(p.stderr)) 28 29 def run_python(self, *args): 30 events = [] 31 with subprocess.Popen( 32 [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], 33 encoding="utf-8", 34 stdout=subprocess.PIPE, 35 stderr=subprocess.PIPE, 36 ) as p: 37 p.wait() 38 sys.stderr.writelines(p.stderr) 39 return ( 40 p.returncode, 41 [line.strip().partition(" ") for line in p.stdout], 42 "".join(p.stderr), 43 ) 44 45 def test_basic(self): 46 self.do_test("test_basic") 47 48 def test_block_add_hook(self): 49 self.do_test("test_block_add_hook") 50 51 def test_block_add_hook_baseexception(self): 52 self.do_test("test_block_add_hook_baseexception") 53 54 def test_finalize_hooks(self): 55 returncode, events, stderr = self.run_python("test_finalize_hooks") 56 if stderr: 57 print(stderr, file=sys.stderr) 58 if returncode: 59 self.fail(stderr) 60 61 firstId = events[0][2] 62 self.assertSequenceEqual( 63 [ 64 ("Created", " ", firstId), 65 ("cpython._PySys_ClearAuditHooks", " ", firstId), 66 ], 67 events, 68 ) 69 70 def test_pickle(self): 71 support.import_module("pickle") 72 73 self.do_test("test_pickle") 74 75 def test_monkeypatch(self): 76 self.do_test("test_monkeypatch") 77 78 def test_open(self): 79 self.do_test("test_open", support.TESTFN) 80 81 def test_cantrace(self): 82 self.do_test("test_cantrace") 83 84 def test_mmap(self): 85 self.do_test("test_mmap") 86 87 def test_excepthook(self): 88 returncode, events, stderr = self.run_python("test_excepthook") 89 if not returncode: 90 self.fail(f"Expected fatal exception\n{stderr}") 91 92 self.assertSequenceEqual( 93 [("sys.excepthook", " ", "RuntimeError('fatal-error')")], events 94 ) 95 96 def test_unraisablehook(self): 97 returncode, events, stderr = self.run_python("test_unraisablehook") 98 if returncode: 99 self.fail(stderr) 100 101 self.assertEqual(events[0][0], "sys.unraisablehook") 102 self.assertEqual( 103 events[0][2], 104 "RuntimeError('nonfatal-error') Exception ignored for audit hook test", 105 ) 106 107 def test_winreg(self): 108 support.import_module("winreg") 109 returncode, events, stderr = self.run_python("test_winreg") 110 if returncode: 111 self.fail(stderr) 112 113 self.assertEqual(events[0][0], "winreg.OpenKey") 114 self.assertEqual(events[1][0], "winreg.OpenKey/result") 115 expected = events[1][2] 116 self.assertTrue(expected) 117 self.assertSequenceEqual(["winreg.EnumKey", " ", f"{expected} 0"], events[2]) 118 self.assertSequenceEqual(["winreg.EnumKey", " ", f"{expected} 10000"], events[3]) 119 self.assertSequenceEqual(["winreg.PyHKEY.Detach", " ", expected], events[4]) 120 121 122if __name__ == "__main__": 123 unittest.main() 124