def test_requests_csv_quote_escaping(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: environment = Environment() master = environment.create_master_runner(master_bind_host="*", master_bind_port=0) server.mocked_send(Message("client_ready", None, "fake_client")) request_name_dict = { "scenario": "get cashes", "path": "/cash/[amount]", "arguments": [{ "size": 1 }], } request_name_str = json.dumps(request_name_dict) master.stats.get(request_name_str, "GET").log(100, 23455) data = {"user_count": 1} environment.events.report_to_master.fire(client_id="fake_client", data=data) master.stats.clear_all() server.mocked_send(Message("stats", data, "fake_client")) locust.stats.write_csv_files(environment, self.STATS_BASE_NAME, full_history=True) with open(self.STATS_FILENAME) as f: reader = csv.DictReader(f) rows = [r for r in reader] csv_request_name = rows[0].get("Name") self.assertEqual(request_name_str, csv_request_name)
def test_csv_stats_on_master_from_aggregated_stats(self): # Failing test for: https://github.com/locustio/locust/issues/1315 with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: environment = Environment() master = environment.create_master_runner(master_bind_host="*", master_bind_port=0) server.mocked_send(Message("client_ready", None, "fake_client")) master.stats.get("/", "GET").log(100, 23455) master.stats.get("/", "GET").log(800, 23455) master.stats.get("/", "GET").log(700, 23455) data = {"user_count": 1} environment.events.report_to_master.fire(client_id="fake_client", data=data) master.stats.clear_all() server.mocked_send(Message("stats", data, "fake_client")) s = master.stats.get("/", "GET") self.assertEqual(700, s.median_response_time) locust.stats.write_csv_files(environment, self.STATS_BASE_NAME, full_history=True) self.assertTrue(os.path.exists(self.STATS_FILENAME)) self.assertTrue(os.path.exists(self.STATS_HISTORY_FILENAME)) self.assertTrue(os.path.exists(self.STATS_FAILURES_FILENAME))
def test_csv_stats_on_master_from_aggregated_stats(self): # Failing test for: https://github.com/locustio/locust/issues/1315 with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: environment = Environment() stats_writer = StatsCSVFileWriter( environment, PERCENTILES_TO_REPORT, self.STATS_BASE_NAME, full_history=True ) master = environment.create_master_runner(master_bind_host="*", master_bind_port=0) greenlet = gevent.spawn(stats_writer) gevent.sleep(_TEST_CSV_STATS_INTERVAL_WAIT_SEC) server.mocked_send(Message("client_ready", __version__, "fake_client")) master.stats.get("/", "GET").log(100, 23455) master.stats.get("/", "GET").log(800, 23455) master.stats.get("/", "GET").log(700, 23455) data = {"user_count": 1} environment.events.report_to_master.fire(client_id="fake_client", data=data) master.stats.clear_all() server.mocked_send(Message("stats", data, "fake_client")) s = master.stats.get("/", "GET") self.assertEqual(700, s.median_response_time) gevent.kill(greenlet) stats_writer.close_files() self.assertTrue(os.path.exists(self.STATS_FILENAME)) self.assertTrue(os.path.exists(self.STATS_HISTORY_FILENAME)) self.assertTrue(os.path.exists(self.STATS_FAILURES_FILENAME)) self.assertTrue(os.path.exists(self.STATS_EXCEPTIONS_FILENAME))
def test_distributed_integration_run(self): """ Full integration test that starts both a MasterRunner and three WorkerRunner instances and makes sure that their stats is sent to the Master. """ class TestUser(User): wait_time = constant(0.1) @task def incr_stats(l): l.environment.events.request_success.fire( request_type="GET", name="/", response_time=1337, response_length=666, ) with mock.patch("locust.runners.WORKER_REPORT_INTERVAL", new=0.3): # start a Master runner master_env = Environment(user_classes=[TestUser]) master = master_env.create_master_runner("*", 0) sleep(0) # start 3 Worker runners workers = [] for i in range(3): worker_env = Environment(user_classes=[TestUser]) worker = worker_env.create_worker_runner( "127.0.0.1", master.server.port) workers.append(worker) # give workers time to connect sleep(0.1) # issue start command that should trigger TestUsers to be spawned in the Workers master.start(6, hatch_rate=1000) sleep(0.1) # check that slave nodes have started locusts for worker in workers: self.assertEqual(2, worker.user_count) # give time for users to generate stats, and stats to be sent to master sleep(1) master.quit() # make sure users are killed for worker in workers: self.assertEqual(0, worker.user_count) # check that stats are present in master self.assertGreater( master_env.runner.stats.total.num_requests, 20, "For some reason the master node's stats has not come in", )
def test_stats_history(self): env1 = Environment(events=locust.events, catch_exceptions=False) runner1 = env1.create_master_runner("127.0.0.1", 5558) env2 = Environment(events=locust.events, catch_exceptions=False) runner2 = env2.create_worker_runner("127.0.0.1", 5558) greenlet1 = gevent.spawn(stats_history, runner1) greenlet2 = gevent.spawn(stats_history, runner2) gevent.sleep(1) hs1 = runner1.stats.history hs2 = runner2.stats.history gevent.kill(greenlet1) gevent.kill(greenlet2) self.assertEqual(1, len(hs1)) self.assertEqual(0, len(hs2))
class TestMasterRunner(LocustTestCase): def setUp(self): super(TestMasterRunner, self).setUp() self.environment = Environment(events=locust.events, catch_exceptions=False) def tearDown(self): super(TestMasterRunner, self).tearDown() def get_runner(self): return self.environment.create_master_runner("*", 5557) def test_worker_connect(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send( Message("client_ready", None, "zeh_fake_client1")) self.assertEqual(1, len(master.clients)) self.assertTrue( "zeh_fake_client1" in master.clients, "Could not find fake client in master instance's clients dict") server.mocked_send( Message("client_ready", None, "zeh_fake_client2")) server.mocked_send( Message("client_ready", None, "zeh_fake_client3")) server.mocked_send( Message("client_ready", None, "zeh_fake_client4")) self.assertEqual(4, len(master.clients)) server.mocked_send(Message("quit", None, "zeh_fake_client3")) self.assertEqual(3, len(master.clients)) def test_worker_stats_report_median(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "fake_client")) master.stats.get("/", "GET").log(100, 23455) master.stats.get("/", "GET").log(800, 23455) master.stats.get("/", "GET").log(700, 23455) data = {"user_count": 1} self.environment.events.report_to_master.fire( client_id="fake_client", data=data) master.stats.clear_all() server.mocked_send(Message("stats", data, "fake_client")) s = master.stats.get("/", "GET") self.assertEqual(700, s.median_response_time) def test_worker_stats_report_with_none_response_times(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "fake_client")) master.stats.get("/mixed", "GET").log(0, 23455) master.stats.get("/mixed", "GET").log(800, 23455) master.stats.get("/mixed", "GET").log(700, 23455) master.stats.get("/mixed", "GET").log(None, 23455) master.stats.get("/mixed", "GET").log(None, 23455) master.stats.get("/mixed", "GET").log(None, 23455) master.stats.get("/mixed", "GET").log(None, 23455) master.stats.get("/onlyNone", "GET").log(None, 23455) data = {"user_count": 1} self.environment.events.report_to_master.fire( client_id="fake_client", data=data) master.stats.clear_all() server.mocked_send(Message("stats", data, "fake_client")) s1 = master.stats.get("/mixed", "GET") self.assertEqual(700, s1.median_response_time) self.assertEqual(500, s1.avg_response_time) s2 = master.stats.get("/onlyNone", "GET") self.assertEqual(0, s2.median_response_time) self.assertEqual(0, s2.avg_response_time) def test_master_marks_downed_workers_as_missing(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "fake_client")) sleep(6) # print(master.clients['fake_client'].__dict__) assert master.clients['fake_client'].state == STATE_MISSING def test_last_worker_quitting_stops_test(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "fake_client1")) server.mocked_send(Message("client_ready", None, "fake_client2")) master.start(1, 2) server.mocked_send(Message("hatching", None, "fake_client1")) server.mocked_send(Message("hatching", None, "fake_client2")) server.mocked_send(Message("quit", None, "fake_client1")) sleep(0) self.assertEqual(1, len(master.clients.all)) self.assertNotEqual( STATE_STOPPED, master.state, "Not all workers quit but test stopped anyway.") server.mocked_send(Message("quit", None, "fake_client2")) sleep(0) self.assertEqual(0, len(master.clients.all)) self.assertEqual(STATE_STOPPED, master.state, "All workers quit but test didn't stop.") @mock.patch("locust.runners.HEARTBEAT_INTERVAL", new=0.1) def test_last_worker_missing_stops_test(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "fake_client1")) server.mocked_send(Message("client_ready", None, "fake_client2")) master.start(1, 2) server.mocked_send(Message("hatching", None, "fake_client1")) server.mocked_send(Message("hatching", None, "fake_client2")) sleep(0.3) server.mocked_send( Message("heartbeat", { 'state': STATE_RUNNING, 'current_cpu_usage': 50 }, "fake_client1")) sleep(0.3) self.assertEqual(1, len(master.clients.missing)) self.assertNotEqual( STATE_STOPPED, master.state, "Not all workers went missing but test stopped anyway.") sleep(0.3) self.assertEqual(2, len(master.clients.missing)) self.assertEqual(STATE_STOPPED, master.state, "All workers went missing but test didn't stop.") def test_master_total_stats(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "fake_client")) stats = RequestStats() stats.log_request("GET", "/1", 100, 3546) stats.log_request("GET", "/1", 800, 56743) stats2 = RequestStats() stats2.log_request("GET", "/2", 700, 2201) server.mocked_send( Message( "stats", { "stats": stats.serialize_stats(), "stats_total": stats.total.serialize(), "errors": stats.serialize_errors(), "user_count": 1, }, "fake_client")) server.mocked_send( Message( "stats", { "stats": stats2.serialize_stats(), "stats_total": stats2.total.serialize(), "errors": stats2.serialize_errors(), "user_count": 2, }, "fake_client")) self.assertEqual(700, master.stats.total.median_response_time) def test_master_total_stats_with_none_response_times(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send(Message("client_ready", None, "fake_client")) stats = RequestStats() stats.log_request("GET", "/1", 100, 3546) stats.log_request("GET", "/1", 800, 56743) stats.log_request("GET", "/1", None, 56743) stats2 = RequestStats() stats2.log_request("GET", "/2", 700, 2201) stats2.log_request("GET", "/2", None, 2201) stats3 = RequestStats() stats3.log_request("GET", "/3", None, 2201) server.mocked_send( Message( "stats", { "stats": stats.serialize_stats(), "stats_total": stats.total.serialize(), "errors": stats.serialize_errors(), "user_count": 1, }, "fake_client")) server.mocked_send( Message( "stats", { "stats": stats2.serialize_stats(), "stats_total": stats2.total.serialize(), "errors": stats2.serialize_errors(), "user_count": 2, }, "fake_client")) server.mocked_send( Message( "stats", { "stats": stats3.serialize_stats(), "stats_total": stats3.total.serialize(), "errors": stats3.serialize_errors(), "user_count": 2, }, "fake_client")) self.assertEqual(700, master.stats.total.median_response_time) def test_master_current_response_times(self): start_time = 1 with mock.patch("time.time") as mocked_time: mocked_time.return_value = start_time with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() self.environment.stats.reset_all() mocked_time.return_value += 1.0234 server.mocked_send(Message("client_ready", None, "fake_client")) stats = RequestStats() stats.log_request("GET", "/1", 100, 3546) stats.log_request("GET", "/1", 800, 56743) server.mocked_send( Message( "stats", { "stats": stats.serialize_stats(), "stats_total": stats.total.get_stripped_report(), "errors": stats.serialize_errors(), "user_count": 1, }, "fake_client")) mocked_time.return_value += 1 stats2 = RequestStats() stats2.log_request("GET", "/2", 400, 2201) server.mocked_send( Message( "stats", { "stats": stats2.serialize_stats(), "stats_total": stats2.total.get_stripped_report(), "errors": stats2.serialize_errors(), "user_count": 2, }, "fake_client")) mocked_time.return_value += 4 self.assertEqual( 400, master.stats.total.get_current_response_time_percentile( 0.5)) self.assertEqual( 800, master.stats.total.get_current_response_time_percentile( 0.95)) # let 10 second pass, do some more requests, send it to the master and make # sure the current response time percentiles only accounts for these new requests mocked_time.return_value += 10.10023 stats.log_request("GET", "/1", 20, 1) stats.log_request("GET", "/1", 30, 1) stats.log_request("GET", "/1", 3000, 1) server.mocked_send( Message( "stats", { "stats": stats.serialize_stats(), "stats_total": stats.total.get_stripped_report(), "errors": stats.serialize_errors(), "user_count": 2, }, "fake_client")) self.assertEqual( 30, master.stats.total.get_current_response_time_percentile( 0.5)) self.assertEqual( 3000, master.stats.total.get_current_response_time_percentile( 0.95)) def test_rebalance_locust_users_on_worker_connect(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() server.mocked_send( Message("client_ready", None, "zeh_fake_client1")) self.assertEqual(1, len(master.clients)) self.assertTrue( "zeh_fake_client1" in master.clients, "Could not find fake client in master instance's clients dict") master.start(100, 20) self.assertEqual(1, len(server.outbox)) client_id, msg = server.outbox.pop() self.assertEqual(100, msg.data["num_users"]) self.assertEqual(20, msg.data["hatch_rate"]) # let another worker connect server.mocked_send( Message("client_ready", None, "zeh_fake_client2")) self.assertEqual(2, len(master.clients)) self.assertEqual(2, len(server.outbox)) client_id, msg = server.outbox.pop() self.assertEqual(50, msg.data["num_users"]) self.assertEqual(10, msg.data["hatch_rate"]) client_id, msg = server.outbox.pop() self.assertEqual(50, msg.data["num_users"]) self.assertEqual(10, msg.data["hatch_rate"]) def test_sends_hatch_data_to_ready_running_hatching_workers(self): '''Sends hatch job to running, ready, or hatching workers''' with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() master.clients[1] = WorkerNode(1) master.clients[2] = WorkerNode(2) master.clients[3] = WorkerNode(3) master.clients[1].state = STATE_INIT master.clients[2].state = STATE_HATCHING master.clients[3].state = STATE_RUNNING master.start(user_count=5, hatch_rate=5) self.assertEqual(3, len(server.outbox)) def test_start_event(self): """ Tests that test_start event is fired """ with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() run_count = [0] @self.environment.events.test_start.add_listener def on_test_start(*a, **kw): run_count[0] += 1 for i in range(5): server.mocked_send( Message("client_ready", None, "fake_client%i" % i)) master.start(7, 7) self.assertEqual(5, len(server.outbox)) self.assertEqual(1, run_count[0]) # change number of users and check that test_start isn't fired again master.start(7, 7) self.assertEqual(1, run_count[0]) # stop and start to make sure test_start is fired again master.stop() master.start(3, 3) self.assertEqual(2, run_count[0]) master.quit() def test_stop_event(self): """ Tests that test_stop event is fired """ with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() run_count = [0] @self.environment.events.test_stop.add_listener def on_test_stop(*a, **kw): run_count[0] += 1 for i in range(5): server.mocked_send( Message("client_ready", None, "fake_client%i" % i)) master.start(7, 7) self.assertEqual(5, len(server.outbox)) master.stop() self.assertEqual(1, run_count[0]) run_count[0] = 0 for i in range(5): server.mocked_send( Message("client_ready", None, "fake_client%i" % i)) master.start(7, 7) master.stop() master.quit() self.assertEqual(1, run_count[0]) def test_stop_event_quit(self): """ Tests that test_stop event is fired when quit() is called directly """ with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() run_count = [0] @self.environment.events.test_stop.add_listener def on_test_stop(*a, **kw): run_count[0] += 1 for i in range(5): server.mocked_send( Message("client_ready", None, "fake_client%i" % i)) master.start(7, 7) self.assertEqual(5, len(server.outbox)) master.quit() self.assertEqual(1, run_count[0]) def test_spawn_zero_locusts(self): class MyTaskSet(TaskSet): @task def my_task(self): pass class MyTestUser(User): tasks = [MyTaskSet] wait_time = constant(0.1) environment = Environment(user_classes=[MyTestUser]) runner = LocalRunner(environment) timeout = gevent.Timeout(2.0) timeout.start() try: runner.start(0, 1, wait=True) runner.hatching_greenlet.join() except gevent.Timeout: self.fail( "Got Timeout exception. A locust seems to have been spawned, even though 0 was specified." ) finally: timeout.cancel() def test_spawn_uneven_locusts(self): """ Tests that we can accurately spawn a certain number of locusts, even if it's not an even number of the connected workers """ with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() for i in range(5): server.mocked_send( Message("client_ready", None, "fake_client%i" % i)) master.start(7, 7) self.assertEqual(5, len(server.outbox)) num_users = 0 for _, msg in server.outbox: num_users += msg.data["num_users"] self.assertEqual( 7, num_users, "Total number of locusts that would have been spawned is not 7" ) def test_spawn_fewer_locusts_than_workers(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() for i in range(5): server.mocked_send( Message("client_ready", None, "fake_client%i" % i)) master.start(2, 2) self.assertEqual(5, len(server.outbox)) num_users = 0 for _, msg in server.outbox: num_users += msg.data["num_users"] self.assertEqual( 2, num_users, "Total number of locusts that would have been spawned is not 2" ) def test_spawn_locusts_in_stepload_mode(self): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() for i in range(5): server.mocked_send( Message("client_ready", None, "fake_client%i" % i)) # start a new swarming in Step Load mode: total locust count of 10, hatch rate of 2, step locust count of 5, step duration of 2s master.start_stepload(10, 2, 5, 2) # make sure the first step run is started sleep(0.5) self.assertEqual(5, len(server.outbox)) num_users = 0 end_of_last_step = len(server.outbox) for _, msg in server.outbox: num_users += msg.data["num_users"] self.assertEqual( 5, num_users, "Total number of locusts that would have been spawned for first step is not 5" ) # make sure the first step run is complete sleep(2) num_users = 0 idx = end_of_last_step while idx < len(server.outbox): msg = server.outbox[idx][1] num_users += msg.data["num_users"] idx += 1 self.assertEqual( 10, num_users, "Total number of locusts that would have been spawned for second step is not 10" ) def test_exception_in_task(self): class MyUser(User): @task def will_error(self): raise HeyAnException(":(") self.environment.user_classes = [MyUser] runner = self.environment.create_local_runner() l = MyUser(self.environment) self.assertRaises(HeyAnException, l.run) self.assertRaises(HeyAnException, l.run) self.assertEqual(1, len(runner.exceptions)) hash_key, exception = runner.exceptions.popitem() self.assertTrue("traceback" in exception) self.assertTrue("HeyAnException" in exception["traceback"]) self.assertEqual(2, exception["count"]) def test_exception_is_catched(self): """ Test that exceptions are stored, and execution continues """ class MyTaskSet(TaskSet): def __init__(self, *a, **kw): super(MyTaskSet, self).__init__(*a, **kw) self._task_queue = [ { "callable": self.will_error, "args": [], "kwargs": {} }, { "callable": self.will_stop, "args": [], "kwargs": {} }, ] @task(1) def will_error(self): raise HeyAnException(":(") @task(1) def will_stop(self): raise StopUser() class MyUser(User): wait_time = constant(0.01) tasks = [MyTaskSet] # set config to catch exceptions in locust users self.environment.catch_exceptions = True self.environment.user_classes = [MyUser] runner = LocalRunner(self.environment) l = MyUser(self.environment) # make sure HeyAnException isn't raised l.run() l.run() # make sure we got two entries in the error log self.assertEqual(2, len(self.mocked_log.error)) # make sure exception was stored self.assertEqual(1, len(runner.exceptions)) hash_key, exception = runner.exceptions.popitem() self.assertTrue("traceback" in exception) self.assertTrue("HeyAnException" in exception["traceback"]) self.assertEqual(2, exception["count"]) def test_master_reset_connection(self): """ Test that connection will be reset when network issues found """ with mock.patch("locust.runners.FALLBACK_INTERVAL", new=0.1): with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server: master = self.get_runner() self.assertEqual(0, len(master.clients)) server.mocked_send( Message("client_ready", NETWORK_BROKEN, "fake_client")) self.assertTrue(master.connection_broken) server.mocked_send(Message("client_ready", None, "fake_client")) sleep(0.2) self.assertFalse(master.connection_broken) self.assertEqual(1, len(master.clients)) master.quit()
from locust import HttpUser, task, SequentialTaskSet from locust_plugins.transaction_manager import TransactionManager class ExampleSequentialTaskSet(SequentialTaskSet): def on_start(self): self.tm = TransactionManager() @task def home(self): self.tm.start_transaction("startup") self.client.get("/", name="01 /") @task def get_config_json(self): self.client.get("/config.json", name="02 /config.json") self.tm.end_transaction("startup") class TranactionExample(HttpUser): host = "https://www.demoblaze.com" tasks = [ExampleSequentialTaskSet] env = Environment(user_classes=[TranactionExample]) env.create_master_runner() web_ui = env.create_web_ui("127.0.0.1", 8089) locust.events.init.fire(environment=env, runner=env.runner, web_ui=web_ui) env.events.worker_report.add_listener(TransactionManager._worker_report) env.runner.greenlet.join()