Skip to content

Commit f45ae85

Browse files
authored
Add integration tests for Linode Client retry (#294)
## 📝 Description Tests added for LinodeClient retry mechanism - Moved tests in linode_client_test.py - Added tests for other allowed methods: PUT, POST, DELETE ## ✔️ How to Test pytest test/integration/linode_client/test_retry.py **How do I run the relevant unit/integration tests?** ## 📷 Preview **If applicable, include a screenshot or code snippet of this change. Otherwise, please remove this section.**
1 parent 88e489e commit f45ae85

2 files changed

Lines changed: 176 additions & 120 deletions

File tree

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
from test.integration.conftest import get_token
2+
3+
import httpretty
4+
5+
from linode_api4 import ApiError, LinodeClient
6+
7+
"""
8+
Tests for retrying on intermittent errors.
9+
10+
.. warning::
11+
This test class _does not_ follow normal testing conventions for this project,
12+
as requests are not automatically mocked. Only add tests to this class if they
13+
pertain to the retry logic, and make sure you mock the requests calls yourself
14+
(or else they will make real requests and those won't work).
15+
"""
16+
ERROR_RESPONSES = [
17+
httpretty.Response(
18+
body="{}",
19+
status=408,
20+
),
21+
httpretty.Response(
22+
body="{}",
23+
status=429,
24+
),
25+
httpretty.Response(
26+
body="{}",
27+
status=200,
28+
),
29+
]
30+
31+
32+
def get_retry_client():
33+
client = LinodeClient(token=get_token(), base_url="https://localhost")
34+
# sidestep the validation to do immediate retries so tests aren't slow
35+
client.retry_rate_limit_interval = 0.1
36+
return client
37+
38+
39+
@httpretty.activate
40+
def test_get_retry_statuses():
41+
"""
42+
Tests that retries work as expected on 408 and 429 responses.
43+
"""
44+
45+
httpretty.register_uri(
46+
httpretty.GET, "https://localhost/test", responses=ERROR_RESPONSES
47+
)
48+
49+
get_retry_client().get("/test")
50+
51+
assert len(httpretty.latest_requests()) == 3
52+
53+
54+
@httpretty.activate
55+
def test_put_retry_statuses():
56+
"""
57+
Tests that retries work as expected on 408 and 429 responses.
58+
"""
59+
60+
httpretty.register_uri(
61+
httpretty.PUT, "https://localhost/test", responses=ERROR_RESPONSES
62+
)
63+
64+
get_retry_client().put("/test")
65+
66+
assert len(httpretty.latest_requests()) == 3
67+
68+
69+
@httpretty.activate
70+
def test_post_retry_statuses():
71+
httpretty.register_uri(
72+
httpretty.POST, "https://localhost/test", responses=ERROR_RESPONSES
73+
)
74+
75+
get_retry_client.post("/test")
76+
77+
assert len(httpretty.latest_requests()) == 3
78+
79+
80+
@httpretty.activate
81+
def test_delete_retry_statuses():
82+
httpretty.register_uri(
83+
httpretty.DELETE, "https://localhost/test", responses=ERROR_RESPONSES
84+
)
85+
86+
get_retry_client().delete("/test")
87+
88+
assert len(httpretty.latest_requests()) == 3
89+
90+
91+
@httpretty.activate
92+
def test_retry_max():
93+
"""
94+
Tests that retries work as expected on 408 and 429 responses.
95+
"""
96+
97+
httpretty.register_uri(
98+
httpretty.GET,
99+
"https://localhost/test",
100+
responses=[
101+
httpretty.Response(
102+
body="{}",
103+
status=408,
104+
),
105+
httpretty.Response(
106+
body="{}",
107+
status=429,
108+
),
109+
httpretty.Response(
110+
body="{}",
111+
status=429,
112+
),
113+
],
114+
)
115+
116+
client = get_retry_client()
117+
client.retry_max = 2
118+
119+
try:
120+
client.get("/test")
121+
except ApiError as err:
122+
assert err.status == 429
123+
else:
124+
raise RuntimeError("Expected retry error after exceeding max retries")
125+
126+
assert len(httpretty.latest_requests()) == 3
127+
128+
129+
@httpretty.activate
130+
def test_retry_disable():
131+
"""
132+
Tests that retries can be disabled.
133+
"""
134+
135+
httpretty.register_uri(
136+
httpretty.GET,
137+
"https://localhost/test",
138+
responses=[
139+
httpretty.Response(
140+
body="{}",
141+
status=408,
142+
),
143+
],
144+
)
145+
146+
client = get_retry_client()
147+
client.retry = False
148+
149+
try:
150+
client.get("/test")
151+
except ApiError as e:
152+
assert e.status == 408
153+
else:
154+
raise RuntimeError("Expected 408 error to be raised")
155+
156+
assert len(httpretty.latest_requests()) == 1
157+
158+
159+
@httpretty.activate
160+
def test_retry_works_with_integer_interval_value():
161+
"""
162+
Tests that retries work as expected on 408 and 429 responses.
163+
"""
164+
165+
httpretty.register_uri(
166+
httpretty.GET, "https://localhost/test", responses=ERROR_RESPONSES
167+
)
168+
169+
client = get_retry_client()
170+
client.retry_max = 2
171+
client.retry_rate_limit_interval = 1
172+
173+
client.get("/test")
174+
175+
assert len(httpretty.latest_requests()) == 3

test/linode_client_test.py

Lines changed: 1 addition & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
from datetime import datetime
22
from test.base import ClientBaseCase
3-
from unittest import TestCase
43

5-
import httpretty
6-
import pytest
7-
8-
from linode_api4 import ApiError, LinodeClient, LongviewSubscription
4+
from linode_api4 import LongviewSubscription
95
from linode_api4.objects.linode import Instance
106
from linode_api4.objects.networking import IPAddress
117
from linode_api4.objects.object_storage import (
@@ -1064,118 +1060,3 @@ def test_ipv6_ranges(self):
10641060
ranges = self.client.networking.ipv6_ranges()
10651061
self.assertEqual(len(ranges), 1)
10661062
self.assertEqual(ranges[0].range, "2600:3c01::")
1067-
1068-
1069-
class LinodeClientRateLimitRetryTest(TestCase):
1070-
"""
1071-
Tests for retrying on intermittent errors.
1072-
1073-
.. warning::
1074-
This test class _does not_ follow normal testing conventions for this project,
1075-
as requests are not automatically mocked. Only add tests to this class if they
1076-
pertain to the retry logic, and make sure you mock the requests calls yourself
1077-
(or else they will make real requests and those won't work).
1078-
"""
1079-
1080-
def get_retry_client(self):
1081-
client = LinodeClient("testing", base_url="https://localhost")
1082-
# sidestep the validation to do immediate retries so tests aren't slow
1083-
client.retry_rate_limit_interval = 0.1
1084-
return client
1085-
1086-
@httpretty.activate
1087-
def test_retry_statuses(self):
1088-
"""
1089-
Tests that retries work as expected on 408 and 429 responses.
1090-
"""
1091-
1092-
httpretty.register_uri(
1093-
httpretty.GET,
1094-
"https://localhost/test",
1095-
responses=[
1096-
httpretty.Response(
1097-
body="{}",
1098-
status=408,
1099-
),
1100-
httpretty.Response(
1101-
body="{}",
1102-
status=429,
1103-
),
1104-
httpretty.Response(
1105-
body="{}",
1106-
status=200,
1107-
),
1108-
],
1109-
)
1110-
1111-
self.get_retry_client().get("/test")
1112-
1113-
assert len(httpretty.latest_requests()) == 3
1114-
1115-
@httpretty.activate
1116-
def test_retry_max(self):
1117-
"""
1118-
Tests that retries work as expected on 408 and 429 responses.
1119-
"""
1120-
1121-
httpretty.register_uri(
1122-
httpretty.GET,
1123-
"https://localhost/test",
1124-
responses=[
1125-
httpretty.Response(
1126-
body="{}",
1127-
status=408,
1128-
),
1129-
httpretty.Response(
1130-
body="{}",
1131-
status=429,
1132-
),
1133-
httpretty.Response(
1134-
body="{}",
1135-
status=429,
1136-
),
1137-
],
1138-
)
1139-
1140-
client = self.get_retry_client()
1141-
client.retry_max = 2
1142-
1143-
try:
1144-
client.get("/test")
1145-
except ApiError as err:
1146-
assert err.status == 429
1147-
else:
1148-
raise RuntimeError(
1149-
"Expected retry error after exceeding max retries"
1150-
)
1151-
1152-
assert len(httpretty.latest_requests()) == 3
1153-
1154-
@httpretty.activate
1155-
def test_retry_disable(self):
1156-
"""
1157-
Tests that retries can be disabled.
1158-
"""
1159-
1160-
httpretty.register_uri(
1161-
httpretty.GET,
1162-
"https://localhost/test",
1163-
responses=[
1164-
httpretty.Response(
1165-
body="{}",
1166-
status=408,
1167-
),
1168-
],
1169-
)
1170-
1171-
client = self.get_retry_client()
1172-
client.retry = False
1173-
1174-
try:
1175-
client.get("/test")
1176-
except ApiError as e:
1177-
assert e.status == 408
1178-
else:
1179-
raise RuntimeError("Expected 408 error to be raised")
1180-
1181-
assert len(httpretty.latest_requests()) == 1

0 commit comments

Comments
 (0)