Unverified Kaydet (Commit) 686b4b5f authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) GitHub

bpo-34130: Fix test_signal.test_warn_on_full_buffer() (GH-8327)

On Windows, sometimes test_signal.test_warn_on_full_buffer() fails to
fill the socketpair buffer. In that case, the C signal handler
succeed to write into the socket, it doesn't log the expected send
error, and so the test fail.

On Windows, the test now uses a timeout of 50 ms to fill the
socketpair buffer to fix this race condition.

Other changes:

* Begin with large chunk size to fill the buffer to speed up the
  test.
* Add error messages to assertion errors to more easily identify
  which assertion failed.
* Don't set the read end of the socketpair as non-blocking.
üst 99bb6df6
...@@ -479,26 +479,51 @@ class WakeupSocketSignalTests(unittest.TestCase): ...@@ -479,26 +479,51 @@ class WakeupSocketSignalTests(unittest.TestCase):
signal.signal(signum, handler) signal.signal(signum, handler)
read, write = socket.socketpair() 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: try:
while True: write.send(b"x")
write.send(b"x")
except BlockingIOError: except BlockingIOError:
# The socketpair buffer seems full
pass pass
else:
raise AssertionError("%s bytes failed to fill the socketpair "
"buffer" % written)
# By default, we get a warning when a signal arrives # 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()) signal.set_wakeup_fd(write.fileno())
with captured_stderr() as err: with captured_stderr() as err:
_testcapi.raise_signal(signum) _testcapi.raise_signal(signum)
err = err.getvalue() err = err.getvalue()
if ('Exception ignored when trying to {action} to the signal wakeup fd' if msg not in err:
not in err): raise AssertionError("first set_wakeup_fd() test failed, "
raise AssertionError(err) "stderr: %r" % err)
# And also if warn_on_full_buffer=True # And also if warn_on_full_buffer=True
signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=True) signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=True)
...@@ -507,9 +532,9 @@ class WakeupSocketSignalTests(unittest.TestCase): ...@@ -507,9 +532,9 @@ class WakeupSocketSignalTests(unittest.TestCase):
_testcapi.raise_signal(signum) _testcapi.raise_signal(signum)
err = err.getvalue() err = err.getvalue()
if ('Exception ignored when trying to {action} to the signal wakeup fd' if msg not in err:
not in err): raise AssertionError("set_wakeup_fd(warn_on_full_buffer=True) "
raise AssertionError(err) "test failed, stderr: %r" % err)
# But not if warn_on_full_buffer=False # But not if warn_on_full_buffer=False
signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=False) signal.set_wakeup_fd(write.fileno(), warn_on_full_buffer=False)
...@@ -519,7 +544,8 @@ class WakeupSocketSignalTests(unittest.TestCase): ...@@ -519,7 +544,8 @@ class WakeupSocketSignalTests(unittest.TestCase):
err = err.getvalue() err = err.getvalue()
if err != "": 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 # And then check the default again, to make sure warn_on_full_buffer
# settings don't leak across calls. # settings don't leak across calls.
...@@ -529,9 +555,9 @@ class WakeupSocketSignalTests(unittest.TestCase): ...@@ -529,9 +555,9 @@ class WakeupSocketSignalTests(unittest.TestCase):
_testcapi.raise_signal(signum) _testcapi.raise_signal(signum)
err = err.getvalue() err = err.getvalue()
if ('Exception ignored when trying to {action} to the signal wakeup fd' if msg not in err:
not in err): raise AssertionError("second set_wakeup_fd() test failed, "
raise AssertionError(err) "stderr: %r" % err)
""".format(action=action) """.format(action=action)
assert_python_ok('-c', code) assert_python_ok('-c', code)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment