diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 48b7a392e50..24cab0f89ee 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -367,7 +367,6 @@ def handler(signum, frame): signal.signal(signum, handler) read, write = socket.socketpair() - read.setblocking(False) write.setblocking(False) signal.set_wakeup_fd(write.fileno()) @@ -455,26 +454,51 @@ def handler(signum, frame): signal.signal(signum, handler) read, write = socket.socketpair() - read.setblocking(False) - write.setblocking(False) - # Fill the send buffer + # Fill the socketpair buffer + if sys.platform == 'win32': + # bpo-34130: On Windows, sometimes non-blocking send fails to fill + # the full socketpair buffer, so use a timeout of 50 ms instead. + write.settimeout(0.050) + else: + write.setblocking(False) + + # Start with large chunk size to reduce the + # number of send needed to fill the buffer. + written = 0 + for chunk_size in (2 ** 16, 2 ** 8, 1): + chunk = b"x" * chunk_size + try: + while True: + write.send(chunk) + written += chunk_size + except (BlockingIOError, socket.timeout): + pass + + print(f"%s bytes written into the socketpair" % written, flush=True) + + write.setblocking(False) try: - while True: - write.send(b"x") + write.send(b"x") except BlockingIOError: + # The socketpair buffer seems full pass + else: + raise AssertionError("%s bytes failed to fill the socketpair " + "buffer" % written) # By default, we get a warning when a signal arrives + msg = ('Exception ignored when trying to {action} ' + 'to the signal wakeup fd') signal.set_wakeup_fd(write.fileno()) with captured_stderr() as err: _testcapi.raise_signal(signum) err = err.getvalue() - if ('Exception ignored when trying to {action} to the signal wakeup fd' - not in err): - raise AssertionError(err) + if msg not in err: + raise AssertionError("first set_wakeup_fd() test failed, " + "stderr: %r" % err) # And also if warn_on_full_buffer=True signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=True) @@ -483,9 +507,9 @@ def handler(signum, frame): _testcapi.raise_signal(signum) err = err.getvalue() - if ('Exception ignored when trying to {action} to the signal wakeup fd' - not in err): - raise AssertionError(err) + if msg not in err: + raise AssertionError("set_wakeup_fd(warn_on_full_buffer=True) " + "test failed, stderr: %r" % err) # But not if warn_on_full_buffer=False signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=False) @@ -495,7 +519,8 @@ def handler(signum, frame): err = err.getvalue() if err != "": - raise AssertionError("got unexpected output %r" % (err,)) + raise AssertionError("set_wakeup_fd(warn_on_full_buffer=False) " + "test failed, stderr: %r" % err) # And then check the default again, to make sure warn_on_full_buffer # settings don't leak across calls. @@ -505,9 +530,9 @@ def handler(signum, frame): _testcapi.raise_signal(signum) err = err.getvalue() - if ('Exception ignored when trying to {action} to the signal wakeup fd' - not in err): - raise AssertionError(err) + if msg not in err: + raise AssertionError("second set_wakeup_fd() test failed, " + "stderr: %r" % err) """.format(action=action) assert_python_ok('-c', code)