1
1
"""Tests for selector_events.py"""
2
2
3
- import sys
3
+ import collections
4
4
import selectors
5
5
import socket
6
+ import sys
6
7
import unittest
8
+ from asyncio import selector_events
7
9
from unittest import mock
10
+
8
11
try :
9
12
import ssl
10
13
except ImportError :
11
14
ssl = None
12
15
13
16
import asyncio
14
- from asyncio .selector_events import BaseSelectorEventLoop
15
- from asyncio . selector_events import _SelectorTransport
16
- from asyncio . selector_events import _SelectorSocketTransport
17
- from asyncio . selector_events import _SelectorDatagramTransport
17
+ from asyncio .selector_events import ( BaseSelectorEventLoop ,
18
+ _SelectorDatagramTransport ,
19
+ _SelectorSocketTransport ,
20
+ _SelectorTransport )
18
21
from test .test_asyncio import utils as test_utils
19
22
20
-
21
23
MOCK_ANY = mock .ANY
22
24
23
25
@@ -37,7 +39,10 @@ def _close_self_pipe(self):
37
39
38
40
39
41
def list_to_buffer (l = ()):
40
- return bytearray ().join (l )
42
+ buffer = collections .deque ()
43
+ buffer .extend ((memoryview (i ) for i in l ))
44
+ return buffer
45
+
41
46
42
47
43
48
def close_transport (transport ):
@@ -493,9 +498,13 @@ def setUp(self):
493
498
self .sock = mock .Mock (socket .socket )
494
499
self .sock_fd = self .sock .fileno .return_value = 7
495
500
496
- def socket_transport (self , waiter = None ):
501
+ def socket_transport (self , waiter = None , sendmsg = False ):
497
502
transport = _SelectorSocketTransport (self .loop , self .sock ,
498
503
self .protocol , waiter = waiter )
504
+ if sendmsg :
505
+ transport ._write_ready = transport ._write_sendmsg
506
+ else :
507
+ transport ._write_ready = transport ._write_send
499
508
self .addCleanup (close_transport , transport )
500
509
return transport
501
510
@@ -664,14 +673,14 @@ def test_write_memoryview(self):
664
673
665
674
def test_write_no_data (self ):
666
675
transport = self .socket_transport ()
667
- transport ._buffer .extend ( b'data' )
676
+ transport ._buffer .append ( memoryview ( b'data' ) )
668
677
transport .write (b'' )
669
678
self .assertFalse (self .sock .send .called )
670
679
self .assertEqual (list_to_buffer ([b'data' ]), transport ._buffer )
671
680
672
681
def test_write_buffer (self ):
673
682
transport = self .socket_transport ()
674
- transport ._buffer .extend (b'data1' )
683
+ transport ._buffer .append (b'data1' )
675
684
transport .write (b'data2' )
676
685
self .assertFalse (self .sock .send .called )
677
686
self .assertEqual (list_to_buffer ([b'data1' , b'data2' ]),
@@ -729,6 +738,77 @@ def test_write_tryagain(self):
729
738
self .loop .assert_writer (7 , transport ._write_ready )
730
739
self .assertEqual (list_to_buffer ([b'data' ]), transport ._buffer )
731
740
741
+ def test_write_sendmsg_no_data (self ):
742
+ self .sock .sendmsg = mock .Mock ()
743
+ self .sock .sendmsg .return_value = 0
744
+ transport = self .socket_transport (sendmsg = True )
745
+ transport ._buffer .append (memoryview (b'data' ))
746
+ transport .write (b'' )
747
+ self .assertFalse (self .sock .sendmsg .called )
748
+ self .assertEqual (list_to_buffer ([b'data' ]), transport ._buffer )
749
+
750
+ @unittest .skipUnless (selector_events ._HAS_SENDMSG , 'no sendmsg' )
751
+ def test_write_sendmsg_full (self ):
752
+ data = memoryview (b'data' )
753
+ self .sock .sendmsg = mock .Mock ()
754
+ self .sock .sendmsg .return_value = len (data )
755
+
756
+ transport = self .socket_transport (sendmsg = True )
757
+ transport ._buffer .append (data )
758
+ self .loop ._add_writer (7 , transport ._write_ready )
759
+ transport ._write_ready ()
760
+ self .assertTrue (self .sock .sendmsg .called )
761
+ self .assertFalse (self .loop .writers )
762
+
763
+ @unittest .skipUnless (selector_events ._HAS_SENDMSG , 'no sendmsg' )
764
+ def test_write_sendmsg_partial (self ):
765
+
766
+ data = memoryview (b'data' )
767
+ self .sock .sendmsg = mock .Mock ()
768
+ # Sent partial data
769
+ self .sock .sendmsg .return_value = 2
770
+
771
+ transport = self .socket_transport (sendmsg = True )
772
+ transport ._buffer .append (data )
773
+ self .loop ._add_writer (7 , transport ._write_ready )
774
+ transport ._write_ready ()
775
+ self .assertTrue (self .sock .sendmsg .called )
776
+ self .assertTrue (self .loop .writers )
777
+ self .assertEqual (list_to_buffer ([b'ta' ]), transport ._buffer )
778
+
779
+ @unittest .skipUnless (selector_events ._HAS_SENDMSG , 'no sendmsg' )
780
+ def test_write_sendmsg_half_buffer (self ):
781
+ data = [memoryview (b'data1' ), memoryview (b'data2' )]
782
+ self .sock .sendmsg = mock .Mock ()
783
+ # Sent partial data
784
+ self .sock .sendmsg .return_value = 2
785
+
786
+ transport = self .socket_transport (sendmsg = True )
787
+ transport ._buffer .extend (data )
788
+ self .loop ._add_writer (7 , transport ._write_ready )
789
+ transport ._write_ready ()
790
+ self .assertTrue (self .sock .sendmsg .called )
791
+ self .assertTrue (self .loop .writers )
792
+ self .assertEqual (list_to_buffer ([b'ta1' , b'data2' ]), transport ._buffer )
793
+
794
+ @unittest .skipUnless (selector_events ._HAS_SENDMSG , 'no sendmsg' )
795
+ def test_write_sendmsg_OSError (self ):
796
+ data = memoryview (b'data' )
797
+ self .sock .sendmsg = mock .Mock ()
798
+ err = self .sock .sendmsg .side_effect = OSError ()
799
+
800
+ transport = self .socket_transport (sendmsg = True )
801
+ transport ._fatal_error = mock .Mock ()
802
+ transport ._buffer .extend (data )
803
+ # Calls _fatal_error and clears the buffer
804
+ transport ._write_ready ()
805
+ self .assertTrue (self .sock .sendmsg .called )
806
+ self .assertFalse (self .loop .writers )
807
+ self .assertEqual (list_to_buffer ([]), transport ._buffer )
808
+ transport ._fatal_error .assert_called_with (
809
+ err ,
810
+ 'Fatal write error on socket transport' )
811
+
732
812
@mock .patch ('asyncio.selector_events.logger' )
733
813
def test_write_exception (self , m_log ):
734
814
err = self .sock .send .side_effect = OSError ()
@@ -768,19 +848,19 @@ def test_write_ready(self):
768
848
self .sock .send .return_value = len (data )
769
849
770
850
transport = self .socket_transport ()
771
- transport ._buffer .extend (data )
851
+ transport ._buffer .append (data )
772
852
self .loop ._add_writer (7 , transport ._write_ready )
773
853
transport ._write_ready ()
774
854
self .assertTrue (self .sock .send .called )
775
855
self .assertFalse (self .loop .writers )
776
856
777
857
def test_write_ready_closing (self ):
778
- data = b'data'
858
+ data = memoryview ( b'data' )
779
859
self .sock .send .return_value = len (data )
780
860
781
861
transport = self .socket_transport ()
782
862
transport ._closing = True
783
- transport ._buffer .extend (data )
863
+ transport ._buffer .append (data )
784
864
self .loop ._add_writer (7 , transport ._write_ready )
785
865
transport ._write_ready ()
786
866
self .assertTrue (self .sock .send .called )
@@ -795,11 +875,11 @@ def test_write_ready_no_data(self):
795
875
self .assertRaises (AssertionError , transport ._write_ready )
796
876
797
877
def test_write_ready_partial (self ):
798
- data = b'data'
878
+ data = memoryview ( b'data' )
799
879
self .sock .send .return_value = 2
800
880
801
881
transport = self .socket_transport ()
802
- transport ._buffer .extend (data )
882
+ transport ._buffer .append (data )
803
883
self .loop ._add_writer (7 , transport ._write_ready )
804
884
transport ._write_ready ()
805
885
self .loop .assert_writer (7 , transport ._write_ready )
@@ -810,7 +890,7 @@ def test_write_ready_partial_none(self):
810
890
self .sock .send .return_value = 0
811
891
812
892
transport = self .socket_transport ()
813
- transport ._buffer .extend (data )
893
+ transport ._buffer .append (data )
814
894
self .loop ._add_writer (7 , transport ._write_ready )
815
895
transport ._write_ready ()
816
896
self .loop .assert_writer (7 , transport ._write_ready )
@@ -820,12 +900,13 @@ def test_write_ready_tryagain(self):
820
900
self .sock .send .side_effect = BlockingIOError
821
901
822
902
transport = self .socket_transport ()
823
- transport ._buffer = list_to_buffer ([b'data1' , b'data2' ])
903
+ buffer = list_to_buffer ([b'data1' , b'data2' ])
904
+ transport ._buffer = buffer
824
905
self .loop ._add_writer (7 , transport ._write_ready )
825
906
transport ._write_ready ()
826
907
827
908
self .loop .assert_writer (7 , transport ._write_ready )
828
- self .assertEqual (list_to_buffer ([ b'data1data2' ]) , transport ._buffer )
909
+ self .assertEqual (buffer , transport ._buffer )
829
910
830
911
def test_write_ready_exception (self ):
831
912
err = self .sock .send .side_effect = OSError ()
0 commit comments