11# test that socket.connect() on a non-blocking socket raises EINPROGRESS
22# and that an immediate write/send/read/recv does the right thing
33
4- import sys , time , socket , errno , ssl
4+ import errno
5+ import select
6+ import socket
7+ import ssl
58
6- isMP = sys .implementation .name == "micropython"
9+ # only mbedTLS supports non-blocking mode
10+ if not hasattr (ssl , "MBEDTLS_VERSION" ):
11+ print ("SKIP" )
12+ raise SystemExit
713
814
9- def dp (e ):
10- # uncomment next line for development and testing, to print the actual exceptions
11- # print(repr(e))
12- pass
15+ # get the name of an errno error code
16+ def errno_name (er ):
17+ if er == errno .EAGAIN :
18+ return "EAGAIN"
19+ if er == errno .EINPROGRESS :
20+ return "EINPROGRESS"
21+ return er
1322
1423
1524# do_connect establishes the socket and wraps it if tls is True.
@@ -22,112 +31,75 @@ def do_connect(peer_addr, tls, handshake):
2231 # print("Connecting to", peer_addr)
2332 s .connect (peer_addr )
2433 except OSError as er :
25- print ("connect:" , er .errno == errno .EINPROGRESS )
26- if er .errno != errno .EINPROGRESS :
27- print (" got" , er .errno )
34+ print ("connect:" , errno_name (er .errno ))
2835 # wrap with ssl/tls if desired
2936 if tls :
3037 ssl_context = ssl .SSLContext (ssl .PROTOCOL_TLS_CLIENT )
31- if hasattr (ssl_context , "check_hostname" ):
32- ssl_context .check_hostname = False
33-
3438 try :
3539 s = ssl_context .wrap_socket (s , do_handshake_on_connect = handshake )
36- print ("wrap: True" )
40+ print ("wrap ok : True" )
3741 except Exception as e :
38- dp (e )
39- print ("wrap:" , e )
40- elif handshake :
41- # just sleep a little bit, this allows any connect() errors to happen
42- time .sleep (0.2 )
42+ print ("wrap er:" , e )
4343 return s
4444
4545
46+ # poll a socket and print out the result
47+ def poll (s ):
48+ poller = select .poll ()
49+ poller .register (s )
50+ print ("poll: " , poller .poll (0 ))
51+
52+
4653# test runs the test against a specific peer address.
47- def test (peer_addr , tls = False , handshake = False ):
48- # MicroPython plain sockets have read/write, but CPython's don't
49- # MicroPython TLS sockets and CPython's have read/write
50- # hasRW captures this wonderful state of affairs
51- hasRW = isMP or tls
54+ def test (peer_addr , tls , handshake ):
55+ # MicroPython plain and TLS sockets have read/write
56+ hasRW = True
5257
53- # MicroPython plain sockets and CPython's have send/recv
54- # MicroPython TLS sockets don't have send/recv, but CPython's do
55- # hasSR captures this wonderful state of affairs
56- hasSR = not (isMP and tls )
58+ # MicroPython plain sockets have send/recv
59+ # MicroPython TLS sockets don't have send/recv
60+ hasSR = not tls
5761
5862 # connect + send
63+ # non-blocking send should raise EAGAIN
5964 if hasSR :
6065 s = do_connect (peer_addr , tls , handshake )
61- # send -> 4 or EAGAIN
66+ poll ( s )
6267 try :
6368 ret = s .send (b"1234" )
64- print ("send:" , handshake and ret == 4 )
69+ print ("send ok :" , ret ) # shouldn't get here
6570 except OSError as er :
66- #
67- dp (er )
68- print ("send:" , er .errno in (errno .EAGAIN , errno .EINPROGRESS ))
71+ print ("send er:" , errno_name (er .errno ))
6972 s .close ()
70- else : # fake it...
71- print ("connect:" , True )
72- if tls :
73- print ("wrap:" , True )
74- print ("send:" , True )
7573
7674 # connect + write
75+ # non-blocking write should return None
7776 if hasRW :
7877 s = do_connect (peer_addr , tls , handshake )
79- # write -> None
80- try :
81- ret = s .write (b"1234" )
82- print ("write:" , ret in (4 , None )) # SSL may accept 4 into buffer
83- except OSError as er :
84- dp (er )
85- print ("write:" , False ) # should not raise
86- except ValueError as er : # CPython
87- dp (er )
88- print ("write:" , er .args [0 ] == "Write on closed or unwrapped SSL socket." )
78+ poll (s )
79+ ret = s .write (b"1234" )
80+ print ("write: " , ret )
8981 s .close ()
90- else : # fake it...
91- print ("connect:" , True )
92- if tls :
93- print ("wrap:" , True )
94- print ("write:" , True )
9582
83+ # connect + recv
84+ # non-blocking recv should raise EAGAIN
9685 if hasSR :
97- # connect + recv
9886 s = do_connect (peer_addr , tls , handshake )
99- # recv -> EAGAIN
87+ poll ( s )
10088 try :
101- print ("recv:" , s .recv (10 ))
89+ ret = s .recv (10 )
90+ print ("recv ok:" , ret ) # shouldn't get here
10291 except OSError as er :
103- dp (er )
104- print ("recv:" , er .errno == errno .EAGAIN )
92+ print ("recv er:" , errno_name (er .errno ))
10593 s .close ()
106- else : # fake it...
107- print ("connect:" , True )
108- if tls :
109- print ("wrap:" , True )
110- print ("recv:" , True )
11194
11295 # connect + read
96+ # non-blocking read should return None
11397 if hasRW :
11498 s = do_connect (peer_addr , tls , handshake )
115- # read -> None
116- try :
117- ret = s .read (10 )
118- print ("read:" , ret is None )
119- except OSError as er :
120- dp (er )
121- print ("read:" , False ) # should not raise
122- except ValueError as er : # CPython
123- dp (er )
124- print ("read:" , er .args [0 ] == "Read on closed or unwrapped SSL socket." )
99+ poll (s )
100+ ret = s .read (10 )
101+ print ("read: " , ret )
125102 s .close ()
126- else : # fake it...
127- print ("connect:" , True )
128- if tls :
129- print ("wrap:" , True )
130- print ("read:" , True )
131103
132104
133105if __name__ == "__main__" :
@@ -136,10 +108,8 @@ def test(peer_addr, tls=False, handshake=False):
136108 print ("--- Plain sockets to nowhere ---" )
137109 test (socket .getaddrinfo ("192.0.2.1" , 80 )[0 ][- 1 ], False , False )
138110 print ("--- SSL sockets to nowhere ---" )
139- # this test fails with AXTLS because do_handshake=False blocks on first read/write and
140- # there it times out until the connect is aborted
141111 test (socket .getaddrinfo ("192.0.2.1" , 443 )[0 ][- 1 ], True , False )
142112 print ("--- Plain sockets ---" )
143- test (socket .getaddrinfo ("micropython.org" , 80 )[0 ][- 1 ], False , True )
113+ test (socket .getaddrinfo ("micropython.org" , 80 )[0 ][- 1 ], False , False )
144114 print ("--- SSL sockets ---" )
145115 test (socket .getaddrinfo ("micropython.org" , 443 )[0 ][- 1 ], True , True )
0 commit comments