Skip to content

Commit 7f2877e

Browse files
committed
Add unit tests
1 parent 019d105 commit 7f2877e

File tree

6 files changed

+229
-13
lines changed

6 files changed

+229
-13
lines changed

adafruit_requests.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ def _get_socket(self, host, port, proto, *, timeout=1):
429429
if any(self._socket_free.items()):
430430
self._free_sockets()
431431
else:
432-
raise RuntimeError("Out of sockets")
432+
raise RuntimeError("Sending request failed")
433433
retry_count += 1
434434

435435
try:
@@ -450,7 +450,7 @@ def _get_socket(self, host, port, proto, *, timeout=1):
450450
except MemoryError:
451451
sock.close()
452452
sock = None
453-
except OSError as e:
453+
except OSError:
454454
sock.close()
455455
sock = None
456456

@@ -619,8 +619,8 @@ def connect(self, address):
619619
"""connect wrapper to add non-standard mode parameter"""
620620
try:
621621
return self._socket.connect(address, self._mode)
622-
except RuntimeError as e:
623-
raise OSError(errno.ENOMEM)
622+
except RuntimeError as error:
623+
raise OSError(errno.ENOMEM) from error
624624

625625

626626
class _FakeSSLContext:

tests/concurrent_test.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from unittest import mock
2+
import mocket
3+
import pytest
4+
import errno
5+
import adafruit_requests
6+
7+
ip = "1.2.3.4"
8+
host = "wifitest.adafruit.com"
9+
host2 = "wifitest2.adafruit.com"
10+
path = "/testwifi/index.html"
11+
text = b"This is a test of Adafruit WiFi!\r\nIf you can read this, its working :)"
12+
response = b"HTTP/1.0 200 OK\r\nContent-Length: 70\r\n\r\n" + text
13+
14+
15+
def test_second_connect_fails_memoryerror():
16+
pool = mocket.MocketPool()
17+
pool.getaddrinfo.return_value = ((None, None, None, None, (ip, 80)),)
18+
sock = mocket.Mocket(response)
19+
sock2 = mocket.Mocket(response)
20+
sock3 = mocket.Mocket(response)
21+
pool.socket.call_count = 0 # Reset call count
22+
pool.socket.side_effect = [sock, sock2, sock3]
23+
sock2.connect.side_effect = MemoryError()
24+
25+
ssl = mocket.SSLContext()
26+
27+
s = adafruit_requests.Session(pool, ssl)
28+
r = s.get("https://" + host + path)
29+
30+
sock.send.assert_has_calls(
31+
[mock.call(b"testwifi/index.html"),]
32+
)
33+
34+
sock.send.assert_has_calls(
35+
[mock.call(b"Host: "), mock.call(b"wifitest.adafruit.com"), mock.call(b"\r\n"),]
36+
)
37+
assert r.text == str(text, "utf-8")
38+
39+
host2 = "test.adafruit.com"
40+
s.get("https://" + host2 + path)
41+
42+
sock.connect.assert_called_once_with((host, 443))
43+
sock2.connect.assert_called_once_with((host2, 443))
44+
sock3.connect.assert_called_once_with((host2, 443))
45+
# Make sure that the socket is closed after send fails.
46+
sock.close.assert_called_once()
47+
sock2.close.assert_called_once()
48+
assert sock3.close.call_count == 0
49+
assert pool.socket.call_count == 3
50+
51+
52+
def test_second_connect_fails_oserror():
53+
pool = mocket.MocketPool()
54+
pool.getaddrinfo.return_value = ((None, None, None, None, (ip, 80)),)
55+
sock = mocket.Mocket(response)
56+
sock2 = mocket.Mocket(response)
57+
sock3 = mocket.Mocket(response)
58+
pool.socket.call_count = 0 # Reset call count
59+
pool.socket.side_effect = [sock, sock2, sock3]
60+
sock2.connect.side_effect = OSError(errno.ENOMEM)
61+
62+
ssl = mocket.SSLContext()
63+
64+
s = adafruit_requests.Session(pool, ssl)
65+
r = s.get("https://" + host + path)
66+
67+
sock.send.assert_has_calls(
68+
[mock.call(b"testwifi/index.html"),]
69+
)
70+
71+
sock.send.assert_has_calls(
72+
[mock.call(b"Host: "), mock.call(b"wifitest.adafruit.com"), mock.call(b"\r\n"),]
73+
)
74+
assert r.text == str(text, "utf-8")
75+
76+
host2 = "test.adafruit.com"
77+
s.get("https://" + host2 + path)
78+
79+
sock.connect.assert_called_once_with((host, 443))
80+
sock2.connect.assert_called_once_with((host2, 443))
81+
sock3.connect.assert_called_once_with((host2, 443))
82+
# Make sure that the socket is closed after send fails.
83+
sock.close.assert_called_once()
84+
sock2.close.assert_called_once()
85+
assert sock3.close.call_count == 0
86+
assert pool.socket.call_count == 3

tests/legacy_mocket.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ def __init__(self, response):
1616
self.send = mock.Mock(side_effect=self._send)
1717
self.readline = mock.Mock(side_effect=self._readline)
1818
self.recv = mock.Mock(side_effect=self._recv)
19+
self.fail_next_send = False
1920
self._response = response
2021
self._position = 0
2122

2223
def _send(self, data):
23-
return len(data)
24+
if self.fail_next_send:
25+
self.fail_next_send = False
26+
raise RuntimeError("Send failed")
27+
return None
2428

2529
def _readline(self):
2630
i = self._response.find(b"\r\n", self._position)
@@ -32,4 +36,5 @@ def _recv(self, count):
3236
end = self._position + count
3337
r = self._response[self._position : end]
3438
self._position = end
39+
print(r)
3540
return r

tests/legacy_test.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from unittest import mock
22
import legacy_mocket as mocket
33
import json
4+
import pytest
45
import adafruit_requests
56

67
ip = "1.2.3.4"
@@ -49,3 +50,122 @@ def test_post_string():
4950
sock.connect.assert_called_once_with((ip, 80))
5051
sock.send.assert_called_with(b"31F")
5152
r.close()
53+
54+
55+
def test_second_tls_send_fails():
56+
mocket.getaddrinfo.return_value = ((None, None, None, None, (ip, 80)),)
57+
sock = mocket.Mocket(headers + encoded)
58+
sock2 = mocket.Mocket(headers + encoded)
59+
mocket.socket.call_count = 0 # Reset call count
60+
mocket.socket.side_effect = [sock, sock2]
61+
62+
adafruit_requests.set_socket(mocket, mocket.interface)
63+
r = adafruit_requests.get("https://" + host + "/testwifi/index.html")
64+
65+
sock.send.assert_has_calls(
66+
[mock.call(b"testwifi/index.html"),]
67+
)
68+
69+
sock.send.assert_has_calls(
70+
[mock.call(b"Host: "), mock.call(host.encode("utf-8")), mock.call(b"\r\n"),]
71+
)
72+
assert r.text == str(encoded, "utf-8")
73+
74+
sock.fail_next_send = True
75+
adafruit_requests.get("https://" + host + "/get2")
76+
77+
sock.connect.assert_called_once_with((host, 443), mocket.interface.TLS_MODE)
78+
sock2.connect.assert_called_once_with((host, 443), mocket.interface.TLS_MODE)
79+
# Make sure that the socket is closed after send fails.
80+
sock.close.assert_called_once()
81+
assert sock2.close.call_count == 0
82+
assert mocket.socket.call_count == 2
83+
84+
85+
def test_second_send_fails():
86+
mocket.getaddrinfo.return_value = ((None, None, None, None, (ip, 80)),)
87+
sock = mocket.Mocket(headers + encoded)
88+
sock2 = mocket.Mocket(headers + encoded)
89+
mocket.socket.call_count = 0 # Reset call count
90+
mocket.socket.side_effect = [sock, sock2]
91+
92+
adafruit_requests.set_socket(mocket, mocket.interface)
93+
r = adafruit_requests.get("http://" + host + "/testwifi/index.html")
94+
95+
sock.send.assert_has_calls(
96+
[mock.call(b"testwifi/index.html"),]
97+
)
98+
99+
sock.send.assert_has_calls(
100+
[mock.call(b"Host: "), mock.call(host.encode("utf-8")), mock.call(b"\r\n"),]
101+
)
102+
assert r.text == str(encoded, "utf-8")
103+
104+
sock.fail_next_send = True
105+
adafruit_requests.get("http://" + host + "/get2")
106+
107+
sock.connect.assert_called_once_with((ip, 80))
108+
sock2.connect.assert_called_once_with((ip, 80))
109+
# Make sure that the socket is closed after send fails.
110+
sock.close.assert_called_once()
111+
assert sock2.close.call_count == 0
112+
assert mocket.socket.call_count == 2
113+
114+
115+
def test_first_read_fails():
116+
mocket.getaddrinfo.return_value = ((None, None, None, None, (ip, 80)),)
117+
sock = mocket.Mocket(b"")
118+
mocket.socket.call_count = 0 # Reset call count
119+
mocket.socket.side_effect = [sock]
120+
121+
adafruit_requests.set_socket(mocket, mocket.interface)
122+
123+
with pytest.raises(RuntimeError):
124+
r = adafruit_requests.get("http://" + host + "/testwifi/index.html")
125+
126+
sock.send.assert_has_calls(
127+
[mock.call(b"testwifi/index.html"),]
128+
)
129+
130+
sock.send.assert_has_calls(
131+
[mock.call(b"Host: "), mock.call(host.encode("utf-8")), mock.call(b"\r\n"),]
132+
)
133+
134+
sock.connect.assert_called_once_with((ip, 80))
135+
# Make sure that the socket is closed after the first receive fails.
136+
sock.close.assert_called_once()
137+
assert mocket.socket.call_count == 1
138+
139+
140+
def test_second_tls_connect_fails():
141+
mocket.getaddrinfo.return_value = ((None, None, None, None, (ip, 80)),)
142+
sock = mocket.Mocket(headers + encoded)
143+
sock2 = mocket.Mocket(headers + encoded)
144+
sock3 = mocket.Mocket(headers + encoded)
145+
mocket.socket.call_count = 0 # Reset call count
146+
mocket.socket.side_effect = [sock, sock2, sock3]
147+
sock2.connect.side_effect = RuntimeError("error connecting")
148+
149+
adafruit_requests.set_socket(mocket, mocket.interface)
150+
r = adafruit_requests.get("https://" + host + "/testwifi/index.html")
151+
152+
sock.send.assert_has_calls(
153+
[mock.call(b"testwifi/index.html"),]
154+
)
155+
156+
sock.send.assert_has_calls(
157+
[mock.call(b"Host: "), mock.call(host.encode("utf-8")), mock.call(b"\r\n"),]
158+
)
159+
assert r.text == str(encoded, "utf-8")
160+
161+
host2 = "test.adafruit.com"
162+
r = adafruit_requests.get("https://" + host2 + "/get2")
163+
164+
sock.connect.assert_called_once_with((host, 443), mocket.interface.TLS_MODE)
165+
sock2.connect.assert_called_once_with((host2, 443), mocket.interface.TLS_MODE)
166+
sock3.connect.assert_called_once_with((host2, 443), mocket.interface.TLS_MODE)
167+
# Make sure that the socket is closed after send fails.
168+
sock.close.assert_called_once()
169+
sock2.close.assert_called_once()
170+
assert sock3.close.call_count == 0
171+
assert mocket.socket.call_count == 3

tests/mocket.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ def __init__(self, response):
2020
self.recv_into = mock.Mock(side_effect=self._recv_into)
2121
self._response = response
2222
self._position = 0
23+
self.fail_next_send = False
2324

2425
def _send(self, data):
26+
if self.fail_next_send:
27+
self.fail_next_send = False
28+
return 0
2529
return len(data)
2630

2731
def _readline(self):

tests/reuse_test.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ def test_connect_out_of_memory():
143143
def test_second_send_fails():
144144
pool = mocket.MocketPool()
145145
pool.getaddrinfo.return_value = ((None, None, None, None, (ip, 80)),)
146-
sock = mocket.Mocket(response + response)
147-
pool.socket.return_value = sock
146+
sock = mocket.Mocket(response)
147+
sock2 = mocket.Mocket(response)
148+
pool.socket.side_effect = [sock, sock2]
149+
148150
ssl = mocket.SSLContext()
149151

150152
s = adafruit_requests.Session(pool, ssl)
@@ -159,13 +161,12 @@ def test_second_send_fails():
159161
)
160162
assert r.text == str(text, "utf-8")
161163

162-
sock.send.side_effect = None
163-
sock.send.return_value = 0
164-
165-
with pytest.raises(RuntimeError):
166-
s.get("https://" + host + path + "2")
164+
sock.fail_next_send = True
165+
s.get("https://" + host + path + "2")
167166

168167
sock.connect.assert_called_once_with((host, 443))
168+
sock2.connect.assert_called_once_with((host, 443))
169169
# Make sure that the socket is closed after send fails.
170170
sock.close.assert_called_once()
171-
pool.socket.assert_called_once()
171+
assert sock2.close.call_count == 0
172+
assert pool.socket.call_count == 2

0 commit comments

Comments
 (0)