{"id":34813,"date":"2016-06-08T16:10:56","date_gmt":"2016-06-08T10:40:56","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=34813"},"modified":"2016-06-09T09:47:28","modified_gmt":"2016-06-09T04:17:28","slug":"performing-heavy-load-testing-on-your-website-using-python-based-tool-locust","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/performing-heavy-load-testing-on-your-website-using-python-based-tool-locust\/","title":{"rendered":"Performing Heavy Load Testing on your Website using Locust"},"content":{"rendered":"<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-35409 aligncenter\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/06\/locust12.png\" alt=\"locust12\" width=\"334\" height=\"80\" \/><\/p>\n<p>Locust is open source and distributed load testing tool , intend to load test websites. A fundamental feature of locust is that you can describe all your test case in python code.<\/p>\n<p>This lightweight, distributed and scalable framework helps us to find out how many concurrent users a system can handle by writing test case scenarios in Python code. It can be used for websites,web applications, and web-based services.<\/p>\n<h3><strong>Why Locust?<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">Locust is completely event based and therefore it is possible to support thousands of users on a single machine.\u00a0Usually, most load testing tools are thread based and benchmarking thousands of users using thread based tools is not feasible.<br \/>\n<\/span><br \/>\n<span style=\"font-weight: 400;\">Our use case is to continuously generate load on web application and figure out how many concurrent users a system can handle.<br \/>\n<\/span><br \/>\nIn contrast to many other event-based applications, it does not use callbacks. Instead, it uses light-weight processes, through g-event. Each locust swarming our site is actually running inside its own process.The idea is a swarm of locusts (same machine) will access the website. The behaviour of each locust is defined by us and the swarming process is monitored from a WebUI in real time.<\/p>\n<h2><span style=\"font-weight: 400;\">Installation<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">This has been tested on Ubuntu 14.04 machine but it also supported on windows and os x<\/span><strong><strong>\u00a0<\/strong><\/strong><\/p>\n<h3>Install pip<\/h3>\n<p>[js]sudo apt-get install\u00a0python-pip[\/js]<\/p>\n<h3><strong>Install locust using pip \u00a0<\/strong><\/h3>\n<p>[js]pip install locustio[\/js]<\/p>\n<p><strong>Or<\/strong><\/p>\n<p>[js]easy install locustio[\/js]<\/p>\n<h4><span style=\"font-weight: 400;\">Once installation is complete we can check available option by running this command on our shell<\/span><\/h4>\n<p>[js]locust &#8211;help[\/js]<\/p>\n<p><strong><strong>\u00a0<\/strong><\/strong>Note:Python version 2.6+ not compatible with 3.x<\/p>\n<h2><span style=\"font-weight: 400;\">Quick start<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">To run a\u00a0load test on websites we have to create python file which contains the taskset and locust class. At least one locust class should be there to properly run locust<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Locust class represent one user which run taskSet assign to task_set attribute \u00a0<\/span><\/p>\n<p>Create file locustfile.py<\/p>\n<p>[js]<br \/>\nfrom locust import HttpLocust, TaskSet, task<br \/>\nfrom requests.auth import HTTPBasicAuth<\/p>\n<p>def http_basic_auth(self,uri)<br \/>\n        self.client.post(uri,auth=HTTPBasicAuth(&quot;username&quot;, &quot;Password&quot;))<\/p>\n<p>class UserDefinedTask(TaskSet):<br \/>\n    def on_start(self):<br \/>\n        &quot;&quot;&quot; call when locust start i.e before exection of tasks&quot;&quot;&quot;<\/p>\n<p>    @task(2)<br \/>\n    def home(self):<br \/>\n        self.client.get(&quot;\/home.html\/&quot;)<\/p>\n<p>    @task(1)<br \/>\n    def about(self):<br \/>\n &quot;&quot;&quot;load testing on page containing http_basic_authentication&quot;&quot;&quot;<br \/>\n    \thttp_basic_auth(self,\u201d\/about\/\u201d)<\/p>\n<p>class User(HttpLocust):<br \/>\n    task_set = UserBehavior<br \/>\n    min_wait=5000<br \/>\n    max_wait=9000<\/p>\n<p>[\/js]<\/p>\n<p><span style=\"font-weight: 400;\">Here we defined UserDefinedTask as a tastkset class which contains the task to be performed.<\/span><br \/>\n<span style=\"font-weight: 400;\">Here we defined User as a \u00a0locust class in which \u00a0tastkset\u00a0UserDefinedTask is pointed to task_set attribute.<br \/>\n<\/span><br \/>\n<span style=\"font-weight: 400;\">@task takes an optional weight argument which can be used to specify the task execution ratio<\/span><br \/>\n<span style=\"font-weight: 400;\">Here task index is executed twice as task profile.<\/span><\/p>\n<p><strong><strong>\u00a0Locust classes and attributes \u00a0<\/strong><\/strong><\/p>\n<ul>\n<li><span style=\"font-weight: 400;\"><strong>Httplocust:<\/strong> Represents users,where we defined how long a simulated user should wait b\/w executing tasks. It is an instance of httpsession and it is client attribute<\/span><\/li>\n<li><span style=\"font-weight: 400;\"><strong>Taskset:<\/strong>\u00a0define how number of locust tasks are gathered<\/span><\/li>\n<li><span style=\"font-weight: 400;\"><strong>Min_wait:<\/strong> Minimum waiting time to execute each task defined in task_set attribute(default to 1000 milliseconds)<\/span><\/li>\n<li><span style=\"font-weight: 400;\"><strong>Max_wait:<\/strong> Maximum waiting time to execute each task (default to 1000 milliseconds)<\/span><\/li>\n<\/ul>\n<h3>Run Locust<\/h3>\n<p><span style=\"font-weight: 400;\">If file is locustfile.py and stored in the same \u00a0directory <\/span><\/p>\n<p>[js]locust &#8211;host=http:\/\/example.com[\/js]<\/p>\n<p><span style=\"font-weight: 400;\">Otherwise <\/span><\/p>\n<p>[js]Locust -f filepath ClassName &#8211;host=http:\/\/example.com[\/js]<\/p>\n<p><span style=\"font-weight: 400;\">It runs on 8089 port<\/span><br \/>\n<i><span style=\"font-weight: 400;\">http:\/\/localhost:8089<\/span><\/i><\/p>\n<p>Once we\u2019ve started Locust using one of the above command lines, we should open up a browser and point it to http:\/\/127.0.0.1:8089\u00a0(if we run locust locally). After that, we should be redirected to something like this. Then it will ask for no of users and hatch rate (rate per second in which clients are spawned)<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-34753\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/05\/Screenshot-from-2016-03-30-170313.png\" alt=\"Screenshot from 2016-03-30 17:03:13\" width=\"1101\" height=\"594\" \/><\/p>\n<p>After clicking on start swarming it will start load testing on our websites and statistics will be shown like this.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-35298\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/06\/basicLocustScreen.png\" alt=\"basicLocustScreen\" width=\"1027\" height=\"258\" \/><\/p>\n<p>We can also check the logs in which load testing will start failing by clicking on Failures. We can also download our load testing result\/data by clicking on download data.<\/p>\n<h3><strong>For NON-UI mode (Monitoring through terminal)<\/strong><\/h3>\n<p>[js]locust -f locustfile.py &#8211;host=http:\/\/hostname &#8211;no-web &#8211;clients=500 &#8211;hatch-rate=500 &#8211;num-request=15000[\/js]<\/p>\n<p><span style=\"font-weight: 400;\"><strong>&#8211;client<\/strong>=Number of concurrent clients. Only used together with &#8211;no-web<\/span><br \/>\n<span style=\"font-weight: 400;\"><strong>&#8211;hatch-rate<\/strong>=The rate per second at which clients are spawned. Only with &#8211;no-web<\/span><br \/>\n<span style=\"font-weight: 400;\"><strong>&#8211;num-request<\/strong>=Number of requests to perform. Only used together with &#8211;no-web<\/span><\/p>\n<p><b>If there is multiple locust class define in single file <\/b><br \/>\n<i><span style=\"font-weight: 400;\">Run<\/span><\/i><\/p>\n<p>[js]Locust -f filename(fullpath) classname &#8211;host=http:\/\/hostname [\/js]<\/p>\n<p><b>let&#8217;s say, w<\/b><b>We have define two locust class CPU and memory which perform specific tasks<\/b><\/p>\n<p>[js]<\/p>\n<p>class CpuBehavior(TaskSet):<br \/>\n    def on_start(self):<br \/>\n        &quot;&quot;&quot; on_start is call before taskset execution i.e when locust is executed&quot;&quot;&quot;<\/p>\n<p>    @task(1)<br \/>\n    def cpu(self):<br \/>\n        self.client.get(&quot;\/cpu.html\/&quot;)<\/p>\n<p>class Cpu(HttpLocust):<br \/>\n    task_set = CpuBehavior<br \/>\n    min_wait=5000<br \/>\n    max_wait=9000<\/p>\n<p>class MemoryBehavior(TaskSet):<br \/>\n    def on_start(self):<br \/>\n        &quot;&quot;&quot; on_start is call before taskset execution i.e when locust is executed&quot;&quot;&quot;<\/p>\n<p>    @task(1)<br \/>\n    def mem(self):<br \/>\n        self.client.get(&quot;\/mem.html\/&quot;)<\/p>\n<p>class Memory(HttpLocust):<br \/>\n    task_set = MemoryBehavior<br \/>\n    min_wait=5000<\/p>\n<p>[\/js]<\/p>\n<h3>for Memory class<\/h3>\n<p>[shell]locust -f locustfile.py Memory &#8211;host=hostname \u00a0( running at default port 8089)[\/shell]<\/p>\n<h3>for CPU class<\/h3>\n<p>[shell]locust -f locustfile.py Cpu &#8211;host=http:\/\/hostname \u00a0-p 8090 ( running at port 8090)[\/shell]<\/p>\n<p>I hope this will help you in understanding what locust is. Locust supports running load tests distributed across multiple machines so it can also be used as \u00a0master-slave. So, In my next blog, we will perform locust across multiple machines as a master-slave concept.<br \/>\nFor Reference :\u00a0http:\/\/locust.io\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Locust is open source and distributed load testing tool , intend to load test websites. A fundamental feature of locust is that you can describe all your test case in python code. This lightweight, distributed and scalable framework helps us to find out how many concurrent users a system can handle by writing test case [&hellip;]<\/p>\n","protected":false},"author":917,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":11},"categories":[2348,1,1816],"tags":[1892,2640,1767,3455,3388,1358,3456],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/34813"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/917"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=34813"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/34813\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=34813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=34813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=34813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}