From 5462939fc6cd6b6b2d36c5c9ff41a550caebe038 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 23 Aug 2023 12:54:14 +0200 Subject: [PATCH 1/5] test_audit: Consolidate subprocess helpers These did nearly the same thing... --- Lib/test/test_audit.py | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 3a15835917cc32..eac967ec33c7b8 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -19,7 +19,7 @@ class AuditTest(unittest.TestCase): maxDiff = None @support.requires_subprocess() - def do_test(self, *args): + def run_test_in_subprocess(self, *args): with subprocess.Popen( [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], encoding="utf-8", @@ -27,27 +27,26 @@ def do_test(self, *args): stderr=subprocess.PIPE, ) as p: p.wait() - sys.stdout.writelines(p.stdout) - sys.stderr.writelines(p.stderr) - if p.returncode: - self.fail("".join(p.stderr)) + return p, p.stdout.read(), p.stderr.read() - @support.requires_subprocess() - def run_python(self, *args): + def do_test(self, *args): + proc, stdout, stderr = self.run_test_in_subprocess(*args) + + sys.stdout.write(stdout) + sys.stderr.write(stderr) + if proc.returncode: + self.fail(stderr) + + def run_python(self, *args, expect_stderr=False): events = [] - with subprocess.Popen( - [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], - encoding="utf-8", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) as p: - p.wait() - sys.stderr.writelines(p.stderr) - return ( - p.returncode, - [line.strip().partition(" ") for line in p.stdout], - "".join(p.stderr), - ) + proc, stdout, stderr = self.run_test_in_subprocess(*args) + if not expect_stderr or support.verbose: + sys.stderr.writelines(stderr) + return ( + proc.returncode, + [line.strip().partition(" ") for line in stdout.splitlines()], + stderr, + ) def test_basic(self): self.do_test("test_basic") From ca8e85ba366bc0f4e127797e33196661e1ca050c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 23 Aug 2023 12:55:46 +0200 Subject: [PATCH 2/5] audit-tests: Pass argv to the test functions --- Lib/test/audit-tests.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index ad8f72f556331d..6eb761bac02e56 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -186,7 +186,7 @@ class C(A): ) -def test_open(): +def test_open(testfn): # SSLContext.load_dh_params uses _Py_fopen_obj rather than normal open() try: import ssl @@ -199,11 +199,11 @@ def test_open(): # All of them should fail with TestHook(raise_on_events={"open"}) as hook: for fn, *args in [ - (open, sys.argv[2], "r"), + (open, testfn, "r"), (open, sys.executable, "rb"), (open, 3, "wb"), - (open, sys.argv[2], "w", -1, None, None, None, False, lambda *a: 1), - (load_dh_params, sys.argv[2]), + (open, testfn, "w", -1, None, None, None, False, lambda *a: 1), + (load_dh_params, testfn), ]: if not fn: continue @@ -216,11 +216,11 @@ def test_open(): [ i for i in [ - (sys.argv[2], "r"), + (testfn, "r"), (sys.executable, "r"), (3, "w"), - (sys.argv[2], "w"), - (sys.argv[2], "rb") if load_dh_params else None, + (testfn, "w"), + (testfn, "rb") if load_dh_params else None, ] if i is not None ], @@ -549,4 +549,4 @@ def hook(event, args): suppress_msvcrt_asserts() test = sys.argv[1] - globals()[test]() + globals()[test](*sys.argv[2:]) From c9435a42021235df5b880f23cb3851079345ebfc Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 23 Aug 2023 11:48:48 +0200 Subject: [PATCH 3/5] Add error handling for time.sleep audit event --- Modules/timemodule.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 68948b6be1a61a..9cd10d4afea852 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -414,7 +414,9 @@ Return the clk_id of a thread's CPU time clock."); static PyObject * time_sleep(PyObject *self, PyObject *timeout_obj) { - PySys_Audit("time.sleep", "O", timeout_obj); + if (PySys_Audit("time.sleep", "O", timeout_obj) < 0) { + return NULL; + } _PyTime_t timeout; if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) From 50ace251b3dec00bd469ef4afe68d62461f04196 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 23 Aug 2023 12:57:05 +0200 Subject: [PATCH 4/5] test_audit: Test "time.sleep" hook raising an exception --- Lib/test/audit-tests.py | 7 +++++-- Lib/test/test_audit.py | 7 ++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index 6eb761bac02e56..a010781996a5aa 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -517,12 +517,15 @@ def test_not_in_gc(): assert hook not in o -def test_time(): +def test_time(mode): import time def hook(event, args): if event.startswith("time."): - print(event, *args) + if mode == 'print': + print(event, *args) + elif mode == 'fail': + raise AssertionError('hook failed') sys.addaudithook(hook) time.sleep(0) diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index eac967ec33c7b8..ee5b8e8a864746 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -256,7 +256,7 @@ def test_not_in_gc(self): self.fail(stderr) def test_time(self): - returncode, events, stderr = self.run_python("test_time") + returncode, events, stderr = self.run_python("test_time", "print") if returncode: self.fail(stderr) @@ -270,6 +270,11 @@ def test_time(self): self.assertEqual(actual, expected) + def test_time_fail(self): + returncode, events, stderr = self.run_python("test_time", "fail", + expect_stderr=True) + self.assertNotEqual(returncode, 0) + self.assertIn('hook failed', stderr.splitlines()[-1]) def test_sys_monitoring_register_callback(self): returncode, events, stderr = self.run_python("test_sys_monitoring_register_callback") From 4e0cf3138f4936a5b92cdcb11c571c2bfa6b9881 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 24 Aug 2023 11:37:29 +0200 Subject: [PATCH 5/5] Write stderr properly in verbose mode --- Lib/test/test_audit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index ee5b8e8a864746..47e5832d311bd1 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -41,7 +41,7 @@ def run_python(self, *args, expect_stderr=False): events = [] proc, stdout, stderr = self.run_test_in_subprocess(*args) if not expect_stderr or support.verbose: - sys.stderr.writelines(stderr) + sys.stderr.write(stderr) return ( proc.returncode, [line.strip().partition(" ") for line in stdout.splitlines()],