Skip to content

Commit 25b400f

Browse files
committed
tests/multi_net/tcp_client_rst.py: Improve and extend test.
These changes test a few more things related to TCP RST: - add a second iteration to drain incoming data after TCP RST - read data after closing socket Signed-off-by: Damien George <damien@micropython.org>
1 parent a7cd418 commit 25b400f

1 file changed

Lines changed: 56 additions & 26 deletions

File tree

tests/multi_net/tcp_client_rst.py

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
import struct, time, socket, select
44

5+
try:
6+
import errno
7+
except ImportError:
8+
print("SKIP")
9+
raise SystemExit
10+
511
PORT = 8000
612

713

@@ -18,27 +24,49 @@ def instance0():
1824
s.bind(socket.getaddrinfo("0.0.0.0", PORT)[0][-1])
1925
s.listen(1)
2026
multitest.next()
21-
s2, _ = s.accept()
22-
s2.setblocking(False)
23-
poll = select.poll()
24-
poll.register(s2, select.POLLIN)
25-
time.sleep(0.4)
26-
print(convert_poll_list(poll.poll(1000)))
27-
# TODO: the following recv don't work with lwip, it abandons data upon TCP RST
28-
try:
29-
print(s2.recv(10))
27+
28+
for iteration in range(2):
29+
print("server iteration", iteration)
30+
31+
# Accept a connection from the client.
32+
s2, _ = s.accept()
33+
s2.setblocking(False)
34+
35+
# Create a poller for the connected socket.
36+
poll = select.poll()
37+
poll.register(s2, select.POLLIN)
38+
39+
# Wait for the client to send data and issue a TCP RST.
40+
for _ in range(10):
41+
if select.POLLIN | select.POLLERR | select.POLLHUP in convert_poll_list(
42+
poll.poll(1000)
43+
):
44+
break
45+
time.sleep(0.1)
3046
print(convert_poll_list(poll.poll(1000)))
31-
print(s2.recv(10))
47+
48+
# On the second test, drain the incoming data.
49+
if iteration == 1:
50+
for _ in range(5):
51+
try:
52+
print(s2.recv(10))
53+
except OSError as er:
54+
# This error should only happen on the 3rd recv.
55+
print("ECONNRESET:", er.errno == errno.ECONNRESET)
56+
print(convert_poll_list(poll.poll(1000)))
57+
58+
# Close the connection to the client.
59+
s2.close()
3260
print(convert_poll_list(poll.poll(1000)))
33-
print(s2.recv(10))
61+
62+
# Try to read more data from the closed socket, to make sure the error code is correct.
63+
try:
64+
print(s2.recv(10))
65+
except OSError as er:
66+
print("EBADF:", er.errno == errno.EBADF)
3467
print(convert_poll_list(poll.poll(1000)))
35-
except OSError as er:
36-
print(er.errno)
37-
print(convert_poll_list(poll.poll(1000)))
38-
# TODO lwip raises here but apparently it shouldn't
39-
print(s2.recv(10))
40-
print(convert_poll_list(poll.poll(1000)))
41-
s2.close()
68+
69+
# Close the listening socket.
4270
s.close()
4371

4472

@@ -47,11 +75,13 @@ def instance1():
4775
if not hasattr(socket, "SO_LINGER"):
4876
multitest.skip()
4977
multitest.next()
50-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
51-
s.connect(socket.getaddrinfo(IP, PORT)[0][-1])
52-
lgr_onoff = 1
53-
lgr_linger = 0
54-
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack("ii", lgr_onoff, lgr_linger))
55-
s.send(b"GET / HTTP/1.0\r\n\r\n")
56-
time.sleep(0.2)
57-
s.close() # This issues a TCP RST since we've set the linger option
78+
for iteration in range(2):
79+
print("client iteration", iteration)
80+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
81+
s.connect(socket.getaddrinfo(IP, PORT)[0][-1])
82+
lgr_onoff = 1
83+
lgr_linger = 0
84+
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack("ii", lgr_onoff, lgr_linger))
85+
s.send(b"GET / HTTP/1.0\r\n\r\n")
86+
time.sleep(0.2)
87+
s.close() # This issues a TCP RST since we've set the linger option

0 commit comments

Comments
 (0)