• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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