locust 2.29.2.dev34__py3-none-any.whl → 2.29.2.dev42__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.
Files changed (40) hide show
  1. locust/_version.py +6 -2
  2. locust/contrib/fasthttp.py +1 -1
  3. locust/dispatch.py +7 -6
  4. {locust-2.29.2.dev34.dist-info → locust-2.29.2.dev42.dist-info}/METADATA +31 -26
  5. {locust-2.29.2.dev34.dist-info → locust-2.29.2.dev42.dist-info}/RECORD +16 -46
  6. locust-2.29.2.dev42.dist-info/WHEEL +4 -0
  7. locust-2.29.2.dev42.dist-info/entry_points.txt +3 -0
  8. locust/test/__init__.py +0 -15
  9. locust/test/fake_module1_for_env_test.py +0 -7
  10. locust/test/fake_module2_for_env_test.py +0 -7
  11. locust/test/mock_locustfile.py +0 -56
  12. locust/test/mock_logging.py +0 -28
  13. locust/test/test_debugging.py +0 -39
  14. locust/test/test_dispatch.py +0 -4170
  15. locust/test/test_env.py +0 -283
  16. locust/test/test_fasthttp.py +0 -785
  17. locust/test/test_http.py +0 -325
  18. locust/test/test_interruptable_task.py +0 -48
  19. locust/test/test_load_locustfile.py +0 -228
  20. locust/test/test_locust_class.py +0 -831
  21. locust/test/test_log.py +0 -237
  22. locust/test/test_main.py +0 -2264
  23. locust/test/test_old_wait_api.py +0 -0
  24. locust/test/test_parser.py +0 -450
  25. locust/test/test_runners.py +0 -4476
  26. locust/test/test_sequential_taskset.py +0 -157
  27. locust/test/test_stats.py +0 -866
  28. locust/test/test_tags.py +0 -440
  29. locust/test/test_taskratio.py +0 -94
  30. locust/test/test_users.py +0 -69
  31. locust/test/test_util.py +0 -33
  32. locust/test/test_wait_time.py +0 -79
  33. locust/test/test_web.py +0 -1257
  34. locust/test/test_zmqrpc.py +0 -58
  35. locust/test/testcases.py +0 -248
  36. locust/test/util.py +0 -88
  37. locust-2.29.2.dev34.dist-info/WHEEL +0 -5
  38. locust-2.29.2.dev34.dist-info/entry_points.txt +0 -2
  39. locust-2.29.2.dev34.dist-info/top_level.txt +0 -1
  40. {locust-2.29.2.dev34.dist-info → locust-2.29.2.dev42.dist-info}/LICENSE +0 -0
@@ -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))