def test_exception_is_catched(self): """ Test that exceptions are stored, and execution continues """ class HeyAnException(Exception): pass 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): self.interrupt() class MyLocust(Locust): min_wait = 10 max_wait = 10 task_set = MyTaskSet self.runner = LocustRunner([MyLocust], config.locust_config()) l = MyLocust(config.locust_config()) # supress stderr with mock.patch("sys.stderr") as mocked: l.task_set._task_queue = [ l.task_set.will_error, l.task_set.will_stop ] self.assertRaises(LocustError, l.run) # make sure HeyAnException isn't raised l.task_set._task_queue = [ l.task_set.will_error, l.task_set.will_stop ] self.assertRaises(LocustError, l.run) # make sure HeyAnException isn't raised self.assertEqual(2, len(mocked.method_calls)) # make sure exception was stored self.assertEqual(1, len(self.runner.exceptions)) hash_key, exception = self.runner.exceptions.popitem() self.assertTrue("traceback" in exception) self.assertTrue("HeyAnException" in exception["traceback"]) self.assertEqual(2, exception["count"])
def test_interrupt_taskset_in_main_taskset(self): class MyTaskSet(TaskSet): @task def interrupted_task(self): raise InterruptTaskSet(reschedule=False) class MyLocust(Locust): task_set = MyTaskSet class MyTaskSet2(TaskSet): @task def interrupted_task(self): self.interrupt() class MyLocust2(Locust): task_set = MyTaskSet2 l = MyLocust(config.locust_config()) l2 = MyLocust2(config.locust_config()) 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 test_stats_reporting(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.WorkerClient", mocked_rpc_server()) as client: self.worker = WorkerLocustRunner([MyTestLocust], config.locust_config()) self.worker.stats.get("Task", "/", "GET").log(100, 23455) self.worker.stats.get("Task", "/", "GET").log(800, 23455) self.worker.stats.get("Task", "/", "GET").log(700, 23455) sleep(runners.worker.WORKER_STATS_INTERVAL) data = Message.unserialize(client.outbox_all[-1]).data self.assertEqual({ 800: 1, 100: 1, 700: 1 }, data['stats'][0]['response_times']) self.assertEqual(3, data['stats'][0]['num_requests']) self.assertEqual(1600, data['stats'][0]['total_response_time'])
def test_on_demand_options_propagate(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.MasterServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.master.Process", mocked_process()): server.mocked_send( 'all', Message("slave_ready", None, "zeh_fake_client1")) self.master = MasterLocustRunner(MyTestLocust, config.locust_config()) sleep(0) self.assertEqual(1, self.master.slave_count) server.outbox_all = [] config_upd = { 'host': 'custom_host.com', 'master_host': 'new_master_host.com' } self.master.propagate_config(config_upd) self.assertEqual(1, len(server.outbox_all)) msg = Message.unserialize(server.outbox_all[0]).data self.assertEqual(msg['host'], 'custom_host.com') self.assertEqual(msg['master_host'], '127.0.0.1')
def test_slave_connect(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.MasterServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.master.Process", mocked_process()): server.mocked_send( 'all', Message("slave_ready", None, "zeh_fake_client1")) self.master = MasterLocustRunner(MyTestLocust, config.locust_config()) sleep(0) self.assertEqual(1, self.master.slave_count) self.assertTrue( "zeh_fake_client1" in self.master.slaves, "Could not find fake client in master instance's clients dict" ) server.mocked_send( "all", Message("slave_ready", None, "zeh_fake_client2")) server.mocked_send( "all", Message("slave_ready", None, "zeh_fake_client3")) server.mocked_send( "all", Message("slave_ready", None, "zeh_fake_client4")) sleep(0) self.assertEqual(4, self.master.slave_count) server.mocked_send("all", Message("quit", None, "zeh_fake_client3")) sleep(0) self.assertEqual(3, self.master.slave_count)
def setUp(self): super(TestTaskSet, self).setUp() class User(WebLocust): pass self.locust = User(config.locust_config())
def test_heartbeat(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.slave.Process", mocked_process()): self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) server.mocked_send( 'all', Message("worker_ready", None, "fake_client0")) self.slave.start_hatching(1, 1) sleep(runners.slave.HEARTBEAT_INTERVAL) self.assertEqual(1, len(server.outbox_all)) self.assertEqual( 'ping', Message.unserialize(server.outbox_all[0]).type) server.mocked_send('all', Message("pong", None, "fake_client0")) sleep(runners.slave.HEARTBEAT_INTERVAL) self.assertEqual(1, self.slave.worker_count) sleep(runners.slave.HEARTBEAT_INTERVAL) self.assertEqual(0, self.slave.worker_count)
def test_worker_stats_report_median(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.slave.Process", mocked_process()): self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) server.mocked_send( 'all', Message("worker_ready", None, "fake_client")) sleep(0) self.slave.start_hatching(1, 1) self.slave.stats.get("Task", "/", "GET").log(100, 23455) self.slave.stats.get("Task", "/", "GET").log(800, 23455) self.slave.stats.get("Task", "/", "GET").log(700, 23455) data = {"user_count": 1} events.report_to_master.fire(node_id="fake_client", data=data) self.slave.stats.clear_all() server.mocked_send("all", Message("stats", data, "fake_client")) sleep(0) s = self.slave.stats.get("Task", "/", "GET") self.assertEqual(700, s.median_response_time)
def test_worker_amount_spawn(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.slave.Process", mocked_process()) as processes: self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) timeout = gevent.Timeout(3.0) timeout.start() try: for i in range(5): server.mocked_send( "all", Message("worker_ready", None, "fake_client%i" % i)) self.slave.start_hatching(42, 2) except gevent.Timeout: self.fail("Got Timeout exception") finally: timeout.cancel() self.assertEqual(5, len(processes.started)) self.assertEqual(5, self.slave.worker_count)
def test_parent_attribute(self): from locust.exception import StopLocust 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 StopLocust() class RootTaskSet(TaskSet): tasks = [SubTaskSet] class MyLocust(Locust): task_set = RootTaskSet l = MyLocust(config.locust_config()) l.run() self.assertTrue(isinstance(parents["sub"], RootTaskSet)) self.assertTrue(isinstance(parents["subsub"], SubTaskSet))
def test_spawn_fewer_locusts_than_slaves(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.MasterServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.master.Process", mocked_process()): server.mocked_send( 'all', Message("slave_ready", None, "fake_client0")) self.master = MasterLocustRunner(MyTestLocust, config.locust_config()) for i in range(1, 5): server.mocked_send( 'all', Message("slave_ready", None, "fake_client%i" % i)) sleep(0) server.outbox_direct = [] self.master.start_hatching(2, 2) self.assertEqual(5, len(server.outbox_direct)) num_clients = 0 for msg in server.outbox_direct: num_clients += Message.unserialize( msg[1]).data["num_clients"] self.assertEqual( 2, num_clients, "Total number of locusts that would have been spawned is not 2" )
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 slaves """ import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.MasterServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.master.Process", mocked_process()): server.mocked_send( 'all', Message("slave_ready", None, "fake_client0")) self.master = MasterLocustRunner(MyTestLocust, config.locust_config()) for i in range(1, 5): server.mocked_send( "all", Message("slave_ready", None, "fake_client%i" % i)) sleep(0) server.outbox_direct = [] self.master.start_hatching(7, 7) self.assertEqual(5, len(server.outbox_direct)) num_clients = 0 for msg in server.outbox_direct: num_clients += Message.unserialize( msg[1]).data["num_clients"] self.assertEqual( 7, num_clients, "Total number of locusts that would have been spawned is not 7" )
def test_on_hatch(self): import mock class MyTaskSet(TaskSet): @task def my_task(self): pass class MyTestLocust(Locust): task_set = MyTaskSet min_wait = 100 max_wait = 100 with mock.patch("locust.rpc.rpc.WorkerClient", mocked_rpc_server()) as client: self.worker = WorkerLocustRunner([MyTestLocust], config.locust_config()) data = { "hatch_rate": 10, "num_clients": 10, "num_requests": None, "host": 'host', "stop_timeout": None } client.mocked_send('all', Message("hatch", data, "slave")) sleep(2) self.assertEqual(10, self.worker.user_count)
def test_exception_in_task(self): class HeyAnException(Exception): pass class MyLocust(Locust): class task_set(TaskSet): @task def will_error(self): raise HeyAnException(":(") self.runner = LocustRunner([MyLocust], config.locust_config()) l = MyLocust(config.locust_config()) l._catch_exceptions = False self.assertRaises(HeyAnException, l.run) self.assertRaises(HeyAnException, l.run) self.assertEqual(1, len(self.runner.exceptions)) hash_key, exception = self.runner.exceptions.popitem() self.assertTrue("traceback" in exception) self.assertTrue("HeyAnException" in exception["traceback"]) self.assertEqual(2, exception["count"])
def test_on_ping(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.WorkerClient", mocked_rpc_server()) as client: self.worker = WorkerLocustRunner(MyTestLocust, config.locust_config()) sleep(0) self.assertEqual(2, len(client.outbox_all)) client.mocked_send('all', Message("ping", None, "master")) sleep(0) self.assertEqual(3, len(client.outbox_all))
def setUp(self): super(TestWebUI, self).setUp() stats.global_stats.clear_all() # parser = parse_options()[0] # options = parser.parse_args([])[0] runners.main = MasterLocustRunner([], config.locust_config()) web.request_stats.clear_cache() self._web_ui_server = wsgi.WSGIServer(('127.0.0.1', 0), web.app, log=None) gevent.spawn(lambda: self._web_ui_server.serve_forever()) gevent.sleep(0.5) self.web_port = self._web_ui_server.server_port
def test_locust_client_error(self): class MyTaskSet(TaskSet): @task def t1(self): self.client.http.get("/") self.interrupt() class MyLocust(WebLocust): task_set = MyTaskSet my_locust = MyLocust(config.locust_config()) self.assertRaises(RescheduleTask, lambda: my_locust.client.http.get("/")) my_taskset = MyTaskSet(my_locust) self.assertRaises(RescheduleTask, lambda: my_taskset.client.http.get("/"))
def test_on_ping(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveClient", mocked_rpc_server()) as client: with mock.patch("locust.runners.slave.Process", mocked_process()) as processes: self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) sleep(0) self.assertEqual(2, len(client.outbox_all)) client.mocked_send('all', Message("ping", None, "master")) sleep(0) self.assertEqual(3, len(client.outbox_all))
def test_on_start_interrupt(self): class SubTaskSet(TaskSet): def on_start(self): if self.kwargs["reschedule"]: self.interrupt(reschedule=True) else: self.interrupt(reschedule=False) class MyLocust(Locust): task_set = SubTaskSet l = MyLocust(config.locust_config()) task_set = SubTaskSet(l) self.assertRaises(RescheduleTaskImmediately, lambda: task_set.run(reschedule=True)) self.assertRaises(RescheduleTask, lambda: task_set.run(reschedule=False))
def test_automatic_options_propagate(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.MasterServer", mocked_rpc_server()) as server: with mock.patch("locust.runners.master.Process", mocked_process()): server.mocked_send( 'all', Message("slave_ready", None, "zeh_fake_client1")) self.master = MasterLocustRunner(MyTestLocust, config.locust_config()) sleep(0) self.assertEqual(1, self.master.slave_count) self.assertEqual(1, len(server.outbox_direct)) msg = Message.unserialize(server.outbox_direct[0][1]).data self.assertEqual(self.master.options._config, msg)
def test_on_hatch(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveServer", mocked_rpc_server()) as server: with mock.patch("locust.rpc.rpc.SlaveClient", mocked_rpc_server()) as client: with mock.patch("locust.runners.slave.Process", mocked_process()) as processes: self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) for i in range(5): server.mocked_send( "all", Message("worker_ready", None, "fake_client%i" % i)) timeout = gevent.Timeout(2.0) timeout.start() try: data = { "hatch_rate": 10, "num_clients": 43, "num_requests": None, "host": 'host', "stop_timeout": None } client.mocked_send('all', Message("hatch", data, "master")) except gevent.Timeout: self.fail( "Got Timeout exception. A locust seems to have been spawned, even though 0 was specified." ) finally: timeout.cancel() sleep(0) self.assertEqual(5, len(processes.started))
def test_stats_reporting(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveServer", mocked_rpc_server()) as server: with mock.patch("locust.rpc.rpc.SlaveClient", mocked_rpc_server()) as client: with mock.patch("locust.runners.slave.Process", mocked_process()) as processes: self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) server.mocked_send( 'all', Message("worker_ready", None, "fake_client0")) self.slave.start_hatching(1, 1) self.slave.stats.get("Task", "/", "GET").log(100, 23455) self.slave.stats.get("Task", "/", "GET").log(800, 23455) self.slave.stats.get("Task", "/", "GET").log(700, 23455) sleep(runners.slave.SLAVE_STATS_INTERVAL + 0.1) messages = [ Message.unserialize(msg) for msg in client.outbox_all ] data = filter( lambda m: m.type == 'stats' and m.data['stats'], messages)[0].data self.assertEqual({ 800: 1, 100: 1, 700: 1 }, data['stats'][0]['response_times']) self.assertEqual(3, data['stats'][0]['num_requests']) self.assertEqual(1600, data['stats'][0]['total_response_time']) self.assertEqual(1, data['worker_count'])
def test_worker_receive_propagated_config(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveClient", mocked_rpc_server()) as client: with mock.patch("locust.runners.slave.Process", mocked_process()) as processes: self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) sleep(0) self.assertEqual(2, len(client.outbox_all)) msg = { 'host': 'custom_host.com', 'master_host': 'new_master_host.com' } client.mocked_send('all', Message("new_config", msg, "master")) sleep(0) self.assertEqual(self.slave.options.host, 'http://custom_host.com') self.assertEqual(self.slave.options.master_host, '127.0.0.1')
def worker_relaunch(self): import mock class MyTestLocust(Locust): pass with mock.patch("locust.rpc.rpc.SlaveServer", mocked_rpc_server()) as server: with mock.patch("locust.rpc.rpc.SlaveClient", mocked_rpc_server()) as client: with mock.patch("locust.runners.slave.Process", mocked_process()) as processes: self.slave = SlaveLocustRunner(MyTestLocust, config.locust_config()) server.mocked_send( 'all', Message("worker_ready", None, "fake_client0")) self.slave.start_hatching(1, 1) self.assertEqual(1, len(processes.started)) sleep(2 * runners.slave.HEARTBEAT_INTERVAL) self.assertEqual(0, self.slave.worker_count) client.mocked_send('all', Message("ping", None, "master")) sleep(runners.slave.HEARTBEAT_INTERVAL) self.assertEqual(2, len(processes.started))
def test_spawn_zero_locusts(self): class MyTaskSet(TaskSet): @task def my_task(self): pass class MyTestLocust(Locust): task_set = MyTaskSet min_wait = 100 max_wait = 100 self.runner = LocustRunner([MyTestLocust], config.locust_config()) timeout = gevent.Timeout(2.0) timeout.start() try: self.runner.start_hatching(0, 1, wait=True) 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_default_slave_up(self): class MyTestLocust(Locust): pass self.master = MasterLocustRunner(MyTestLocust, config.locust_config()) self.assertEqual(self.master.slave_count, 1)