def test_user_count_in_csv_history_stats(self): start_time = int(time.time()) class TestUser(User): wait_time = constant(10) @task def t(self): self.environment.runner.stats.log_request("GET", "/", 10, 10) environment = Environment(user_classes=[TestUser]) runner = environment.create_local_runner() runner.start(3, 5) # spawn a user every 0.2 second gevent.sleep(0.1) greenlet = gevent.spawn(stats_writer, environment, self.STATS_BASE_NAME, full_history=True) gevent.sleep(0.6) gevent.kill(greenlet) runner.stop() with open(self.STATS_HISTORY_FILENAME) as f: reader = csv.DictReader(f) rows = [r for r in reader] self.assertEqual(6, len(rows)) for i in range(3): row = rows.pop(0) self.assertEqual("%i" % (i + 1), row["User Count"]) self.assertEqual("/", row["Name"]) self.assertEqual("%i" % (i + 1), row["Total Request Count"]) self.assertGreaterEqual(int(row["Timestamp"]), start_time) row = rows.pop(0) self.assertEqual("%i" % (i + 1), row["User Count"]) self.assertEqual("Aggregated", row["Name"]) self.assertEqual("%i" % (i + 1), row["Total Request Count"]) self.assertGreaterEqual(int(row["Timestamp"]), start_time)
def test_env_exclude_tags(self): class MyTaskSet(User): @tag('exclude this') @task def excluded(self): pass @tag('dont exclude this') @task def not_excluded(self): pass @task def dont_exclude_this_either(self): pass class MyUser(User): tasks = [MyTaskSet] env = Environment(user_classes=[MyUser], exclude_tags=['exclude this']) env._filter_tasks_by_tags() self.assertListEqual(MyUser.tasks, [MyTaskSet]) self.assertListEqual( MyUser.tasks[0].tasks, [MyTaskSet.not_excluded, MyTaskSet.dont_exclude_this_either])
def test_stop_timeout_exit_during_wait(self): short_time = 0.05 class MyTaskSet(TaskSet): @task def my_task(self): pass class MyTestUser(User): tasks = [MyTaskSet] wait_time = between(1, 1) environment = Environment(user_classes=[MyTestUser], stop_timeout=short_time) runner = environment.create_local_runner() runner.start(1, 1) gevent.sleep( short_time ) # sleep to make sure locust has had time to start waiting timeout = gevent.Timeout(short_time) timeout.start() try: runner.quit() runner.greenlet.join() except gevent.Timeout: self.fail( "Got Timeout exception. Waiting locusts should stop immediately, even when using stop_timeout." ) finally: timeout.cancel()
def test_weight_locusts(self): maxDiff = 2048 class BaseUser(User): pass class L1(BaseUser): weight = 101 class L2(BaseUser): weight = 99 class L3(BaseUser): weight = 100 runner = Environment(user_classes=[L1, L2, L3]).create_local_runner() self.assert_locust_class_distribution({ L1: 10, L2: 9, L3: 10 }, runner.weight_users(29)) self.assert_locust_class_distribution({ L1: 10, L2: 10, L3: 10 }, runner.weight_users(30)) self.assert_locust_class_distribution({ L1: 11, L2: 10, L3: 10 }, runner.weight_users(31))
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_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 run(settings): """ Run the load test programmatically. """ env = Environment( user_classes=[getattr(main, settings["persona_arg"])], host=settings["base_url"], ) env.create_local_runner() # start a greenlet that saves current stats to history gevent.spawn(stats_history, env.runner) # start the load test env.runner.start(user_count=int(settings["users"]), spawn_rate=int(settings["users"])) # add a listener for failures env.events.request_failure.add_listener(main.failure_handler) # stop the runner at the end duration_s = parse_timespan(settings["duration"]) gevent.spawn_later(duration_s, lambda: stop(env)) # wait for the greenlets env.runner.greenlet.join()
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 run_single_user( locust_class: User, env=None, catch_exceptions=False, include_length=False, include_time=False, include_context=False, init_listener=None, loglevel=None, ): _gevent_debugger_patch() if loglevel: locust.log.setup_logging(loglevel) if env is None: env = Environment() env.parsed_options = argument_parser.parse_options() listeners.Print(env, include_length=include_length, include_time=include_time, include_context=include_context) env.events.init.fire(environment=env, runner=None, web_ui=None) if init_listener: init_listener(env) locust_class._catch_exceptions = catch_exceptions locust_class(env).run()
def setUp(self): # Prevent args passed to test runner from being passed to Locust del sys.argv[1:] locust.events = Events() self.environment = Environment(events=locust.events, catch_exceptions=False) self.runner = self.environment.create_local_runner() # When running the tests in Python 3 we get warnings about unclosed sockets. # This causes tests that depends on calls to sys.stderr to fail, so we'll # suppress those warnings. For more info see: # https://github.com/requests/requests/issues/1882 try: warnings.filterwarnings(action="ignore", message="unclosed <socket object", category=ResourceWarning) except NameError: # ResourceWarning doesn't exist in Python 2, but since the warning only appears # on Python 3 we don't need to mock it. Instead we can happily ignore the exception pass # set up mocked logging handler self._logger_class = MockedLoggingHandler() self._logger_class.setLevel(logging.INFO) self._root_log_handlers = [h for h in logging.root.handlers] [logging.root.removeHandler(h) for h in logging.root.handlers] logging.root.addHandler(self._logger_class) logging.root.setLevel(logging.INFO) self.mocked_log = MockedLoggingHandler # set unhandled exception flag to False log.unhandled_greenlet_exception = False
def test_distributed_integration_run(self): """ Full integration test that starts both a MasterLocustRunner and three WorkerLocustRunner instances and makes sure that their stats is sent to the Master. """ class TestUser(Locust): 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() master = MasterLocustRunner(master_env, [TestUser], master_bind_host="*", master_bind_port=0) sleep(0) # start 3 Worker runners workers = [] for i in range(3): worker_env = Environment() worker = WorkerLocustRunner(worker_env, [TestUser], master_host="127.0.0.1", master_port=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 run(self): """ Run the load test. """ if self.settings.run_time: self.set_run_time_in_sec(run_time_str=self.settings.run_time) logger.info("Run time limit set to %s seconds" % self.run_time_in_sec) def timelimit_stop(): logger.info( "Run time limit reached: %s seconds. Stopping Locust Runner." % self.run_time_in_sec) self.env.runner.quit() self.end_time = time.time() logger.info("Locust completed %s requests with %s errors" % (self.env.runner.stats.num_requests, len(self.env.runner.errors))) logger.info(json.dumps(self.stats())) gevent.spawn_later(self.run_time_in_sec, timelimit_stop) try: logger.info("Starting Locust with settings %s " % vars(self.settings)) self.env = Environment( user_classes=self.settings.classes, host=self.settings.host, tags=self.settings.tags, exclude_tags=self.settings.exclude_tags, reset_stats=self.settings.reset_stats, step_load=self.settings.step_load, stop_timeout=self.settings.stop_timeout, ) self.env.create_local_runner() gevent.spawn(stats_printer(self.env.stats)) self.env.runner.start(user_count=self.settings.num_users, hatch_rate=self.settings.hatch_rate) self.start_time = time.time() self.env.runner.greenlet.join() except Exception as e: logger.error("Locust exception {0}".format(repr(e))) finally: self.env.events.quitting.fire()
def test_weight_locusts_fewer_amount_than_user_classes(self): class BaseUser(User): pass class L1(BaseUser): weight = 101 class L2(BaseUser): weight = 99 class L3(BaseUser): weight = 100 runner = Environment(user_classes=[L1, L2, L3]).create_local_runner() self.assertEqual(1, len(runner.weight_users(1))) self.assert_locust_class_distribution({L1:1}, runner.weight_users(1))
def test_user_count_in_csv_history_stats(self): start_time = int(time.time()) class TestUser(User): wait_time = constant(10) @task def t(self): self.environment.runner.stats.log_request("GET", "/", 10, 10) environment = Environment(user_classes=[TestUser]) stats_writer = StatsCSVFileWriter(environment, PERCENTILES_TO_REPORT, self.STATS_BASE_NAME, full_history=True) runner = environment.create_local_runner() # spawn a user every _TEST_CSV_STATS_INTERVAL_SEC second user_count = 15 spawn_rate = 5 assert 1 / 5 == _TEST_CSV_STATS_INTERVAL_SEC runner_greenlet = gevent.spawn(runner.start, user_count, spawn_rate) gevent.sleep(0.1) greenlet = gevent.spawn(stats_writer) gevent.sleep(user_count / spawn_rate) gevent.kill(greenlet) stats_writer.close_files() runner.stop() gevent.kill(runner_greenlet) with open(self.STATS_HISTORY_FILENAME) as f: reader = csv.DictReader(f) rows = [r for r in reader] self.assertEqual(2 * user_count, len(rows)) for i in range(int(user_count / spawn_rate)): for _ in range(spawn_rate): row = rows.pop(0) self.assertEqual("%i" % ((i + 1) * spawn_rate), row["User Count"]) self.assertEqual("/", row["Name"]) self.assertEqual("%i" % ((i + 1) * spawn_rate), row["Total Request Count"]) self.assertGreaterEqual(int(row["Timestamp"]), start_time) row = rows.pop(0) self.assertEqual("%i" % ((i + 1) * spawn_rate), row["User Count"]) self.assertEqual("Aggregated", row["Name"]) self.assertEqual("%i" % ((i + 1) * spawn_rate), row["Total Request Count"]) self.assertGreaterEqual(int(row["Timestamp"]), start_time)
def test_interrupt_taskset_in_main_taskset(self): class MyTaskSet(TaskSet): @task def interrupted_task(self): raise InterruptTaskSet(reschedule=False) class MyLocust(Locust): host = "http://127.0.0.1" task_set = MyTaskSet class MyTaskSet2(TaskSet): @task def interrupted_task(self): self.interrupt() class MyLocust2(Locust): host = "http://127.0.0.1" task_set = MyTaskSet2 l = MyLocust(Environment()) l2 = MyLocust2(Environment()) self.assertRaises(LocustError, lambda: l.run()) self.assertRaises(LocustError, lambda: l2.run()) try: l.run() except LocustError as e: self.assertTrue( "MyLocust" in e.args[0], "MyLocust should have been referred to in the exception message" ) self.assertTrue( "MyTaskSet" in e.args[0], "MyTaskSet should have been referred to in the exception message" ) except: raise try: l2.run() except LocustError as e: self.assertTrue( "MyLocust2" in e.args[0], "MyLocust2 should have been referred to in the exception message" ) self.assertTrue( "MyTaskSet2" in e.args[0], "MyTaskSet2 should have been referred to in the exception message" ) except: raise
def locust_executor(host, port, collection_name, connection_type="single", run_params=None): m = MilvusClient(host=host, port=port, collection_name=collection_name) MyUser.tasks = {} MyUser.op_info = run_params["op_info"] MyUser.params = {} tasks = run_params["tasks"] for op, value in tasks.items(): task = {eval("Tasks." + op): value["weight"]} MyUser.tasks.update(task) MyUser.params[op] = value["params"] if "params" in value else None logger.info(MyUser.tasks) MyUser.tasks = {Tasks.load: 1, Tasks.flush: 1} MyUser.client = MilvusTask(host=host, port=port, collection_name=collection_name, connection_type=connection_type, m=m) # MyUser.info = m.get_info(collection_name) env = Environment(events=events, user_classes=[MyUser]) runner = env.create_local_runner() # setup logging # setup_logging("WARNING", "/dev/null") # greenlet_exception_logger(logger=logger) gevent.spawn(stats_printer(env.stats)) # env.create_web_ui("127.0.0.1", 8089) # gevent.spawn(stats_printer(env.stats), env, "test", full_history=True) # events.init.fire(environment=env, runner=runner) clients_num = run_params["clients_num"] spawn_rate = run_params["spawn_rate"] during_time = run_params["during_time"] runner.start(clients_num, spawn_rate=spawn_rate) gevent.spawn_later(during_time, lambda: runner.quit()) runner.greenlet.join() print_stats(env.stats) result = { "rps": round(env.stats.total.current_rps, 1), "fail_ratio": env.stats.total.fail_ratio, "max_response_time": round(env.stats.total.max_response_time, 1), "avg_response_time": round(env.stats.total.avg_response_time, 1) } runner.stop() return result
def setUp(self): super(TestTaskSet, self).setUp() class User(Locust): host = "127.0.0.1" self.environment = Environment() self.locust = User(self.environment)
def test_taskset_setup_method_exception(self): class User(Locust): setup_run_count = 0 task_run_count = 0 locust_error_count = 0 wait_time = constant(1) @task class task_set(TaskSet): def setup(self): User.setup_run_count += 1 raise Exception("some exception") @task def my_task(self): User.task_run_count += 1 environment = Environment(options=mocked_options()) def on_locust_error(*args, **kwargs): User.locust_error_count += 1 environment.events.locust_error.add_listener(on_locust_error) runner = LocalLocustRunner(environment, locust_classes=[User]) runner.start(locust_count=3, hatch_rate=3, wait=False) runner.hatching_greenlet.get(timeout=3) self.assertEqual(1, User.setup_run_count) self.assertEqual(1, User.locust_error_count) self.assertEqual(3, User.task_run_count)
def test_reset_stats(self): class User(Locust): wait_time = constant(0) @task class task_set(TaskSet): @task def my_task(self): self.locust.environment.events.request_success.fire( request_type="GET", name="/test", response_time=666, response_length=1337, ) sleep(2) environment = Environment(reset_stats=True, options=mocked_options()) runner = LocalLocustRunner(environment, locust_classes=[User]) runner.start(locust_count=6, hatch_rate=12, wait=False) sleep(0.25) self.assertGreaterEqual( runner.stats.get("/test", "GET").num_requests, 3) sleep(0.3) self.assertLessEqual(runner.stats.get("/test", "GET").num_requests, 1) runner.quit()
def test_weight_locusts(self): maxDiff = 2048 class BaseLocust(Locust): pass class L1(BaseLocust): weight = 101 class L2(BaseLocust): weight = 99 class L3(BaseLocust): weight = 100 runner = LocustRunner(Environment(options=mocked_options()), locust_classes=[L1, L2, L3]) self.assert_locust_class_distribution({ L1: 10, L2: 9, L3: 10 }, runner.weight_locusts(29)) self.assert_locust_class_distribution({ L1: 10, L2: 10, L3: 10 }, runner.weight_locusts(30)) self.assert_locust_class_distribution({ L1: 11, L2: 10, L3: 10 }, runner.weight_locusts(31))
def test_worker_without_stop_timeout(self): class MyTestUser(User): _test_state = 0 wait_time = constant(0) @task def the_task(self): MyTestUser._test_state = 1 gevent.sleep(0.2) MyTestUser._test_state = 2 with mock.patch("locust.rpc.rpc.Client", mocked_rpc()) as client: environment = Environment(stop_timeout=None) worker = self.get_runner(environment=environment, user_classes=[MyTestUser]) self.assertEqual(1, len(client.outbox)) self.assertEqual("client_ready", client.outbox[0].type) client.mocked_send(Message("hatch", { "hatch_rate": 1, "num_users": 1, "host": "", "stop_timeout": None, }, "dummy_client_id")) #print("outbox:", client.outbox) # wait for worker to hatch locusts self.assertIn("hatching", [m.type for m in client.outbox]) worker.hatching_greenlet.join() self.assertEqual(1, len(worker.user_greenlets)) # check that locust has started running gevent.sleep(0.01) self.assertEqual(1, MyTestUser._test_state) # send stop message client.mocked_send(Message("stop", None, "dummy_client_id")) worker.user_greenlets.join() # check that locust user did not get to finish self.assertEqual(1, MyTestUser._test_state)
def test_stop_timeout_exit_during_wait(self): short_time = 0.05 class MyTaskSet(TaskSet): @task def my_task(self): pass class MyTestLocust(Locust): tasks = [MyTaskSet] wait_time = between(1, 1) options = mocked_options() options.stop_timeout = short_time environment = Environment(options=options) runner = LocalLocustRunner(environment, [MyTestLocust]) runner.start(1, 1) gevent.sleep( short_time ) # sleep to make sure locust has had time to start waiting timeout = gevent.Timeout(short_time) timeout.start() try: runner.quit() runner.greenlet.join() except gevent.Timeout: self.fail( "Got Timeout exception. Waiting locusts should stop immediately, even when using stop_timeout." ) finally: timeout.cancel()
def test_parent_attribute(self): from locust.exception import StopUser parents = {} class SubTaskSet(TaskSet): def on_start(self): parents["sub"] = self.parent @task class SubSubTaskSet(TaskSet): def on_start(self): parents["subsub"] = self.parent @task def stop(self): raise StopUser() class RootTaskSet(TaskSet): tasks = [SubTaskSet] class MyUser(User): host = "" tasks = [RootTaskSet] l = MyUser(Environment()) l.run() self.assertTrue(isinstance(parents["sub"], RootTaskSet)) self.assertTrue(isinstance(parents["subsub"], SubTaskSet))
def test_spawn_zero_locusts(self): class MyTaskSet(TaskSet): @task def my_task(self): pass class MyTestLocust(Locust): task_set = MyTaskSet wait_time = constant(0.1) environment = Environment(options=mocked_options()) runner = LocalLocustRunner(environment, [MyTestLocust]) 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_change_user_count_during_hatching(self): class MyUser(User): wait_time = constant(1) @task def my_task(self): pass with mock.patch("locust.rpc.rpc.Client", mocked_rpc()) as client: environment = Environment() worker = self.get_runner(environment=environment, user_classes=[MyUser]) client.mocked_send( Message( "hatch", { "hatch_rate": 5, "num_users": 10, "host": "", "stop_timeout": None, }, "dummy_client_id")) sleep(0.6) self.assertEqual(STATE_HATCHING, worker.state) client.mocked_send( Message( "hatch", { "hatch_rate": 5, "num_users": 9, "host": "", "stop_timeout": None, }, "dummy_client_id")) sleep(0) worker.hatching_greenlet.join() self.assertEqual(9, len(worker.user_greenlets)) worker.quit()
def test_users_can_call_runner_quit(self): class BaseUser(User): wait_time = constant(0) @task def trigger(self): self.environment.runner.quit() runner = Environment(user_classes=[BaseUser]).create_local_runner() runner.spawn_users(1, 1, wait=False) timeout = gevent.Timeout(0.5) timeout.start() try: runner.greenlet.join() except gevent.Timeout: self.fail("Got Timeout exception, runner must have hung somehow.") finally: timeout.cancel()
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_no_reset_stats(self): class MyUser(User): wait_time = constant(0) @task class task_set(TaskSet): @task def my_task(self): self.user.environment.events.request_success.fire( request_type="GET", name="/test", response_time=666, response_length=1337, ) sleep(2) environment = Environment(reset_stats=False, user_classes=[MyUser]) runner = LocalRunner(environment) runner.start(user_count=6, hatch_rate=12, wait=False) sleep(0.25) self.assertGreaterEqual( runner.stats.get("/test", "GET").num_requests, 3) sleep(0.3) self.assertEqual(6, runner.stats.get("/test", "GET").num_requests) runner.quit()
def test_stop_timeout(self): short_time = 0.05 class MyTaskSet(TaskSet): @task def my_task(self): MyTaskSet.state = "first" gevent.sleep(short_time) MyTaskSet.state = "second" # should only run when run time + stop_timeout is > short_time gevent.sleep(short_time) MyTaskSet.state = "third" # should only run when run time + stop_timeout is > short_time * 2 class MyTestLocust(Locust): tasks = [MyTaskSet] wait_time = constant(0) options = mocked_options() environment = Environment(options=options) runner = LocalLocustRunner(environment, [MyTestLocust]) runner.start(1, 1) gevent.sleep(short_time / 2) runner.quit() self.assertEqual("first", MyTaskSet.state) environment.stop_timeout = short_time / 2 # exit with timeout runner = LocalLocustRunner(environment, [MyTestLocust]) runner.start(1, 1) gevent.sleep(short_time) runner.quit() self.assertEqual("second", MyTaskSet.state) environment.stop_timeout = short_time * 3 # allow task iteration to complete, with some margin runner = LocalLocustRunner(environment, [MyTestLocust]) runner.start(1, 1) gevent.sleep(short_time) timeout = gevent.Timeout(short_time * 2) timeout.start() try: runner.quit() runner.greenlet.join() except gevent.Timeout: self.fail( "Got Timeout exception. Some locusts must have kept runnining after iteration finish" ) finally: timeout.cancel() self.assertEqual("third", MyTaskSet.state)
def test_user_classes_with_same_name_is_error(self): with self.assertRaises(ValueError) as e: environment = Environment(user_classes=[MyUserWithSameName1, MyUserWithSameName2]) self.assertEqual( e.exception.args[0], "The following user classes have the same class name: locust.test.fake_module1_for_env_test.MyUserWithSameName, locust.test.fake_module2_for_env_test.MyUserWithSameName", )