Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ca023ca

Browse files
committed
Issue #1677694: Refactor and improve test_timeout. Original patch by
Björn Lindqvist.
1 parent d53dfa3 commit ca023ca

2 files changed

Lines changed: 57 additions & 56 deletions

File tree

Lib/test/test_timeout.py

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
skip_expected = not support.is_resource_enabled('network')
88

99
import time
10+
import errno
1011
import socket
1112

1213

@@ -101,8 +102,29 @@ class TimeoutTestCase(unittest.TestCase):
101102
def setUp(self):
102103
raise NotImplementedError()
103104

104-
def tearDown(self):
105-
self.sock.close()
105+
tearDown = setUp
106+
107+
def _sock_operation(self, count, timeout, method, *args):
108+
"""
109+
Test the specified socket method.
110+
111+
The method is run at most `count` times and must raise a socket.timeout
112+
within `timeout` + self.fuzz seconds.
113+
"""
114+
self.sock.settimeout(timeout)
115+
method = getattr(self.sock, method)
116+
for i in range(count):
117+
t1 = time.time()
118+
try:
119+
method(*args)
120+
except socket.timeout as e:
121+
delta = time.time() - t1
122+
break
123+
else:
124+
self.fail('socket.timeout was not raised')
125+
# These checks should account for timing unprecision
126+
self.assertLess(delta, timeout + self.fuzz)
127+
self.assertGreater(delta, timeout - 1.0)
106128

107129

108130
class TCPTimeoutTestCase(TimeoutTestCase):
@@ -112,75 +134,58 @@ def setUp(self):
112134
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
113135
self.addr_remote = ('www.python.org.', 80)
114136

137+
def tearDown(self):
138+
self.sock.close()
139+
115140
def testConnectTimeout(self):
116141
# Choose a private address that is unlikely to exist to prevent
117142
# failures due to the connect succeeding before the timeout.
118143
# Use a dotted IP address to avoid including the DNS lookup time
119144
# with the connect time. This avoids failing the assertion that
120145
# the timeout occurred fast enough.
121146
addr = ('10.0.0.0', 12345)
122-
123-
# Test connect() timeout
124-
_timeout = 0.001
125-
self.sock.settimeout(_timeout)
126-
127-
_t1 = time.time()
128-
self.assertRaises(socket.error, self.sock.connect, addr)
129-
_t2 = time.time()
130-
131-
_delta = abs(_t1 - _t2)
132-
self.assertTrue(_delta < _timeout + self.fuzz,
133-
"timeout (%g) is more than %g seconds more than expected (%g)"
134-
%(_delta, self.fuzz, _timeout))
147+
with support.transient_internet(addr[0]):
148+
self._sock_operation(1, 0.001, 'connect', addr)
135149

136150
def testRecvTimeout(self):
137151
# Test recv() timeout
138-
_timeout = 0.02
139-
140152
with support.transient_internet(self.addr_remote[0]):
141153
self.sock.connect(self.addr_remote)
142-
self.sock.settimeout(_timeout)
143-
144-
_t1 = time.time()
145-
self.assertRaises(socket.timeout, self.sock.recv, 1024)
146-
_t2 = time.time()
147-
148-
_delta = abs(_t1 - _t2)
149-
self.assertTrue(_delta < _timeout + self.fuzz,
150-
"timeout (%g) is %g seconds more than expected (%g)"
151-
%(_delta, self.fuzz, _timeout))
154+
self._sock_operation(1, 1.5, 'recv', 1024)
152155

153156
def testAcceptTimeout(self):
154157
# Test accept() timeout
155-
_timeout = 2
156-
self.sock.settimeout(_timeout)
157-
# Prevent "Address already in use" socket exceptions
158158
support.bind_port(self.sock, self.localhost)
159159
self.sock.listen(5)
160-
161-
_t1 = time.time()
162-
self.assertRaises(socket.error, self.sock.accept)
163-
_t2 = time.time()
164-
165-
_delta = abs(_t1 - _t2)
166-
self.assertTrue(_delta < _timeout + self.fuzz,
167-
"timeout (%g) is %g seconds more than expected (%g)"
168-
%(_delta, self.fuzz, _timeout))
160+
self._sock_operation(1, 1.5, 'accept')
169161

170162
def testSend(self):
171163
# Test send() timeout
172-
# couldn't figure out how to test it
173-
pass
164+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serv:
165+
support.bind_port(serv, self.localhost)
166+
serv.listen(5)
167+
self.sock.connect(serv.getsockname())
168+
# Send a lot of data in order to bypass buffering in the TCP stack.
169+
self._sock_operation(100, 1.5, 'send', b"X" * 200000)
174170

175171
def testSendto(self):
176172
# Test sendto() timeout
177-
# couldn't figure out how to test it
178-
pass
173+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serv:
174+
support.bind_port(serv, self.localhost)
175+
serv.listen(5)
176+
self.sock.connect(serv.getsockname())
177+
# The address argument is ignored since we already connected.
178+
self._sock_operation(100, 1.5, 'sendto', b"X" * 200000,
179+
serv.getsockname())
179180

180181
def testSendall(self):
181182
# Test sendall() timeout
182-
# couldn't figure out how to test it
183-
pass
183+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serv:
184+
support.bind_port(serv, self.localhost)
185+
serv.listen(5)
186+
self.sock.connect(serv.getsockname())
187+
# Send a lot of data in order to bypass buffering in the TCP stack.
188+
self._sock_operation(100, 1.5, 'sendall', b"X" * 200000)
184189

185190

186191
class UDPTimeoutTestCase(TimeoutTestCase):
@@ -189,21 +194,14 @@ class UDPTimeoutTestCase(TimeoutTestCase):
189194
def setUp(self):
190195
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
191196

197+
def tearDown(self):
198+
self.sock.close()
199+
192200
def testRecvfromTimeout(self):
193201
# Test recvfrom() timeout
194-
_timeout = 2
195-
self.sock.settimeout(_timeout)
196202
# Prevent "Address already in use" socket exceptions
197203
support.bind_port(self.sock, self.localhost)
198-
199-
_t1 = time.time()
200-
self.assertRaises(socket.error, self.sock.recvfrom, 8192)
201-
_t2 = time.time()
202-
203-
_delta = abs(_t1 - _t2)
204-
self.assertTrue(_delta < _timeout + self.fuzz,
205-
"timeout (%g) is %g seconds more than expected (%g)"
206-
%(_delta, self.fuzz, _timeout))
204+
self._sock_operation(1, 1.5, 'recvfrom', 1024)
207205

208206

209207
def test_main():

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ Tools/Demos
159159
Tests
160160
-----
161161

162+
- Issue #1677694: Refactor and improve test_timeout. Original patch by
163+
Björn Lindqvist.
164+
162165
- Issue #5485: Add tests for the UseForeignDTD method of expat parser objects.
163166
Patch by Jean-Paul Calderone and Sandro Tosi.
164167

0 commit comments

Comments
 (0)