summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2018-07-18 16:29:54 (GMT)
committerGitHub <noreply@github.com>2018-07-18 16:29:54 (GMT)
commit686b4b5ff219ed66714f3b811815776dafadc23b (patch)
tree9516e763de1fe17521370710994ec8b11eadf824
parent99bb6df66a42625367c4f38e6802c8bb527baf4a (diff)
downloadcpython-686b4b5ff219ed66714f3b811815776dafadc23b.zip
cpython-686b4b5ff219ed66714f3b811815776dafadc23b.tar.gz
cpython-686b4b5ff219ed66714f3b811815776dafadc23b.tar.bz2
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.
-rw-r--r--Lib/test/test_signal.py56
1 files changed, 41 insertions, 15 deletions
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index e69db79..ecdffa6 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -479,26 +479,51 @@ class WakeupSocketSignalTests(unittest.TestCase):
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)
@@ -507,9 +532,9 @@ class WakeupSocketSignalTests(unittest.TestCase):
_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)
@@ -519,7 +544,8 @@ class WakeupSocketSignalTests(unittest.TestCase):
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.
@@ -529,9 +555,9 @@ class WakeupSocketSignalTests(unittest.TestCase):
_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)