locust 2.29.2.dev34__py3-none-any.whl → 2.29.2.dev45__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- locust/_version.py +6 -2
- locust/contrib/fasthttp.py +1 -1
- locust/dispatch.py +7 -6
- locust/main.py +0 -1
- {locust-2.29.2.dev34.dist-info → locust-2.29.2.dev45.dist-info}/METADATA +31 -26
- locust-2.29.2.dev45.dist-info/RECORD +49 -0
- locust-2.29.2.dev45.dist-info/WHEEL +4 -0
- locust-2.29.2.dev45.dist-info/entry_points.txt +3 -0
- locust/test/__init__.py +0 -15
- locust/test/fake_module1_for_env_test.py +0 -7
- locust/test/fake_module2_for_env_test.py +0 -7
- locust/test/mock_locustfile.py +0 -56
- locust/test/mock_logging.py +0 -28
- locust/test/test_debugging.py +0 -39
- locust/test/test_dispatch.py +0 -4170
- locust/test/test_env.py +0 -283
- locust/test/test_fasthttp.py +0 -785
- locust/test/test_http.py +0 -325
- locust/test/test_interruptable_task.py +0 -48
- locust/test/test_load_locustfile.py +0 -228
- locust/test/test_locust_class.py +0 -831
- locust/test/test_log.py +0 -237
- locust/test/test_main.py +0 -2264
- locust/test/test_old_wait_api.py +0 -0
- locust/test/test_parser.py +0 -450
- locust/test/test_runners.py +0 -4476
- locust/test/test_sequential_taskset.py +0 -157
- locust/test/test_stats.py +0 -866
- locust/test/test_tags.py +0 -440
- locust/test/test_taskratio.py +0 -94
- locust/test/test_users.py +0 -69
- locust/test/test_util.py +0 -33
- locust/test/test_wait_time.py +0 -79
- locust/test/test_web.py +0 -1257
- locust/test/test_zmqrpc.py +0 -58
- locust/test/testcases.py +0 -248
- locust/test/util.py +0 -88
- locust-2.29.2.dev34.dist-info/RECORD +0 -79
- locust-2.29.2.dev34.dist-info/WHEEL +0 -5
- locust-2.29.2.dev34.dist-info/entry_points.txt +0 -2
- locust-2.29.2.dev34.dist-info/top_level.txt +0 -1
- {locust-2.29.2.dev34.dist-info → locust-2.29.2.dev45.dist-info}/LICENSE +0 -0
locust/test/test_fasthttp.py
DELETED
@@ -1,785 +0,0 @@
|
|
1
|
-
from locust import FastHttpUser
|
2
|
-
from locust.argument_parser import parse_options
|
3
|
-
from locust.contrib.fasthttp import FastHttpSession
|
4
|
-
from locust.exception import CatchResponseError, InterruptTaskSet, LocustError, ResponseError
|
5
|
-
from locust.user import TaskSet, task
|
6
|
-
from locust.util.load_locustfile import is_user_class
|
7
|
-
|
8
|
-
import socket
|
9
|
-
import time
|
10
|
-
from tempfile import NamedTemporaryFile
|
11
|
-
|
12
|
-
import gevent
|
13
|
-
from geventhttpclient.client import HTTPClientPool
|
14
|
-
from pyquery import PyQuery as pq
|
15
|
-
|
16
|
-
from .testcases import LocustTestCase, WebserverTestCase
|
17
|
-
from .util import create_tls_cert
|
18
|
-
|
19
|
-
|
20
|
-
class TestFastHttpSession(WebserverTestCase):
|
21
|
-
def get_client(self):
|
22
|
-
return FastHttpSession(self.environment, base_url="http://127.0.0.1:%i" % self.port, user=None)
|
23
|
-
|
24
|
-
def test_get(self):
|
25
|
-
s = self.get_client()
|
26
|
-
r = s.get("/ultra_fast")
|
27
|
-
self.assertEqual(200, r.status_code)
|
28
|
-
|
29
|
-
def test_connection_error(self):
|
30
|
-
s = FastHttpSession(self.environment, "http://localhost:1", user=None)
|
31
|
-
r = s.get("/", headers={"X-Test-Headers": "hello"})
|
32
|
-
self.assertEqual(r.status_code, 0)
|
33
|
-
self.assertEqual(None, r.content)
|
34
|
-
self.assertEqual(1, len(self.runner.stats.errors))
|
35
|
-
self.assertTrue(isinstance(r.error, ConnectionRefusedError))
|
36
|
-
self.assertTrue(isinstance(next(iter(self.runner.stats.errors.values())).error, ConnectionRefusedError))
|
37
|
-
self.assertEqual(r.url, "http://localhost:1/")
|
38
|
-
self.assertEqual(r.request.url, r.url)
|
39
|
-
self.assertEqual(r.request.headers.get("X-Test-Headers", ""), "hello")
|
40
|
-
|
41
|
-
def test_404(self):
|
42
|
-
s = self.get_client()
|
43
|
-
r = s.get("/does_not_exist")
|
44
|
-
self.assertEqual(404, r.status_code)
|
45
|
-
self.assertEqual(1, self.runner.stats.get("/does_not_exist", "GET").num_failures)
|
46
|
-
|
47
|
-
def test_204(self):
|
48
|
-
s = self.get_client()
|
49
|
-
r = s.get("/status/204")
|
50
|
-
self.assertEqual(204, r.status_code)
|
51
|
-
self.assertEqual(1, self.runner.stats.get("/status/204", "GET").num_requests)
|
52
|
-
self.assertEqual(0, self.runner.stats.get("/status/204", "GET").num_failures)
|
53
|
-
self.assertEqual(r.url, "http://127.0.0.1:%i/status/204" % self.port)
|
54
|
-
self.assertEqual(r.request.url, r.url)
|
55
|
-
|
56
|
-
def test_streaming_response(self):
|
57
|
-
"""
|
58
|
-
Test a request to an endpoint that returns a streaming response
|
59
|
-
"""
|
60
|
-
s = self.get_client()
|
61
|
-
r = s.get("/streaming/30")
|
62
|
-
|
63
|
-
# verify that the time reported includes the download time of the whole streamed response
|
64
|
-
self.assertGreater(self.runner.stats.get("/streaming/30", method="GET").avg_response_time, 250)
|
65
|
-
self.runner.stats.clear_all()
|
66
|
-
|
67
|
-
# verify that response time does NOT include whole download time, when using stream=True
|
68
|
-
r = s.get("/streaming/30", stream=True)
|
69
|
-
self.assertGreaterEqual(self.runner.stats.get("/streaming/30", method="GET").avg_response_time, 0)
|
70
|
-
self.assertLess(self.runner.stats.get("/streaming/30", method="GET").avg_response_time, 250)
|
71
|
-
|
72
|
-
# download the content of the streaming response (so we don't get an ugly exception in the log)
|
73
|
-
_ = r.content
|
74
|
-
|
75
|
-
def test_streaming_response_catch_response(self):
|
76
|
-
"""
|
77
|
-
Test a request to an endpoint that returns a streaming response, and uses catch_response
|
78
|
-
"""
|
79
|
-
s = self.get_client()
|
80
|
-
|
81
|
-
with s.get("/streaming/30", stream=True, catch_response=True) as r:
|
82
|
-
# typical usage of r when stream=True is to read the stream as desired,
|
83
|
-
# with the possibility to "fail fast" when some things are read early on
|
84
|
-
response_content = str(r.stream.read())
|
85
|
-
r.failure("some error")
|
86
|
-
|
87
|
-
self.assertRegex(response_content, "streaming response")
|
88
|
-
|
89
|
-
stats = self.runner.stats.get("/streaming/30", "GET")
|
90
|
-
self.assertEqual(1, stats.num_requests)
|
91
|
-
self.assertEqual(1, stats.num_failures)
|
92
|
-
|
93
|
-
# verify that response time does NOT include whole download time, when using stream=True
|
94
|
-
self.assertGreaterEqual(stats.avg_response_time, 0)
|
95
|
-
self.assertLess(stats.avg_response_time, 250)
|
96
|
-
|
97
|
-
def test_slow_redirect(self):
|
98
|
-
s = self.get_client()
|
99
|
-
url = "/redirect?url=/redirect&delay=0.5"
|
100
|
-
s.get(url)
|
101
|
-
stats = self.runner.stats.get(url, method="GET")
|
102
|
-
self.assertEqual(1, stats.num_requests)
|
103
|
-
self.assertGreater(stats.avg_response_time, 500)
|
104
|
-
|
105
|
-
def test_post_redirect(self):
|
106
|
-
s = self.get_client()
|
107
|
-
url = "/redirect"
|
108
|
-
r = s.post(url)
|
109
|
-
self.assertEqual(200, r.status_code)
|
110
|
-
post_stats = self.runner.stats.get(url, method="POST")
|
111
|
-
get_stats = self.runner.stats.get(url, method="GET")
|
112
|
-
self.assertEqual(1, post_stats.num_requests)
|
113
|
-
self.assertEqual(0, get_stats.num_requests)
|
114
|
-
|
115
|
-
def test_cookie(self):
|
116
|
-
s = self.get_client()
|
117
|
-
r = s.post("/set_cookie?name=testcookie&value=1337")
|
118
|
-
self.assertEqual(200, r.status_code)
|
119
|
-
r = s.get("/get_cookie?name=testcookie")
|
120
|
-
self.assertEqual("1337", r.content.decode())
|
121
|
-
self.assertEqual("1337", r.text)
|
122
|
-
|
123
|
-
def test_head(self):
|
124
|
-
s = self.get_client()
|
125
|
-
r = s.head("/request_method")
|
126
|
-
self.assertEqual(200, r.status_code)
|
127
|
-
self.assertEqual("", r.content.decode())
|
128
|
-
|
129
|
-
def test_delete(self):
|
130
|
-
s = self.get_client()
|
131
|
-
r = s.delete("/request_method")
|
132
|
-
self.assertEqual(200, r.status_code)
|
133
|
-
self.assertEqual("DELETE", r.content.decode())
|
134
|
-
|
135
|
-
def test_patch(self):
|
136
|
-
s = self.get_client()
|
137
|
-
r = s.patch("/request_method")
|
138
|
-
self.assertEqual(200, r.status_code)
|
139
|
-
self.assertEqual("PATCH", r.content.decode())
|
140
|
-
|
141
|
-
def test_options(self):
|
142
|
-
s = self.get_client()
|
143
|
-
r = s.options("/request_method")
|
144
|
-
self.assertEqual(200, r.status_code)
|
145
|
-
self.assertEqual("", r.content.decode())
|
146
|
-
self.assertEqual(
|
147
|
-
{"OPTIONS", "DELETE", "PUT", "GET", "POST", "HEAD", "PATCH"},
|
148
|
-
set(r.headers["allow"].split(", ")),
|
149
|
-
)
|
150
|
-
|
151
|
-
def test_json_payload(self):
|
152
|
-
s = self.get_client()
|
153
|
-
r = s.post("/request_method", json={"foo": "bar"})
|
154
|
-
self.assertEqual(200, r.status_code)
|
155
|
-
self.assertEqual(r.request.body, '{"foo": "bar"}')
|
156
|
-
self.assertEqual(r.request.headers.get("Content-Type"), "application/json")
|
157
|
-
|
158
|
-
def test_catch_response_fail_successful_request(self):
|
159
|
-
s = self.get_client()
|
160
|
-
with s.get("/ultra_fast", catch_response=True) as r:
|
161
|
-
r.failure("nope")
|
162
|
-
self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_requests)
|
163
|
-
self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_failures)
|
164
|
-
|
165
|
-
def test_catch_response_pass_failed_request(self):
|
166
|
-
s = self.get_client()
|
167
|
-
with s.get("/fail", catch_response=True) as r:
|
168
|
-
r.success()
|
169
|
-
self.assertEqual(1, self.environment.stats.total.num_requests)
|
170
|
-
self.assertEqual(0, self.environment.stats.total.num_failures)
|
171
|
-
|
172
|
-
def test_catch_response_multiple_failure_and_success(self):
|
173
|
-
s = self.get_client()
|
174
|
-
with s.get("/ultra_fast", catch_response=True) as r:
|
175
|
-
r.failure("nope")
|
176
|
-
r.success()
|
177
|
-
r.failure("nooo")
|
178
|
-
r.success()
|
179
|
-
self.assertEqual(1, self.environment.stats.total.num_requests)
|
180
|
-
self.assertEqual(0, self.environment.stats.total.num_failures)
|
181
|
-
|
182
|
-
def test_catch_response_pass_failed_request_with_other_exception_within_block(self):
|
183
|
-
class OtherException(Exception):
|
184
|
-
pass
|
185
|
-
|
186
|
-
s = self.get_client()
|
187
|
-
try:
|
188
|
-
with s.get("/fail", catch_response=True) as r:
|
189
|
-
r.success()
|
190
|
-
raise OtherException("wtf")
|
191
|
-
except OtherException:
|
192
|
-
pass
|
193
|
-
else:
|
194
|
-
self.fail("OtherException should have been raised")
|
195
|
-
|
196
|
-
self.assertEqual(1, self.environment.stats.total.num_requests)
|
197
|
-
self.assertEqual(0, self.environment.stats.total.num_failures)
|
198
|
-
|
199
|
-
def test_catch_response_default_success(self):
|
200
|
-
s = self.get_client()
|
201
|
-
with s.get("/ultra_fast", catch_response=True):
|
202
|
-
pass
|
203
|
-
self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_requests)
|
204
|
-
self.assertEqual(0, self.environment.stats.get("/ultra_fast", "GET").num_failures)
|
205
|
-
|
206
|
-
def test_catch_response_default_fail(self):
|
207
|
-
s = self.get_client()
|
208
|
-
with s.get("/fail", catch_response=True):
|
209
|
-
pass
|
210
|
-
self.assertEqual(1, self.environment.stats.total.num_requests)
|
211
|
-
self.assertEqual(1, self.environment.stats.total.num_failures)
|
212
|
-
|
213
|
-
def test_error_message_with_name_replacement(self):
|
214
|
-
s = self.get_client()
|
215
|
-
kwargs = {}
|
216
|
-
|
217
|
-
def on_request(**kw):
|
218
|
-
self.assertIsNotNone(kw["exception"])
|
219
|
-
kwargs.update(kw)
|
220
|
-
|
221
|
-
self.environment.events.request.add_listener(on_request)
|
222
|
-
before_request = time.time()
|
223
|
-
s.request("get", "/wrong_url/01", name="replaced_url_name", context={"foo": "bar"})
|
224
|
-
after_request = time.time()
|
225
|
-
# self.assertIn("for url: replaced_url_name", str(kwargs["exception"])) # this is actually broken for FastHttpUser right now...
|
226
|
-
self.assertAlmostEqual(before_request, kwargs["start_time"], delta=0.01)
|
227
|
-
self.assertAlmostEqual(after_request, kwargs["start_time"] + kwargs["response_time"] / 1000, delta=0.01)
|
228
|
-
self.assertEqual(s.base_url + "/wrong_url/01", kwargs["url"]) # url is unaffected by name
|
229
|
-
self.assertDictEqual({"foo": "bar"}, kwargs["context"])
|
230
|
-
|
231
|
-
def test_custom_ssl_context_fail_with_bad_context(self):
|
232
|
-
"""
|
233
|
-
Test FastHttpSession with a custom SSLContext factory that will fail as
|
234
|
-
we can not set verify_mode to CERT_NONE when check_hostname is enabled
|
235
|
-
"""
|
236
|
-
|
237
|
-
def create_custom_context():
|
238
|
-
context = gevent.ssl.create_default_context()
|
239
|
-
context.check_hostname = True
|
240
|
-
context.verify_mode = gevent.ssl.CERT_NONE
|
241
|
-
return context
|
242
|
-
|
243
|
-
s = FastHttpSession(
|
244
|
-
self.environment,
|
245
|
-
"https://127.0.0.1:%i" % self.port,
|
246
|
-
ssl_context_factory=create_custom_context,
|
247
|
-
user=None,
|
248
|
-
)
|
249
|
-
with self.assertRaises(ValueError) as e:
|
250
|
-
s.get("/")
|
251
|
-
self.assertEqual(e.exception.args, ("Cannot set verify_mode to CERT_NONE when check_hostname is enabled.",))
|
252
|
-
|
253
|
-
def test_custom_ssl_context_passed_correct_to_client_pool(self):
|
254
|
-
"""
|
255
|
-
Test FastHttpSession with a custom SSLContext factory with a options.name
|
256
|
-
that will be passed correctly to the ClientPool. It will also test a 2nd
|
257
|
-
factory which is not the correct one.
|
258
|
-
"""
|
259
|
-
|
260
|
-
def custom_ssl_context():
|
261
|
-
context = gevent.ssl.create_default_context()
|
262
|
-
context.check_hostname = False
|
263
|
-
context.verify_mode = gevent.ssl.CERT_NONE
|
264
|
-
context.options.name = "FAKEOPTION"
|
265
|
-
return context
|
266
|
-
|
267
|
-
def custom_context_with_wrong_option():
|
268
|
-
context = gevent.ssl.create_default_context()
|
269
|
-
context.check_hostname = False
|
270
|
-
context.verify_mode = gevent.ssl.CERT_NONE
|
271
|
-
context.options.name = "OPTIONFAKED"
|
272
|
-
return context
|
273
|
-
|
274
|
-
s = FastHttpSession(
|
275
|
-
self.environment,
|
276
|
-
"https://127.0.0.1:%i" % self.port,
|
277
|
-
ssl_context_factory=custom_ssl_context,
|
278
|
-
user=None,
|
279
|
-
)
|
280
|
-
self.assertEqual(s.client.clientpool.client_args["ssl_context_factory"], custom_ssl_context)
|
281
|
-
self.assertNotEqual(s.client.clientpool.client_args["ssl_context_factory"], custom_context_with_wrong_option)
|
282
|
-
|
283
|
-
|
284
|
-
class TestRequestStatsWithWebserver(WebserverTestCase):
|
285
|
-
def test_request_stats_content_length(self):
|
286
|
-
class MyUser(FastHttpUser):
|
287
|
-
host = "http://127.0.0.1:%i" % self.port
|
288
|
-
|
289
|
-
locust = MyUser(self.environment)
|
290
|
-
locust.client.get("/ultra_fast")
|
291
|
-
self.assertEqual(
|
292
|
-
self.runner.stats.get("/ultra_fast", "GET").avg_content_length, len("This is an ultra fast response")
|
293
|
-
)
|
294
|
-
locust.client.get("/ultra_fast")
|
295
|
-
self.assertEqual(
|
296
|
-
self.runner.stats.get("/ultra_fast", "GET").avg_content_length, len("This is an ultra fast response")
|
297
|
-
)
|
298
|
-
|
299
|
-
def test_request_stats_no_content_length(self):
|
300
|
-
class MyUser(FastHttpUser):
|
301
|
-
host = "http://127.0.0.1:%i" % self.port
|
302
|
-
|
303
|
-
l = MyUser(self.environment)
|
304
|
-
path = "/no_content_length"
|
305
|
-
l.client.get(path)
|
306
|
-
self.assertEqual(
|
307
|
-
self.runner.stats.get(path, "GET").avg_content_length,
|
308
|
-
len("This response does not have content-length in the header"),
|
309
|
-
)
|
310
|
-
|
311
|
-
def test_request_stats_no_content_length_streaming(self):
|
312
|
-
class MyUser(FastHttpUser):
|
313
|
-
host = "http://127.0.0.1:%i" % self.port
|
314
|
-
|
315
|
-
l = MyUser(self.environment)
|
316
|
-
path = "/no_content_length"
|
317
|
-
l.client.get(path, stream=True)
|
318
|
-
self.assertEqual(0, self.runner.stats.get(path, "GET").avg_content_length)
|
319
|
-
|
320
|
-
def test_request_stats_named_endpoint(self):
|
321
|
-
class MyUser(FastHttpUser):
|
322
|
-
host = "http://127.0.0.1:%i" % self.port
|
323
|
-
|
324
|
-
locust = MyUser(self.environment)
|
325
|
-
locust.client.get("/ultra_fast", name="my_custom_name")
|
326
|
-
self.assertEqual(1, self.runner.stats.get("my_custom_name", "GET").num_requests)
|
327
|
-
|
328
|
-
def test_request_stats_query_variables(self):
|
329
|
-
class MyUser(FastHttpUser):
|
330
|
-
host = "http://127.0.0.1:%i" % self.port
|
331
|
-
|
332
|
-
locust = MyUser(self.environment)
|
333
|
-
locust.client.get("/ultra_fast?query=1")
|
334
|
-
self.assertEqual(1, self.runner.stats.get("/ultra_fast?query=1", "GET").num_requests)
|
335
|
-
|
336
|
-
def test_request_stats_put(self):
|
337
|
-
class MyUser(FastHttpUser):
|
338
|
-
host = "http://127.0.0.1:%i" % self.port
|
339
|
-
|
340
|
-
locust = MyUser(self.environment)
|
341
|
-
locust.client.put("/put")
|
342
|
-
self.assertEqual(1, self.runner.stats.get("/put", "PUT").num_requests)
|
343
|
-
|
344
|
-
def test_request_connection_error(self):
|
345
|
-
class MyUser(FastHttpUser):
|
346
|
-
host = "http://localhost:1"
|
347
|
-
|
348
|
-
locust = MyUser(self.environment)
|
349
|
-
response = locust.client.get("/")
|
350
|
-
self.assertEqual(response.status_code, 0)
|
351
|
-
self.assertEqual(1, self.runner.stats.get("/", "GET").num_failures)
|
352
|
-
self.assertEqual(1, self.runner.stats.get("/", "GET").num_requests)
|
353
|
-
|
354
|
-
|
355
|
-
class TestFastHttpUserClass(WebserverTestCase):
|
356
|
-
def test_is_abstract(self):
|
357
|
-
self.assertTrue(FastHttpUser.abstract)
|
358
|
-
self.assertFalse(is_user_class(FastHttpUser))
|
359
|
-
|
360
|
-
def test_class_context(self):
|
361
|
-
class MyUser(FastHttpUser):
|
362
|
-
host = "http://127.0.0.1:%i" % self.port
|
363
|
-
|
364
|
-
def context(self):
|
365
|
-
return {"user": self.username}
|
366
|
-
|
367
|
-
kwargs = {}
|
368
|
-
|
369
|
-
def on_request(**kw):
|
370
|
-
kwargs.update(kw)
|
371
|
-
|
372
|
-
self.environment.events.request.add_listener(on_request)
|
373
|
-
user = MyUser(self.environment)
|
374
|
-
user.username = "foo"
|
375
|
-
user.client.request("get", "/request_method")
|
376
|
-
self.assertDictEqual({"user": "foo"}, kwargs["context"])
|
377
|
-
self.assertEqual("GET", kwargs["response"].text)
|
378
|
-
user.client.request("get", "/request_method", context={"user": "bar"})
|
379
|
-
self.assertDictEqual({"user": "bar"}, kwargs["context"])
|
380
|
-
|
381
|
-
def test_get_request(self):
|
382
|
-
self.response = ""
|
383
|
-
|
384
|
-
def t1(l):
|
385
|
-
self.response = l.client.get("/ultra_fast")
|
386
|
-
|
387
|
-
class MyUser(FastHttpUser):
|
388
|
-
tasks = [t1]
|
389
|
-
host = "http://127.0.0.1:%i" % self.port
|
390
|
-
|
391
|
-
my_locust = MyUser(self.environment)
|
392
|
-
t1(my_locust)
|
393
|
-
self.assertEqual(self.response.text, "This is an ultra fast response")
|
394
|
-
|
395
|
-
def test_client_request_headers(self):
|
396
|
-
class MyUser(FastHttpUser):
|
397
|
-
host = "http://127.0.0.1:%i" % self.port
|
398
|
-
|
399
|
-
locust = MyUser(self.environment)
|
400
|
-
r = locust.client.get("/request_header_test", headers={"X-Header-Test": "hello"})
|
401
|
-
self.assertEqual("hello", r.text)
|
402
|
-
self.assertEqual("hello", r.headers.get("X-Header-Test"))
|
403
|
-
self.assertEqual("hello", r.request.headers.get("X-Header-Test"))
|
404
|
-
|
405
|
-
def test_client_get(self):
|
406
|
-
class MyUser(FastHttpUser):
|
407
|
-
host = "http://127.0.0.1:%i" % self.port
|
408
|
-
|
409
|
-
locust = MyUser(self.environment)
|
410
|
-
self.assertEqual("GET", locust.client.get("/request_method").text)
|
411
|
-
|
412
|
-
def test_client_get_absolute_url(self):
|
413
|
-
class MyUser(FastHttpUser):
|
414
|
-
host = "http://127.0.0.1:%i" % self.port
|
415
|
-
|
416
|
-
locust = MyUser(self.environment)
|
417
|
-
self.assertEqual("GET", locust.client.get("http://127.0.0.1:%i/request_method" % self.port).text)
|
418
|
-
|
419
|
-
def test_client_post(self):
|
420
|
-
class MyUser(FastHttpUser):
|
421
|
-
host = "http://127.0.0.1:%i" % self.port
|
422
|
-
|
423
|
-
locust = MyUser(self.environment)
|
424
|
-
self.assertEqual("POST", locust.client.post("/request_method", {"arg": "hello world"}).text)
|
425
|
-
self.assertEqual("hello world", locust.client.post("/post", {"arg": "hello world"}).text)
|
426
|
-
|
427
|
-
def test_client_put(self):
|
428
|
-
class MyUser(FastHttpUser):
|
429
|
-
host = "http://127.0.0.1:%i" % self.port
|
430
|
-
|
431
|
-
locust = MyUser(self.environment)
|
432
|
-
self.assertEqual("PUT", locust.client.put("/request_method", {"arg": "hello world"}).text)
|
433
|
-
self.assertEqual("hello world", locust.client.put("/put", {"arg": "hello world"}).text)
|
434
|
-
|
435
|
-
def test_client_delete(self):
|
436
|
-
class MyUser(FastHttpUser):
|
437
|
-
host = "http://127.0.0.1:%i" % self.port
|
438
|
-
|
439
|
-
locust = MyUser(self.environment)
|
440
|
-
self.assertEqual("DELETE", locust.client.delete("/request_method").text)
|
441
|
-
self.assertEqual(200, locust.client.delete("/request_method").status_code)
|
442
|
-
|
443
|
-
def test_client_head(self):
|
444
|
-
class MyUser(FastHttpUser):
|
445
|
-
host = "http://127.0.0.1:%i" % self.port
|
446
|
-
|
447
|
-
locust = MyUser(self.environment)
|
448
|
-
self.assertEqual(200, locust.client.head("/request_method").status_code)
|
449
|
-
|
450
|
-
def test_complex_content_type(self):
|
451
|
-
class MyUser(FastHttpUser):
|
452
|
-
host = "http://127.0.0.1:%i" % self.port
|
453
|
-
|
454
|
-
locust = MyUser(self.environment)
|
455
|
-
|
456
|
-
self.assertEqual("stuff", locust.client.get("/content_type_missing_charset").text)
|
457
|
-
self.assertEqual("stuff", locust.client.get("/content_type_regular").text)
|
458
|
-
self.assertEqual("stuff", locust.client.get("/content_type_with_extra_stuff").text)
|
459
|
-
|
460
|
-
def test_log_request_name_argument(self):
|
461
|
-
self.response = ""
|
462
|
-
|
463
|
-
class MyUser(FastHttpUser):
|
464
|
-
tasks = []
|
465
|
-
host = "http://127.0.0.1:%i" % self.port
|
466
|
-
|
467
|
-
@task()
|
468
|
-
def t1(l):
|
469
|
-
self.response = l.client.get("/ultra_fast", name="new name!")
|
470
|
-
|
471
|
-
my_locust = MyUser(self.environment)
|
472
|
-
my_locust.t1()
|
473
|
-
|
474
|
-
self.assertEqual(1, self.runner.stats.get("new name!", "GET").num_requests)
|
475
|
-
self.assertEqual(0, self.runner.stats.get("/ultra_fast", "GET").num_requests)
|
476
|
-
|
477
|
-
def test_redirect_url_original_path_as_name(self):
|
478
|
-
class MyUser(FastHttpUser):
|
479
|
-
host = "http://127.0.0.1:%i" % self.port
|
480
|
-
|
481
|
-
l = MyUser(self.environment)
|
482
|
-
l.client.get("/redirect")
|
483
|
-
|
484
|
-
self.assertEqual(1, len(self.runner.stats.entries))
|
485
|
-
self.assertEqual(1, self.runner.stats.get("/redirect", "GET").num_requests)
|
486
|
-
self.assertEqual(0, self.runner.stats.get("/ultra_fast", "GET").num_requests)
|
487
|
-
|
488
|
-
def test_network_timeout_setting(self):
|
489
|
-
class MyUser(FastHttpUser):
|
490
|
-
network_timeout = 0.5
|
491
|
-
host = "http://127.0.0.1:%i" % self.port
|
492
|
-
|
493
|
-
l = MyUser(self.environment)
|
494
|
-
|
495
|
-
timeout = gevent.Timeout(
|
496
|
-
seconds=0.6,
|
497
|
-
exception=AssertionError(
|
498
|
-
"Request took longer than 0.6 even though FastHttpUser.network_timeout was set to 0.5"
|
499
|
-
),
|
500
|
-
)
|
501
|
-
timeout.start()
|
502
|
-
r = l.client.get("/redirect?url=/redirect&delay=5.0")
|
503
|
-
timeout.cancel()
|
504
|
-
|
505
|
-
self.assertTrue(isinstance(r.error.original, socket.timeout))
|
506
|
-
self.assertEqual(1, self.runner.stats.get("/redirect?url=/redirect&delay=5.0", "GET").num_failures)
|
507
|
-
|
508
|
-
def test_max_redirect_setting(self):
|
509
|
-
class MyUser(FastHttpUser):
|
510
|
-
max_redirects = 0
|
511
|
-
host = "http://127.0.0.1:%i" % self.port
|
512
|
-
|
513
|
-
l = MyUser(self.environment)
|
514
|
-
l.client.get("/redirect")
|
515
|
-
self.assertEqual(1, self.runner.stats.get("/redirect", "GET").num_failures)
|
516
|
-
|
517
|
-
def test_allow_redirects_override(self):
|
518
|
-
class MyLocust(FastHttpUser):
|
519
|
-
host = "http://127.0.0.1:%i" % self.port
|
520
|
-
|
521
|
-
l = MyLocust(self.environment)
|
522
|
-
resp = l.client.get("/redirect", allow_redirects=False)
|
523
|
-
self.assertTrue(resp.headers["location"].endswith("/ultra_fast"))
|
524
|
-
resp = l.client.get("/redirect") # ensure redirect still works
|
525
|
-
self.assertFalse("location" in resp.headers)
|
526
|
-
|
527
|
-
def test_slow_redirect(self):
|
528
|
-
s = FastHttpSession(self.environment, "http://127.0.0.1:%i" % self.port, user=None)
|
529
|
-
url = "/redirect?url=/redirect&delay=0.5"
|
530
|
-
s.get(url)
|
531
|
-
stats = self.runner.stats.get(url, method="GET")
|
532
|
-
self.assertEqual(1, stats.num_requests)
|
533
|
-
self.assertGreater(stats.avg_response_time, 500)
|
534
|
-
|
535
|
-
def test_client_basic_auth(self):
|
536
|
-
class MyUser(FastHttpUser):
|
537
|
-
host = "http://127.0.0.1:%i" % self.port
|
538
|
-
|
539
|
-
class MyAuthorizedUser(FastHttpUser):
|
540
|
-
host = "http://locust:menace@127.0.0.1:%i" % self.port
|
541
|
-
|
542
|
-
class MyUnauthorizedUser(FastHttpUser):
|
543
|
-
host = "http://locust:wrong@127.0.0.1:%i" % self.port
|
544
|
-
|
545
|
-
locust = MyUser(self.environment)
|
546
|
-
unauthorized = MyUnauthorizedUser(self.environment)
|
547
|
-
authorized = MyAuthorizedUser(self.environment)
|
548
|
-
response = authorized.client.get("/basic_auth")
|
549
|
-
self.assertEqual(200, response.status_code)
|
550
|
-
self.assertEqual("Authorized", response.text)
|
551
|
-
self.assertEqual(401, locust.client.get("/basic_auth").status_code)
|
552
|
-
self.assertEqual(401, unauthorized.client.get("/basic_auth").status_code)
|
553
|
-
|
554
|
-
def test_shared_client_pool(self):
|
555
|
-
shared_client_pool = HTTPClientPool(concurrency=1)
|
556
|
-
|
557
|
-
class MyUserA(FastHttpUser):
|
558
|
-
host = "http://127.0.0.1:%i" % self.port
|
559
|
-
client_pool = shared_client_pool
|
560
|
-
|
561
|
-
class MyUserB(FastHttpUser):
|
562
|
-
host = "http://127.0.0.1:%i" % self.port
|
563
|
-
client_pool = shared_client_pool
|
564
|
-
|
565
|
-
user_a = MyUserA(self.environment)
|
566
|
-
user_b = MyUserB(self.environment)
|
567
|
-
|
568
|
-
user_a.client.get("/ultra_fast")
|
569
|
-
user_b.client.get("/ultra_fast")
|
570
|
-
user_b.client.get("/ultra_fast")
|
571
|
-
user_a.client.get("/ultra_fast")
|
572
|
-
|
573
|
-
self.assertEqual(1, self.connections_count)
|
574
|
-
self.assertEqual(4, self.requests_count)
|
575
|
-
|
576
|
-
def test_client_pool_per_user_instance(self):
|
577
|
-
class MyUser(FastHttpUser):
|
578
|
-
host = "http://127.0.0.1:%i" % self.port
|
579
|
-
|
580
|
-
user_a = MyUser(self.environment)
|
581
|
-
user_b = MyUser(self.environment)
|
582
|
-
|
583
|
-
user_a.client.get("/ultra_fast")
|
584
|
-
user_b.client.get("/ultra_fast")
|
585
|
-
user_b.client.get("/ultra_fast")
|
586
|
-
user_a.client.get("/ultra_fast")
|
587
|
-
|
588
|
-
self.assertEqual(2, self.connections_count)
|
589
|
-
self.assertEqual(4, self.requests_count)
|
590
|
-
|
591
|
-
def test_client_pool_concurrency(self):
|
592
|
-
class MyUser(FastHttpUser):
|
593
|
-
host = "http://127.0.0.1:%i" % self.port
|
594
|
-
|
595
|
-
@task
|
596
|
-
def t(self):
|
597
|
-
def concurrent_request(url):
|
598
|
-
response = self.client.get(url)
|
599
|
-
assert response.status_code == 200
|
600
|
-
|
601
|
-
pool = gevent.pool.Pool()
|
602
|
-
urls = ["/slow?delay=0.2"] * 20 # these urls are all the same, but they could be different
|
603
|
-
for url in urls:
|
604
|
-
pool.spawn(concurrent_request, url)
|
605
|
-
pool.join()
|
606
|
-
|
607
|
-
user = MyUser(self.environment)
|
608
|
-
before_requests = time.time()
|
609
|
-
user.t()
|
610
|
-
after_requests = time.time()
|
611
|
-
expected_delta = 0.4 # 20 requests with concurrency 10 and response time 0.2
|
612
|
-
self.assertAlmostEqual(before_requests + expected_delta, after_requests, delta=0.1)
|
613
|
-
|
614
|
-
|
615
|
-
class TestFastHttpCatchResponse(WebserverTestCase):
|
616
|
-
def setUp(self):
|
617
|
-
super().setUp()
|
618
|
-
|
619
|
-
class MyUser(FastHttpUser):
|
620
|
-
host = "http://127.0.0.1:%i" % self.port
|
621
|
-
|
622
|
-
self.user = MyUser(self.environment)
|
623
|
-
|
624
|
-
self.num_failures = 0
|
625
|
-
self.num_success = 0
|
626
|
-
|
627
|
-
def on_request(exception, **kwargs):
|
628
|
-
if exception:
|
629
|
-
self.num_failures += 1
|
630
|
-
self.last_failure_exception = exception
|
631
|
-
else:
|
632
|
-
self.num_success += 1
|
633
|
-
|
634
|
-
self.environment.events.request.add_listener(on_request)
|
635
|
-
|
636
|
-
def test_catch_response(self):
|
637
|
-
self.assertEqual(500, self.user.client.get("/fail").status_code)
|
638
|
-
self.assertEqual(1, self.num_failures)
|
639
|
-
self.assertEqual(0, self.num_success)
|
640
|
-
|
641
|
-
with self.user.client.get("/ultra_fast", catch_response=True) as response:
|
642
|
-
pass
|
643
|
-
self.assertEqual(1, self.num_failures)
|
644
|
-
self.assertEqual(1, self.num_success)
|
645
|
-
self.assertIn("ultra fast", str(response.content))
|
646
|
-
|
647
|
-
with self.user.client.get("/ultra_fast", catch_response=True) as response:
|
648
|
-
raise ResponseError("Not working")
|
649
|
-
|
650
|
-
self.assertEqual(2, self.num_failures)
|
651
|
-
self.assertEqual(1, self.num_success)
|
652
|
-
|
653
|
-
def test_catch_response_http_fail(self):
|
654
|
-
with self.user.client.get("/fail", catch_response=True):
|
655
|
-
pass
|
656
|
-
self.assertEqual(1, self.num_failures)
|
657
|
-
self.assertEqual(0, self.num_success)
|
658
|
-
|
659
|
-
def test_catch_response_http_manual_fail(self):
|
660
|
-
with self.user.client.get("/ultra_fast", catch_response=True) as response:
|
661
|
-
response.failure("Haha!")
|
662
|
-
self.assertEqual(1, self.num_failures)
|
663
|
-
self.assertEqual(0, self.num_success)
|
664
|
-
self.assertTrue(
|
665
|
-
isinstance(self.last_failure_exception, CatchResponseError),
|
666
|
-
"Failure event handler should have been passed a CatchResponseError instance",
|
667
|
-
)
|
668
|
-
|
669
|
-
def test_catch_response_http_manual_success(self):
|
670
|
-
with self.user.client.get("/fail", catch_response=True) as response:
|
671
|
-
response.success()
|
672
|
-
self.assertEqual(0, self.num_failures)
|
673
|
-
self.assertEqual(1, self.num_success)
|
674
|
-
|
675
|
-
def test_catch_response_allow_404(self):
|
676
|
-
with self.user.client.get("/does/not/exist", catch_response=True) as response:
|
677
|
-
self.assertEqual(404, response.status_code)
|
678
|
-
if response.status_code == 404:
|
679
|
-
response.success()
|
680
|
-
self.assertEqual(0, self.num_failures)
|
681
|
-
self.assertEqual(1, self.num_success)
|
682
|
-
|
683
|
-
def test_interrupt_taskset_with_catch_response(self):
|
684
|
-
class MyTaskSet(TaskSet):
|
685
|
-
@task
|
686
|
-
def interrupted_task(self):
|
687
|
-
with self.client.get("/ultra_fast", catch_response=True):
|
688
|
-
raise InterruptTaskSet()
|
689
|
-
|
690
|
-
class MyUser(FastHttpUser):
|
691
|
-
host = "http://127.0.0.1:%i" % self.port
|
692
|
-
tasks = [MyTaskSet]
|
693
|
-
|
694
|
-
l = MyUser(self.environment)
|
695
|
-
ts = MyTaskSet(l)
|
696
|
-
self.assertRaises(InterruptTaskSet, lambda: ts.interrupted_task())
|
697
|
-
self.assertEqual(0, self.num_failures)
|
698
|
-
self.assertEqual(0, self.num_success)
|
699
|
-
|
700
|
-
def test_catch_response_connection_error_success(self):
|
701
|
-
class MyUser(FastHttpUser):
|
702
|
-
host = "http://127.0.0.1:1"
|
703
|
-
|
704
|
-
l = MyUser(self.environment)
|
705
|
-
with l.client.get("/", catch_response=True) as r:
|
706
|
-
self.assertEqual(r.status_code, 0)
|
707
|
-
self.assertEqual(None, r.content)
|
708
|
-
r.success()
|
709
|
-
self.assertEqual(1, self.num_success)
|
710
|
-
self.assertEqual(0, self.num_failures)
|
711
|
-
|
712
|
-
def test_catch_response_connection_error_fail(self):
|
713
|
-
class MyUser(FastHttpUser):
|
714
|
-
host = "http://127.0.0.1:1"
|
715
|
-
|
716
|
-
l = MyUser(self.environment)
|
717
|
-
with l.client.get("/", catch_response=True) as r:
|
718
|
-
self.assertEqual(r.status_code, 0)
|
719
|
-
self.assertEqual(None, r.content)
|
720
|
-
r.failure("Manual fail")
|
721
|
-
self.assertEqual(0, self.num_success)
|
722
|
-
self.assertEqual(1, self.num_failures)
|
723
|
-
|
724
|
-
def test_catch_response_missing_with_block(self):
|
725
|
-
# incorrect usage, missing with-block
|
726
|
-
r = self.user.client.get("/fail", catch_response=True)
|
727
|
-
self.assertRaises(LocustError, r.success)
|
728
|
-
self.assertRaises(LocustError, r.failure, "")
|
729
|
-
|
730
|
-
def test_missing_catch_response_true(self):
|
731
|
-
# incorrect usage, missing catch_response=True
|
732
|
-
with self.user.client.get("/fail") as resp:
|
733
|
-
self.assertRaises(LocustError, resp.success)
|
734
|
-
|
735
|
-
def test_rest_success(self):
|
736
|
-
self.last_failure_exception = None
|
737
|
-
with self.user.rest("POST", "/rest", json={"foo": "bar"}) as response:
|
738
|
-
assert response.js["foo"] == "bar"
|
739
|
-
|
740
|
-
self.assertEqual(0, self.num_failures)
|
741
|
-
self.assertEqual(1, self.num_success)
|
742
|
-
|
743
|
-
def test_rest_fail(self):
|
744
|
-
with self.user.rest("POST", "/rest", json={"foo": "bar"}) as response:
|
745
|
-
assert response.js["foo"] == "NOPE"
|
746
|
-
|
747
|
-
self.assertTrue(
|
748
|
-
isinstance(self.last_failure_exception, CatchResponseError),
|
749
|
-
"Failure event handler should have been passed a CatchResponseError instance",
|
750
|
-
)
|
751
|
-
self.assertEqual(1, self.num_failures)
|
752
|
-
self.assertEqual(0, self.num_success)
|
753
|
-
|
754
|
-
|
755
|
-
class TestFastHttpSsl(LocustTestCase):
|
756
|
-
def setUp(self):
|
757
|
-
super().setUp()
|
758
|
-
tls_cert, tls_key = create_tls_cert("127.0.0.1")
|
759
|
-
self.tls_cert_file = NamedTemporaryFile()
|
760
|
-
self.tls_key_file = NamedTemporaryFile()
|
761
|
-
with open(self.tls_cert_file.name, "w") as f:
|
762
|
-
f.write(tls_cert.decode())
|
763
|
-
with open(self.tls_key_file.name, "w") as f:
|
764
|
-
f.write(tls_key.decode())
|
765
|
-
|
766
|
-
self.web_ui = self.environment.create_web_ui(
|
767
|
-
"127.0.0.1",
|
768
|
-
0,
|
769
|
-
tls_cert=self.tls_cert_file.name,
|
770
|
-
tls_key=self.tls_key_file.name,
|
771
|
-
)
|
772
|
-
gevent.sleep(0.01)
|
773
|
-
self.web_port = self.web_ui.server.server_port
|
774
|
-
|
775
|
-
def tearDown(self):
|
776
|
-
super().tearDown()
|
777
|
-
self.web_ui.stop()
|
778
|
-
|
779
|
-
def test_ssl_request_insecure(self):
|
780
|
-
s = FastHttpSession(self.environment, "https://127.0.0.1:%i" % self.web_port, insecure=True, user=None)
|
781
|
-
response = s.get("/")
|
782
|
-
d = pq(response.content.decode("utf-8"))
|
783
|
-
|
784
|
-
self.assertEqual(200, response.status_code)
|
785
|
-
self.assertIn('"users": null', str(d))
|