Skip to content

Commit 230649f

Browse files
authored
gh-108294: Add error handling for time.sleep audit event (GH-108363)
I've also cleaned the tests up a bit to make this easier to test.
1 parent 24e9892 commit 230649f

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed

Lib/test/audit-tests.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class C(A):
186186
)
187187

188188

189-
def test_open():
189+
def test_open(testfn):
190190
# SSLContext.load_dh_params uses _Py_fopen_obj rather than normal open()
191191
try:
192192
import ssl
@@ -199,11 +199,11 @@ def test_open():
199199
# All of them should fail
200200
with TestHook(raise_on_events={"open"}) as hook:
201201
for fn, *args in [
202-
(open, sys.argv[2], "r"),
202+
(open, testfn, "r"),
203203
(open, sys.executable, "rb"),
204204
(open, 3, "wb"),
205-
(open, sys.argv[2], "w", -1, None, None, None, False, lambda *a: 1),
206-
(load_dh_params, sys.argv[2]),
205+
(open, testfn, "w", -1, None, None, None, False, lambda *a: 1),
206+
(load_dh_params, testfn),
207207
]:
208208
if not fn:
209209
continue
@@ -216,11 +216,11 @@ def test_open():
216216
[
217217
i
218218
for i in [
219-
(sys.argv[2], "r"),
219+
(testfn, "r"),
220220
(sys.executable, "r"),
221221
(3, "w"),
222-
(sys.argv[2], "w"),
223-
(sys.argv[2], "rb") if load_dh_params else None,
222+
(testfn, "w"),
223+
(testfn, "rb") if load_dh_params else None,
224224
]
225225
if i is not None
226226
],
@@ -517,12 +517,15 @@ def test_not_in_gc():
517517
assert hook not in o
518518

519519

520-
def test_time():
520+
def test_time(mode):
521521
import time
522522

523523
def hook(event, args):
524524
if event.startswith("time."):
525-
print(event, *args)
525+
if mode == 'print':
526+
print(event, *args)
527+
elif mode == 'fail':
528+
raise AssertionError('hook failed')
526529
sys.addaudithook(hook)
527530

528531
time.sleep(0)
@@ -549,4 +552,4 @@ def hook(event, args):
549552
suppress_msvcrt_asserts()
550553

551554
test = sys.argv[1]
552-
globals()[test]()
555+
globals()[test](*sys.argv[2:])

Lib/test/test_audit.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,34 @@ class AuditTest(unittest.TestCase):
1919
maxDiff = None
2020

2121
@support.requires_subprocess()
22-
def do_test(self, *args):
22+
def run_test_in_subprocess(self, *args):
2323
with subprocess.Popen(
2424
[sys.executable, "-X utf8", AUDIT_TESTS_PY, *args],
2525
encoding="utf-8",
2626
stdout=subprocess.PIPE,
2727
stderr=subprocess.PIPE,
2828
) as p:
2929
p.wait()
30-
sys.stdout.writelines(p.stdout)
31-
sys.stderr.writelines(p.stderr)
32-
if p.returncode:
33-
self.fail("".join(p.stderr))
30+
return p, p.stdout.read(), p.stderr.read()
3431

35-
@support.requires_subprocess()
36-
def run_python(self, *args):
32+
def do_test(self, *args):
33+
proc, stdout, stderr = self.run_test_in_subprocess(*args)
34+
35+
sys.stdout.write(stdout)
36+
sys.stderr.write(stderr)
37+
if proc.returncode:
38+
self.fail(stderr)
39+
40+
def run_python(self, *args, expect_stderr=False):
3741
events = []
38-
with subprocess.Popen(
39-
[sys.executable, "-X utf8", AUDIT_TESTS_PY, *args],
40-
encoding="utf-8",
41-
stdout=subprocess.PIPE,
42-
stderr=subprocess.PIPE,
43-
) as p:
44-
p.wait()
45-
sys.stderr.writelines(p.stderr)
46-
return (
47-
p.returncode,
48-
[line.strip().partition(" ") for line in p.stdout],
49-
"".join(p.stderr),
50-
)
42+
proc, stdout, stderr = self.run_test_in_subprocess(*args)
43+
if not expect_stderr or support.verbose:
44+
sys.stderr.write(stderr)
45+
return (
46+
proc.returncode,
47+
[line.strip().partition(" ") for line in stdout.splitlines()],
48+
stderr,
49+
)
5150

5251
def test_basic(self):
5352
self.do_test("test_basic")
@@ -257,7 +256,7 @@ def test_not_in_gc(self):
257256
self.fail(stderr)
258257

259258
def test_time(self):
260-
returncode, events, stderr = self.run_python("test_time")
259+
returncode, events, stderr = self.run_python("test_time", "print")
261260
if returncode:
262261
self.fail(stderr)
263262

@@ -271,6 +270,11 @@ def test_time(self):
271270

272271
self.assertEqual(actual, expected)
273272

273+
def test_time_fail(self):
274+
returncode, events, stderr = self.run_python("test_time", "fail",
275+
expect_stderr=True)
276+
self.assertNotEqual(returncode, 0)
277+
self.assertIn('hook failed', stderr.splitlines()[-1])
274278

275279
def test_sys_monitoring_register_callback(self):
276280
returncode, events, stderr = self.run_python("test_sys_monitoring_register_callback")

Modules/timemodule.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,9 @@ Return the clk_id of a thread's CPU time clock.");
413413
static PyObject *
414414
time_sleep(PyObject *self, PyObject *timeout_obj)
415415
{
416-
PySys_Audit("time.sleep", "O", timeout_obj);
416+
if (PySys_Audit("time.sleep", "O", timeout_obj) < 0) {
417+
return NULL;
418+
}
417419

418420
_PyTime_t timeout;
419421
if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT))

0 commit comments

Comments
 (0)