@@ -46,6 +46,8 @@ def test_ctor_global_loop(self, m_events):
46
46
self .assertIs (stream ._loop , m_events .get_event_loop .return_value )
47
47
48
48
def _basetest_open_connection (self , open_connection_fut ):
49
+ messages = []
50
+ self .loop .set_exception_handler (lambda loop , ctx : messages .append (ctx ))
49
51
reader , writer = self .loop .run_until_complete (open_connection_fut )
50
52
writer .write (b'GET / HTTP/1.0\r \n \r \n ' )
51
53
f = reader .readline ()
@@ -55,6 +57,7 @@ def _basetest_open_connection(self, open_connection_fut):
55
57
data = self .loop .run_until_complete (f )
56
58
self .assertTrue (data .endswith (b'\r \n \r \n Test message' ))
57
59
writer .close ()
60
+ self .assertEqual (messages , [])
58
61
59
62
def test_open_connection (self ):
60
63
with test_utils .run_test_server () as httpd :
@@ -70,6 +73,8 @@ def test_open_unix_connection(self):
70
73
self ._basetest_open_connection (conn_fut )
71
74
72
75
def _basetest_open_connection_no_loop_ssl (self , open_connection_fut ):
76
+ messages = []
77
+ self .loop .set_exception_handler (lambda loop , ctx : messages .append (ctx ))
73
78
try :
74
79
reader , writer = self .loop .run_until_complete (open_connection_fut )
75
80
finally :
@@ -80,6 +85,7 @@ def _basetest_open_connection_no_loop_ssl(self, open_connection_fut):
80
85
self .assertTrue (data .endswith (b'\r \n \r \n Test message' ))
81
86
82
87
writer .close ()
88
+ self .assertEqual (messages , [])
83
89
84
90
@unittest .skipIf (ssl is None , 'No ssl module' )
85
91
def test_open_connection_no_loop_ssl (self ):
@@ -104,13 +110,16 @@ def test_open_unix_connection_no_loop_ssl(self):
104
110
self ._basetest_open_connection_no_loop_ssl (conn_fut )
105
111
106
112
def _basetest_open_connection_error (self , open_connection_fut ):
113
+ messages = []
114
+ self .loop .set_exception_handler (lambda loop , ctx : messages .append (ctx ))
107
115
reader , writer = self .loop .run_until_complete (open_connection_fut )
108
116
writer ._protocol .connection_lost (ZeroDivisionError ())
109
117
f = reader .read ()
110
118
with self .assertRaises (ZeroDivisionError ):
111
119
self .loop .run_until_complete (f )
112
120
writer .close ()
113
121
test_utils .run_briefly (self .loop )
122
+ self .assertEqual (messages , [])
114
123
115
124
def test_open_connection_error (self ):
116
125
with test_utils .run_test_server () as httpd :
@@ -621,6 +630,9 @@ async def client(addr):
621
630
writer .close ()
622
631
return msgback
623
632
633
+ messages = []
634
+ self .loop .set_exception_handler (lambda loop , ctx : messages .append (ctx ))
635
+
624
636
# test the server variant with a coroutine as client handler
625
637
server = MyServer (self .loop )
626
638
addr = server .start ()
@@ -637,6 +649,8 @@ async def client(addr):
637
649
server .stop ()
638
650
self .assertEqual (msg , b"hello world!\n " )
639
651
652
+ self .assertEqual (messages , [])
653
+
640
654
@support .skip_unless_bind_unix_socket
641
655
def test_start_unix_server (self ):
642
656
@@ -685,6 +699,9 @@ async def client(path):
685
699
writer .close ()
686
700
return msgback
687
701
702
+ messages = []
703
+ self .loop .set_exception_handler (lambda loop , ctx : messages .append (ctx ))
704
+
688
705
# test the server variant with a coroutine as client handler
689
706
with test_utils .unix_socket_path () as path :
690
707
server = MyServer (self .loop , path )
@@ -703,6 +720,8 @@ async def client(path):
703
720
server .stop ()
704
721
self .assertEqual (msg , b"hello world!\n " )
705
722
723
+ self .assertEqual (messages , [])
724
+
706
725
@unittest .skipIf (sys .platform == 'win32' , "Don't have pipes" )
707
726
def test_read_all_from_pipe_reader (self ):
708
727
# See asyncio issue 168. This test is derived from the example
@@ -893,6 +912,58 @@ def test_wait_closed_on_close_with_unread_data(self):
893
912
wr .close ()
894
913
self .loop .run_until_complete (wr .wait_closed ())
895
914
915
+ def test_del_stream_before_sock_closing (self ):
916
+ messages = []
917
+ self .loop .set_exception_handler (lambda loop , ctx : messages .append (ctx ))
918
+
919
+ with test_utils .run_test_server () as httpd :
920
+ rd , wr = self .loop .run_until_complete (
921
+ asyncio .open_connection (* httpd .address , loop = self .loop ))
922
+ sock = wr .get_extra_info ('socket' )
923
+ self .assertNotEqual (sock .fileno (), - 1 )
924
+
925
+ wr .write (b'GET / HTTP/1.0\r \n \r \n ' )
926
+ f = rd .readline ()
927
+ data = self .loop .run_until_complete (f )
928
+ self .assertEqual (data , b'HTTP/1.0 200 OK\r \n ' )
929
+
930
+ # drop refs to reader/writer
931
+ del rd
932
+ del wr
933
+ gc .collect ()
934
+ # make a chance to close the socket
935
+ test_utils .run_briefly (self .loop )
936
+
937
+ self .assertEqual (1 , len (messages ))
938
+ self .assertEqual (sock .fileno (), - 1 )
939
+
940
+ self .assertEqual (1 , len (messages ))
941
+ self .assertEqual ('An open stream object is being garbage '
942
+ 'collected; call "stream.close()" explicitly.' ,
943
+ messages [0 ]['message' ])
944
+
945
+ def test_del_stream_before_connection_made (self ):
946
+ messages = []
947
+ self .loop .set_exception_handler (lambda loop , ctx : messages .append (ctx ))
948
+
949
+ with test_utils .run_test_server () as httpd :
950
+ rd = asyncio .StreamReader (loop = self .loop )
951
+ pr = asyncio .StreamReaderProtocol (rd , loop = self .loop )
952
+ del rd
953
+ gc .collect ()
954
+ tr , _ = self .loop .run_until_complete (
955
+ self .loop .create_connection (
956
+ lambda : pr , * httpd .address ))
957
+
958
+ sock = tr .get_extra_info ('socket' )
959
+ self .assertEqual (sock .fileno (), - 1 )
960
+
961
+ self .assertEqual (1 , len (messages ))
962
+ self .assertEqual ('An open stream was garbage collected prior to '
963
+ 'establishing network connection; '
964
+ 'call "stream.close()" explicitly.' ,
965
+ messages [0 ]['message' ])
966
+
896
967
897
968
if __name__ == '__main__' :
898
969
unittest .main ()
0 commit comments