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.
Files changed (42) hide show
  1. locust/_version.py +6 -2
  2. locust/contrib/fasthttp.py +1 -1
  3. locust/dispatch.py +7 -6
  4. locust/main.py +0 -1
  5. {locust-2.29.2.dev34.dist-info → locust-2.29.2.dev45.dist-info}/METADATA +31 -26
  6. locust-2.29.2.dev45.dist-info/RECORD +49 -0
  7. locust-2.29.2.dev45.dist-info/WHEEL +4 -0
  8. locust-2.29.2.dev45.dist-info/entry_points.txt +3 -0
  9. locust/test/__init__.py +0 -15
  10. locust/test/fake_module1_for_env_test.py +0 -7
  11. locust/test/fake_module2_for_env_test.py +0 -7
  12. locust/test/mock_locustfile.py +0 -56
  13. locust/test/mock_logging.py +0 -28
  14. locust/test/test_debugging.py +0 -39
  15. locust/test/test_dispatch.py +0 -4170
  16. locust/test/test_env.py +0 -283
  17. locust/test/test_fasthttp.py +0 -785
  18. locust/test/test_http.py +0 -325
  19. locust/test/test_interruptable_task.py +0 -48
  20. locust/test/test_load_locustfile.py +0 -228
  21. locust/test/test_locust_class.py +0 -831
  22. locust/test/test_log.py +0 -237
  23. locust/test/test_main.py +0 -2264
  24. locust/test/test_old_wait_api.py +0 -0
  25. locust/test/test_parser.py +0 -450
  26. locust/test/test_runners.py +0 -4476
  27. locust/test/test_sequential_taskset.py +0 -157
  28. locust/test/test_stats.py +0 -866
  29. locust/test/test_tags.py +0 -440
  30. locust/test/test_taskratio.py +0 -94
  31. locust/test/test_users.py +0 -69
  32. locust/test/test_util.py +0 -33
  33. locust/test/test_wait_time.py +0 -79
  34. locust/test/test_web.py +0 -1257
  35. locust/test/test_zmqrpc.py +0 -58
  36. locust/test/testcases.py +0 -248
  37. locust/test/util.py +0 -88
  38. locust-2.29.2.dev34.dist-info/RECORD +0 -79
  39. locust-2.29.2.dev34.dist-info/WHEEL +0 -5
  40. locust-2.29.2.dev34.dist-info/entry_points.txt +0 -2
  41. locust-2.29.2.dev34.dist-info/top_level.txt +0 -1
  42. {locust-2.29.2.dev34.dist-info → locust-2.29.2.dev45.dist-info}/LICENSE +0 -0
locust/test/test_http.py DELETED
@@ -1,325 +0,0 @@
1
- from locust.clients import HttpSession
2
- from locust.exception import LocustError, ResponseError
3
- from locust.user.users import HttpUser
4
-
5
- import time
6
-
7
- from requests.exceptions import InvalidSchema, InvalidURL, MissingSchema, RequestException
8
-
9
- from .testcases import WebserverTestCase
10
-
11
-
12
- class TestHttpSession(WebserverTestCase):
13
- def get_client(self, base_url=None):
14
- if base_url is None:
15
- base_url = "http://127.0.0.1:%i" % self.port
16
- return HttpSession(
17
- base_url=base_url,
18
- request_event=self.environment.events.request,
19
- user=None,
20
- )
21
-
22
- def test_get(self):
23
- s = self.get_client()
24
- r = s.get("/ultra_fast")
25
- self.assertEqual(200, r.status_code)
26
-
27
- def test_connection_error(self):
28
- s = self.get_client(base_url="http://localhost:1")
29
- r = s.get("/", timeout=0.1)
30
- self.assertEqual(r.status_code, 0)
31
- self.assertEqual(None, r.content)
32
- self.assertRaises(RequestException, r.raise_for_status)
33
-
34
- def test_wrong_url(self):
35
- for url, exception in (
36
- ("http://\x94", InvalidURL),
37
- ("telnet://127.0.0.1", InvalidSchema),
38
- ("127.0.0.1", MissingSchema),
39
- ):
40
- s = self.get_client(base_url=url)
41
- try:
42
- self.assertRaises(exception, s.get, "/")
43
- except KeyError:
44
- self.fail(f"Invalid URL {url} was not propagated")
45
-
46
- def test_streaming_response(self):
47
- """
48
- Test a request to an endpoint that returns a streaming response
49
- """
50
- s = self.get_client()
51
- r = s.get("/streaming/30")
52
-
53
- # verify that the time reported includes the download time of the whole streamed response
54
- self.assertGreater(self.runner.stats.get("/streaming/30", method="GET").avg_response_time, 250)
55
- self.runner.stats.clear_all()
56
-
57
- # verify that response time does NOT include whole download time, when using stream=True
58
- r = s.get("/streaming/30", stream=True)
59
- self.assertGreater(self.runner.stats.get("/streaming/30", method="GET").avg_response_time, 0)
60
- self.assertLess(self.runner.stats.get("/streaming/30", method="GET").avg_response_time, 250)
61
-
62
- # download the content of the streaming response (so we don't get an ugly exception in the log)
63
- _ = r.content
64
-
65
- def test_slow_redirect(self):
66
- s = self.get_client()
67
- url = "/redirect?url=/redirect&delay=0.5"
68
- s.get(url)
69
- stats = self.runner.stats.get(url, method="GET")
70
- self.assertEqual(1, stats.num_requests)
71
- self.assertGreater(stats.avg_response_time, 500)
72
-
73
- def test_post_redirect(self):
74
- s = self.get_client()
75
- url = "/redirect"
76
- r = s.post(url)
77
- self.assertEqual(200, r.status_code)
78
- post_stats = self.runner.stats.get(url, method="POST")
79
- get_stats = self.runner.stats.get(url, method="GET")
80
- self.assertEqual(1, post_stats.num_requests)
81
- self.assertEqual(0, get_stats.num_requests)
82
-
83
- def test_cookie(self):
84
- s = self.get_client()
85
- r = s.post("/set_cookie?name=testcookie&value=1337")
86
- self.assertEqual(200, r.status_code)
87
- r = s.get("/get_cookie?name=testcookie")
88
- self.assertEqual("1337", r.content.decode())
89
-
90
- def test_head(self):
91
- s = self.get_client()
92
- r = s.head("/request_method")
93
- self.assertEqual(200, r.status_code)
94
- self.assertEqual("", r.content.decode())
95
-
96
- def test_delete(self):
97
- s = self.get_client()
98
- r = s.delete("/request_method")
99
- self.assertEqual(200, r.status_code)
100
- self.assertEqual("DELETE", r.content.decode())
101
-
102
- def test_options(self):
103
- s = self.get_client()
104
- r = s.options("/request_method")
105
- self.assertEqual(200, r.status_code)
106
- self.assertEqual("", r.content.decode())
107
- self.assertEqual(
108
- {"OPTIONS", "DELETE", "PUT", "GET", "POST", "HEAD", "PATCH"},
109
- set(r.headers["allow"].split(", ")),
110
- )
111
-
112
- def test_error_message(self):
113
- s = self.get_client()
114
- kwargs = {}
115
-
116
- def on_request(**kw):
117
- kwargs.update(kw)
118
-
119
- self.environment.events.request.add_listener(on_request)
120
- s.request("get", "/wrong_url", context={"foo": "bar"})
121
- self.assertIn("/wrong_url", str(kwargs["exception"]))
122
- self.assertDictEqual({"foo": "bar"}, kwargs["context"])
123
-
124
- def test_context_in_success(self):
125
- s = self.get_client()
126
- kwargs = {}
127
-
128
- def on_request(exception, **kw):
129
- self.assertIsNone(exception)
130
- kwargs.update(kw)
131
-
132
- self.environment.events.request.add_listener(on_request)
133
- s.request("get", "/request_method", context={"foo": "bar"})
134
- self.assertDictEqual({"foo": "bar"}, kwargs["context"])
135
-
136
- def test_response_parameter(self):
137
- s = self.get_client()
138
- kwargs = {}
139
-
140
- def on_request(**kw):
141
- kwargs.update(kw)
142
-
143
- self.environment.events.request.add_listener(on_request)
144
- s.request("get", "/request_method")
145
- self.assertEqual("GET", kwargs["response"].text)
146
- s.request("get", "/wrong_url")
147
- self.assertEqual("Not Found", kwargs["response"].text)
148
-
149
- def test_error_message_with_name_replacement(self):
150
- s = self.get_client()
151
- kwargs = {}
152
-
153
- def on_request(**kw):
154
- self.assertIsNotNone(kw["exception"])
155
- kwargs.update(kw)
156
-
157
- self.environment.events.request.add_listener(on_request)
158
- before_request = time.time()
159
- s.request("get", "/wrong_url/01", name="replaced_url_name", context={"foo": "bar"})
160
- after_request = time.time()
161
- self.assertIn("for url: replaced_url_name", str(kwargs["exception"]))
162
- self.assertAlmostEqual(before_request, kwargs["start_time"], delta=0.01)
163
- self.assertAlmostEqual(after_request, kwargs["start_time"] + kwargs["response_time"] / 1000, delta=0.01)
164
- self.assertEqual(s.base_url + "/wrong_url/01", kwargs["url"]) # url is unaffected by name
165
- self.assertDictEqual({"foo": "bar"}, kwargs["context"])
166
-
167
- def test_get_with_params(self):
168
- s = self.get_client()
169
- r = s.get("/get_arg", params={"arg": "test_123"})
170
- self.assertEqual(200, r.status_code)
171
- self.assertEqual("test_123", r.text)
172
-
173
- def test_catch_response_fail_successful_request(self):
174
- s = self.get_client()
175
- with s.get("/ultra_fast", catch_response=True) as r:
176
- r.failure("nope")
177
- self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_requests)
178
- self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_failures)
179
-
180
- def test_catch_response_fail_successful_request_with_non_string_error_message(self):
181
- s = self.get_client()
182
- with s.get("/ultra_fast", catch_response=True) as r:
183
- r.failure({"other types are also wrapped as exceptions": True})
184
- self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_requests)
185
- self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_failures)
186
-
187
- def test_catch_response_pass_failed_request(self):
188
- s = self.get_client()
189
- with s.get("/fail", catch_response=True) as r:
190
- r.success()
191
- self.assertEqual(1, self.environment.stats.total.num_requests)
192
- self.assertEqual(0, self.environment.stats.total.num_failures)
193
-
194
- def test_catch_response_multiple_failure_and_success(self):
195
- s = self.get_client()
196
- with s.get("/ultra_fast", catch_response=True) as r:
197
- r.failure("nope")
198
- r.success()
199
- r.failure("nooo")
200
- r.success()
201
- self.assertEqual(1, self.environment.stats.total.num_requests)
202
- self.assertEqual(0, self.environment.stats.total.num_failures)
203
-
204
- def test_catch_response_timeout(self):
205
- s = self.get_client()
206
- with s.get("/slow", catch_response=True, timeout=0.1) as r:
207
- self.assertAlmostEqual(r.request_meta["response_time"], 100, delta=50)
208
- self.assertEqual(1, self.environment.stats.total.num_requests)
209
- self.assertEqual(1, self.environment.stats.total.num_failures)
210
-
211
- def test_catch_response_pass_failed_request_with_other_exception_within_block(self):
212
- class OtherException(Exception):
213
- pass
214
-
215
- s = self.get_client()
216
- try:
217
- with s.get("/fail", catch_response=True) as r:
218
- r.success()
219
- raise OtherException("wtf")
220
- except OtherException:
221
- pass
222
- else:
223
- self.fail("OtherException should have been raised")
224
-
225
- self.assertEqual(1, self.environment.stats.total.num_requests)
226
- self.assertEqual(0, self.environment.stats.total.num_failures)
227
-
228
- def test_catch_response_response_error(self):
229
- s = self.get_client()
230
- try:
231
- with s.get("/fail", catch_response=True):
232
- raise ResponseError("response error")
233
- except ResponseError:
234
- self.fail("ResponseError should not have been raised")
235
-
236
- self.assertEqual(1, self.environment.stats.total.num_requests)
237
- self.assertEqual(1, self.environment.stats.total.num_failures)
238
-
239
- def test_catch_response_default_success(self):
240
- s = self.get_client()
241
- with s.get("/ultra_fast", catch_response=True):
242
- pass
243
- self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_requests)
244
- self.assertEqual(0, self.environment.stats.get("/ultra_fast", "GET").num_failures)
245
-
246
- def test_catch_response_default_fail(self):
247
- s = self.get_client()
248
- with s.get("/fail", catch_response=True):
249
- pass
250
- self.assertEqual(1, self.environment.stats.total.num_requests)
251
- self.assertEqual(1, self.environment.stats.total.num_failures)
252
-
253
- def test_catch_response_with_name_replacement(self):
254
- s = self.get_client()
255
- kwargs = {}
256
-
257
- def on_request(**kw):
258
- self.assertIsNotNone(kw["exception"])
259
- kwargs.update(kw)
260
-
261
- self.environment.events.request.add_listener(on_request)
262
-
263
- with s.get("/wrong_url/01", name="replaced_url_name"):
264
- pass
265
-
266
- self.assertIn("for url: replaced_url_name", str(kwargs["exception"]))
267
- self.assertEqual(s.base_url + "/wrong_url/01", kwargs["url"]) # url is unaffected by name
268
-
269
- def test_catch_response_missing_with_block(self):
270
- s = self.get_client()
271
- # incorrect usage, missing with-block
272
- r = s.get("/fail", catch_response=True)
273
- self.assertRaises(LocustError, r.success)
274
- self.assertRaises(LocustError, r.failure, "")
275
-
276
- def test_missing_catch_response_true(self):
277
- s = self.get_client()
278
- # incorrect usage, missing catch_response=True
279
- with s.get("/fail") as resp:
280
- self.assertRaises(LocustError, resp.success)
281
-
282
- def test_event_measure(self):
283
- kwargs = {}
284
-
285
- def on_request(**kw):
286
- kwargs.update(**kw)
287
-
288
- self.environment.events.request.add_listener(on_request)
289
-
290
- with self.environment.events.request.measure("GET", "/test") as request_meta:
291
- time.sleep(0.001)
292
-
293
- self.assertTrue(1 <= kwargs["response_time"] <= 1.5, kwargs["response_time"])
294
- self.assertEqual(kwargs["name"], "/test")
295
- self.assertIsNone(kwargs["exception"])
296
-
297
- with self.environment.events.request.measure("GET", "/test") as request_meta:
298
- request_meta["foo"] = "bar"
299
- raise Exception("nooo")
300
-
301
- self.assertEqual(kwargs["name"], "/test")
302
- self.assertEqual(kwargs["foo"], "bar")
303
- self.assertEqual(str(kwargs["exception"]), "nooo")
304
-
305
- def test_user_context(self):
306
- class TestUser(HttpUser):
307
- host = f"http://127.0.0.1:{self.port}"
308
-
309
- def context(self):
310
- return {"user": self.username}
311
-
312
- kwargs = {}
313
-
314
- def on_request(**kw):
315
- kwargs.update(kw)
316
-
317
- self.environment.events.request.add_listener(on_request)
318
-
319
- user = TestUser(self.environment)
320
- user.username = "foo"
321
- user.client.request("get", "/request_method")
322
- self.assertDictEqual({"user": "foo"}, kwargs["context"])
323
- self.assertEqual("GET", kwargs["response"].text)
324
- user.client.request("get", "/request_method", context={"user": "bar"}) # override User context
325
- self.assertDictEqual({"user": "bar"}, kwargs["context"])
@@ -1,48 +0,0 @@
1
- from locust import SequentialTaskSet, User, constant, task
2
- from locust.env import Environment
3
- from locust.exception import StopUser
4
-
5
- from collections import defaultdict
6
- from unittest import TestCase
7
-
8
-
9
- class InterruptableTaskSet(SequentialTaskSet):
10
- counter: defaultdict[str, int] = defaultdict(int)
11
-
12
- def on_start(self):
13
- super().on_start()
14
- self.counter["on_start"] += 1
15
-
16
- @task
17
- def t1(self):
18
- self.counter["t1"] += 1
19
- self.interrupt(reschedule=False)
20
-
21
- @task
22
- def t2(self):
23
- self.counter["t2"] += 1
24
-
25
- def on_stop(self):
26
- super().on_stop()
27
- self.counter["on_stop"] += 1
28
- if self.counter["on_stop"] >= 2:
29
- raise StopUser()
30
-
31
-
32
- class TestInterruptableTask(TestCase):
33
- def setUp(self):
34
- super().setUp()
35
-
36
- class InterruptableUser(User):
37
- host = "127.0.0.1"
38
- tasks = [InterruptableTaskSet]
39
- wait_time = constant(0)
40
-
41
- self.locust = InterruptableUser(Environment(catch_exceptions=True))
42
-
43
- def test_interruptable_task(self):
44
- self.locust.run()
45
- self.assertEqual(InterruptableTaskSet.counter.get("on_start"), 2)
46
- self.assertEqual(InterruptableTaskSet.counter.get("t1"), 2)
47
- self.assertEqual(InterruptableTaskSet.counter.get("t2", 0), 0)
48
- self.assertEqual(InterruptableTaskSet.counter.get("on_stop"), 2)
@@ -1,228 +0,0 @@
1
- from locust import main
2
- from locust.argument_parser import parse_locustfile_option, parse_options
3
- from locust.main import create_environment
4
- from locust.user import HttpUser, TaskSet, User
5
- from locust.util.load_locustfile import is_user_class
6
-
7
- import filecmp
8
- import os
9
- import pathlib
10
- import textwrap
11
-
12
- from .mock_locustfile import MOCK_LOCUSTFILE_CONTENT, mock_locustfile
13
- from .testcases import LocustTestCase
14
- from .util import temporary_file
15
-
16
-
17
- class TestLoadLocustfile(LocustTestCase):
18
- def test_is_user_class(self):
19
- self.assertFalse(is_user_class(User))
20
- self.assertFalse(is_user_class(HttpUser))
21
- self.assertFalse(is_user_class({}))
22
- self.assertFalse(is_user_class([]))
23
-
24
- class MyTaskSet(TaskSet):
25
- pass
26
-
27
- class MyHttpUser(HttpUser):
28
- tasks = [MyTaskSet]
29
-
30
- class MyUser(User):
31
- tasks = [MyTaskSet]
32
-
33
- self.assertTrue(is_user_class(MyHttpUser))
34
- self.assertTrue(is_user_class(MyUser))
35
-
36
- class ThriftLocust(User):
37
- abstract = True
38
-
39
- self.assertFalse(is_user_class(ThriftLocust))
40
-
41
- def test_load_locust_file_from_absolute_path(self):
42
- with mock_locustfile() as mocked:
43
- docstring, user_classes, shape_classes = main.load_locustfile(mocked.file_path)
44
- self.assertIn("UserSubclass", user_classes)
45
- self.assertNotIn("NotUserSubclass", user_classes)
46
- self.assertNotIn("LoadTestShape", user_classes)
47
- self.assertEqual(shape_classes, [])
48
-
49
- def test_load_locust_file_from_relative_path(self):
50
- with mock_locustfile() as mocked:
51
- docstring, user_classes, shape_classes = main.load_locustfile(
52
- os.path.join(os.path.relpath(mocked.directory, os.getcwd()), mocked.filename)
53
- )
54
-
55
- def test_load_locust_file_called_locust_dot_py(self):
56
- with mock_locustfile() as mocked:
57
- new_filename = mocked.file_path.replace(mocked.filename, "locust.py")
58
- os.rename(mocked.file_path, new_filename)
59
- try:
60
- docstring, user_classes, shape_classes = main.load_locustfile(new_filename)
61
- finally:
62
- # move it back, so it can be deleted
63
- os.rename(new_filename, mocked.file_path)
64
-
65
- def test_load_locust_file_with_a_dot_in_filename(self):
66
- with mock_locustfile(filename_prefix="mocked.locust.file") as mocked:
67
- docstring, user_classes, shape_classes = main.load_locustfile(mocked.file_path)
68
-
69
- def test_return_docstring_and_user_classes(self):
70
- with mock_locustfile() as mocked:
71
- docstring, user_classes, shape_classes = main.load_locustfile(mocked.file_path)
72
- self.assertEqual("This is a mock locust file for unit testing", docstring)
73
- self.assertIn("UserSubclass", user_classes)
74
- self.assertNotIn("NotUserSubclass", user_classes)
75
- self.assertNotIn("LoadTestShape", user_classes)
76
-
77
- def test_with_shape_class(self):
78
- content = (
79
- MOCK_LOCUSTFILE_CONTENT
80
- + """class LoadTestShape(LoadTestShape):
81
- def tick(self):
82
- return None
83
- """
84
- )
85
- with mock_locustfile(content=content) as mocked:
86
- docstring, user_classes, shape_classes = main.load_locustfile(mocked.file_path)
87
- self.assertEqual("This is a mock locust file for unit testing", docstring)
88
- self.assertIn("UserSubclass", user_classes)
89
- self.assertNotIn("NotUserSubclass", user_classes)
90
- self.assertEqual(shape_classes[0].__class__.__name__, "LoadTestShape")
91
-
92
- def test_with_multiple_shape_classes(self):
93
- content = MOCK_LOCUSTFILE_CONTENT + textwrap.dedent(
94
- """\
95
- class LoadTestShape1(LoadTestShape):
96
- def tick(self):
97
- pass
98
-
99
- class LoadTestShape2(LoadTestShape):
100
- def tick(self):
101
- pass
102
- """
103
- )
104
- with mock_locustfile(content=content) as mocked:
105
- docstring, user_classes, shape_classes = main.load_locustfile(mocked.file_path)
106
- self.assertEqual("This is a mock locust file for unit testing", docstring)
107
- self.assertIn("UserSubclass", user_classes)
108
- self.assertNotIn("NotUserSubclass", user_classes)
109
- self.assertEqual(shape_classes[0].__class__.__name__, "LoadTestShape1")
110
- self.assertEqual(shape_classes[1].__class__.__name__, "LoadTestShape2")
111
-
112
- def test_with_abstract_shape_class(self):
113
- content = MOCK_LOCUSTFILE_CONTENT + textwrap.dedent(
114
- """\
115
- class UserBaseLoadTestShape(LoadTestShape):
116
- abstract = True
117
-
118
- def tick(self):
119
- pass
120
-
121
-
122
- class UserLoadTestShape(UserBaseLoadTestShape):
123
- pass
124
- """
125
- )
126
-
127
- with mock_locustfile(content=content) as mocked:
128
- _, user_classes, shape_classes = main.load_locustfile(mocked.file_path)
129
- self.assertNotIn("UserBaseLoadTestShape", user_classes)
130
- self.assertNotIn("UserLoadTestShape", user_classes)
131
- self.assertEqual(shape_classes[0].__class__.__name__, "UserLoadTestShape")
132
-
133
- def test_with_not_imported_shape_class(self):
134
- content = MOCK_LOCUSTFILE_CONTENT + textwrap.dedent(
135
- """\
136
- class UserLoadTestShape(LoadTestShape):
137
- def tick(self):
138
- pass
139
- """
140
- )
141
-
142
- with mock_locustfile(content=content) as mocked:
143
- _, user_classes, shape_classes = main.load_locustfile(mocked.file_path)
144
- self.assertNotIn("UserLoadTestShape", user_classes)
145
- self.assertEqual(shape_classes[0].__class__.__name__, "UserLoadTestShape")
146
-
147
- def test_create_environment(self):
148
- options = parse_options(
149
- args=[
150
- "--host",
151
- "https://custom-host",
152
- "--reset-stats",
153
- ]
154
- )
155
- env = create_environment([], options)
156
- self.assertEqual("https://custom-host", env.host)
157
- self.assertTrue(env.reset_stats)
158
-
159
- options = parse_options(args=[])
160
- env = create_environment([], options)
161
- self.assertEqual(None, env.host)
162
- self.assertFalse(env.reset_stats)
163
-
164
- def test_specify_config_file(self):
165
- with temporary_file(
166
- textwrap.dedent(
167
- """
168
- host = localhost # With "="
169
- u 100 # Short form
170
- spawn-rate 5 # long form
171
- # boolean
172
- headless
173
- # (for some reason an inline comment makes boolean values fail in configargparse nowadays)
174
- """
175
- ),
176
- suffix=".conf",
177
- ) as conf_file_path:
178
- options = parse_options(
179
- args=[
180
- "--config",
181
- conf_file_path,
182
- ]
183
- )
184
- self.assertEqual(conf_file_path, options.config)
185
- self.assertEqual("localhost", options.host)
186
- self.assertEqual(100, options.num_users)
187
- self.assertEqual(5, options.spawn_rate)
188
- self.assertTrue(options.headless)
189
-
190
- def test_command_line_arguments_override_config_file(self):
191
- with temporary_file("host=from_file", suffix=".conf") as conf_file_path:
192
- options = parse_options(
193
- args=[
194
- "--config",
195
- conf_file_path,
196
- "--host",
197
- "from_args",
198
- ]
199
- )
200
- self.assertEqual("from_args", options.host)
201
-
202
- def test_locustfile_can_be_set_in_config_file(self):
203
- with temporary_file(
204
- "locustfile my_locust_file.py",
205
- suffix=".conf",
206
- ) as conf_file_path:
207
- options = parse_options(
208
- args=[
209
- "--config",
210
- conf_file_path,
211
- ]
212
- )
213
- self.assertEqual("my_locust_file.py", options.locustfile)
214
-
215
- def test_locustfile_from_url(self):
216
- locustfiles = parse_locustfile_option(
217
- args=[
218
- "-f",
219
- "https://raw.githubusercontent.com/locustio/locust/master/examples/basic.py",
220
- ]
221
- )
222
- self.assertEqual(len(locustfiles), 1)
223
- self.assertTrue(
224
- filecmp.cmp(
225
- locustfiles[0],
226
- f"{os.getcwd()}/examples/basic.py",
227
- )
228
- )