@@ -182,15 +182,35 @@ def test_sock_recv(self):
182182
183183 f = self .loop .sock_recv (sock , 1024 )
184184 self .assertIsInstance (f , asyncio .Future )
185- self .loop ._sock_recv .assert_called_with (f , False , sock , 1024 )
185+ self .loop ._sock_recv .assert_called_with (f , None , sock , 1024 )
186+
187+ def test_sock_recv_reconnection (self ):
188+ sock = mock .Mock ()
189+ sock .fileno .return_value = 10
190+ sock .recv .side_effect = BlockingIOError
191+
192+ self .loop .add_reader = mock .Mock ()
193+ self .loop .remove_reader = mock .Mock ()
194+ fut = self .loop .sock_recv (sock , 1024 )
195+ callback = self .loop .add_reader .call_args [0 ][1 ]
196+ params = self .loop .add_reader .call_args [0 ][2 :]
197+
198+ # emulate the old socket has closed, but the new one has
199+ # the same fileno, so callback is called with old (closed) socket
200+ sock .fileno .return_value = - 1
201+ sock .recv .side_effect = OSError (9 )
202+ callback (* params )
203+
204+ self .assertIsInstance (fut .exception (), OSError )
205+ self .assertEqual ((10 ,), self .loop .remove_reader .call_args [0 ])
186206
187207 def test__sock_recv_canceled_fut (self ):
188208 sock = mock .Mock ()
189209
190210 f = asyncio .Future (loop = self .loop )
191211 f .cancel ()
192212
193- self .loop ._sock_recv (f , False , sock , 1024 )
213+ self .loop ._sock_recv (f , None , sock , 1024 )
194214 self .assertFalse (sock .recv .called )
195215
196216 def test__sock_recv_unregister (self ):
@@ -201,7 +221,7 @@ def test__sock_recv_unregister(self):
201221 f .cancel ()
202222
203223 self .loop .remove_reader = mock .Mock ()
204- self .loop ._sock_recv (f , True , sock , 1024 )
224+ self .loop ._sock_recv (f , 10 , sock , 1024 )
205225 self .assertEqual ((10 ,), self .loop .remove_reader .call_args [0 ])
206226
207227 def test__sock_recv_tryagain (self ):
@@ -211,8 +231,8 @@ def test__sock_recv_tryagain(self):
211231 sock .recv .side_effect = BlockingIOError
212232
213233 self .loop .add_reader = mock .Mock ()
214- self .loop ._sock_recv (f , False , sock , 1024 )
215- self .assertEqual ((10 , self .loop ._sock_recv , f , True , sock , 1024 ),
234+ self .loop ._sock_recv (f , None , sock , 1024 )
235+ self .assertEqual ((10 , self .loop ._sock_recv , f , 10 , sock , 1024 ),
216236 self .loop .add_reader .call_args [0 ])
217237
218238 def test__sock_recv_exception (self ):
@@ -221,7 +241,7 @@ def test__sock_recv_exception(self):
221241 sock .fileno .return_value = 10
222242 err = sock .recv .side_effect = OSError ()
223243
224- self .loop ._sock_recv (f , False , sock , 1024 )
244+ self .loop ._sock_recv (f , None , sock , 1024 )
225245 self .assertIs (err , f .exception ())
226246
227247 def test_sock_sendall (self ):
@@ -231,7 +251,7 @@ def test_sock_sendall(self):
231251 f = self .loop .sock_sendall (sock , b'data' )
232252 self .assertIsInstance (f , asyncio .Future )
233253 self .assertEqual (
234- (f , False , sock , b'data' ),
254+ (f , None , sock , b'data' ),
235255 self .loop ._sock_sendall .call_args [0 ])
236256
237257 def test_sock_sendall_nodata (self ):
@@ -244,13 +264,33 @@ def test_sock_sendall_nodata(self):
244264 self .assertIsNone (f .result ())
245265 self .assertFalse (self .loop ._sock_sendall .called )
246266
267+ def test_sock_sendall_reconnection (self ):
268+ sock = mock .Mock ()
269+ sock .fileno .return_value = 10
270+ sock .send .side_effect = BlockingIOError
271+
272+ self .loop .add_writer = mock .Mock ()
273+ self .loop .remove_writer = mock .Mock ()
274+ fut = self .loop .sock_sendall (sock , b'data' )
275+ callback = self .loop .add_writer .call_args [0 ][1 ]
276+ params = self .loop .add_writer .call_args [0 ][2 :]
277+
278+ # emulate the old socket has closed, but the new one has
279+ # the same fileno, so callback is called with old (closed) socket
280+ sock .fileno .return_value = - 1
281+ sock .send .side_effect = OSError (9 )
282+ callback (* params )
283+
284+ self .assertIsInstance (fut .exception (), OSError )
285+ self .assertEqual ((10 ,), self .loop .remove_writer .call_args [0 ])
286+
247287 def test__sock_sendall_canceled_fut (self ):
248288 sock = mock .Mock ()
249289
250290 f = asyncio .Future (loop = self .loop )
251291 f .cancel ()
252292
253- self .loop ._sock_sendall (f , False , sock , b'data' )
293+ self .loop ._sock_sendall (f , None , sock , b'data' )
254294 self .assertFalse (sock .send .called )
255295
256296 def test__sock_sendall_unregister (self ):
@@ -261,7 +301,7 @@ def test__sock_sendall_unregister(self):
261301 f .cancel ()
262302
263303 self .loop .remove_writer = mock .Mock ()
264- self .loop ._sock_sendall (f , True , sock , b'data' )
304+ self .loop ._sock_sendall (f , 10 , sock , b'data' )
265305 self .assertEqual ((10 ,), self .loop .remove_writer .call_args [0 ])
266306
267307 def test__sock_sendall_tryagain (self ):
@@ -271,9 +311,9 @@ def test__sock_sendall_tryagain(self):
271311 sock .send .side_effect = BlockingIOError
272312
273313 self .loop .add_writer = mock .Mock ()
274- self .loop ._sock_sendall (f , False , sock , b'data' )
314+ self .loop ._sock_sendall (f , None , sock , b'data' )
275315 self .assertEqual (
276- (10 , self .loop ._sock_sendall , f , True , sock , b'data' ),
316+ (10 , self .loop ._sock_sendall , f , 10 , sock , b'data' ),
277317 self .loop .add_writer .call_args [0 ])
278318
279319 def test__sock_sendall_interrupted (self ):
@@ -283,9 +323,9 @@ def test__sock_sendall_interrupted(self):
283323 sock .send .side_effect = InterruptedError
284324
285325 self .loop .add_writer = mock .Mock ()
286- self .loop ._sock_sendall (f , False , sock , b'data' )
326+ self .loop ._sock_sendall (f , None , sock , b'data' )
287327 self .assertEqual (
288- (10 , self .loop ._sock_sendall , f , True , sock , b'data' ),
328+ (10 , self .loop ._sock_sendall , f , 10 , sock , b'data' ),
289329 self .loop .add_writer .call_args [0 ])
290330
291331 def test__sock_sendall_exception (self ):
@@ -294,7 +334,7 @@ def test__sock_sendall_exception(self):
294334 sock .fileno .return_value = 10
295335 err = sock .send .side_effect = OSError ()
296336
297- self .loop ._sock_sendall (f , False , sock , b'data' )
337+ self .loop ._sock_sendall (f , None , sock , b'data' )
298338 self .assertIs (f .exception (), err )
299339
300340 def test__sock_sendall (self ):
@@ -304,7 +344,7 @@ def test__sock_sendall(self):
304344 sock .fileno .return_value = 10
305345 sock .send .return_value = 4
306346
307- self .loop ._sock_sendall (f , False , sock , b'data' )
347+ self .loop ._sock_sendall (f , None , sock , b'data' )
308348 self .assertTrue (f .done ())
309349 self .assertIsNone (f .result ())
310350
@@ -316,10 +356,10 @@ def test__sock_sendall_partial(self):
316356 sock .send .return_value = 2
317357
318358 self .loop .add_writer = mock .Mock ()
319- self .loop ._sock_sendall (f , False , sock , b'data' )
359+ self .loop ._sock_sendall (f , None , sock , b'data' )
320360 self .assertFalse (f .done ())
321361 self .assertEqual (
322- (10 , self .loop ._sock_sendall , f , True , sock , b'ta' ),
362+ (10 , self .loop ._sock_sendall , f , 10 , sock , b'ta' ),
323363 self .loop .add_writer .call_args [0 ])
324364
325365 def test__sock_sendall_none (self ):
@@ -330,10 +370,10 @@ def test__sock_sendall_none(self):
330370 sock .send .return_value = 0
331371
332372 self .loop .add_writer = mock .Mock ()
333- self .loop ._sock_sendall (f , False , sock , b'data' )
373+ self .loop ._sock_sendall (f , None , sock , b'data' )
334374 self .assertFalse (f .done ())
335375 self .assertEqual (
336- (10 , self .loop ._sock_sendall , f , True , sock , b'data' ),
376+ (10 , self .loop ._sock_sendall , f , 10 , sock , b'data' ),
337377 self .loop .add_writer .call_args [0 ])
338378
339379 def test_sock_connect_timeout (self ):
0 commit comments