Locust.io: Load-testing using vagrant ====== ![](https://process.filestackapi.com/cache=expiry:max/resize=width:700/compress/Rm2HlpyYQc6ma5BnUGRO) What could possibly go wrong when you release an application to the public domain without testing? You could either wait to find out or you can just find out before releasing the product. In this tutorial, we will be considering the art of load-testing, one of the several types of [non-functional test][1] required for a system. According to wikipedia > [Load testing][2] is the process of putting demand on a software system or computing device and measuring its response. Load testing is performed to determine a system's behavior under both normal and anticipated peak load conditions. It helps to identify the maximum operating capacity of an application as well as any bottlenecks and determine which element is causing degradation. ### What the heck is locust.io? [Locust][3] is an opensource load-testing tool that can be used to simulate millions of simultaneous users, it has other cool features that allows you to visualize the data generated from the test plus it has been proven & battle tested ![😃][4] ### Why Vagrant? Because [vagrant][5] allows us to build and maintain our near replica production environment with the right parameters for memory, CPU, storage, and disk i/o. ### Why VirtualBox? VirtualBox here will act as our hypervisor, the computer software that will create and run our virtual machine(s). ### So, what is the plan here? * Download [Vagrant][6] and [VirtualBox][7] * Set up a near-production replica environment using ### vagrant** and **virtualbox [SOURCE_CODE_APPLICATION][8] * Set up locust to run our load test [SOURCE_CODE_LOCUST][9] * Execute test against our production replica environment and check performance ### Some context Vagrant uses "Provisioners" and "Providers" as building blocks to manage the development environments. > Provisioners are tools that allow users to customize the configuration of virtual environments. Puppet and Chef are the two most widely used provisioners in the Vagrant ecosystem. > Providers are the services that Vagrant uses to set up and create virtual environments. Reference can be found [here][10] That said for our vagrant configuration we will be making use of the Vagrant Shell provisioner and VirtualBox for our provider, just a simple setup for now ![😉][11] One more thing, the Machine, and software requirements are written in a file called "Vagrantfile" to execute necessary steps in order to create a development-ready box, so let's get down to business. ### A near production environment using Vagrant and Virtualbox I used a past project of mine, a very minimal Python/Django application I called Bookshelf to create a near-production environment. Here is the link to the [repository][8] Let's create our environmnet using a vagrantfile. Use the command `vagrant init --minimal hashicorp/precise64` to create a vagrant file, where `hashicorp` is the username and `precise64` is the box name. More about getting started with vagrant can be found [here][12] ``` # vagrant file # set our environment to use our host private and public key to access the VM # as vagrant project provides an insecure key pair for SSH Public Key # Authentication so that vagrant ssh works # https://stackoverflow.com/questions/14715678/vagrant-insecure-by-default private_key_path = File.join(Dir.home, ".ssh", "id_rsa") public_key_path = File.join(Dir.home, ".ssh", "id_rsa.pub") insecure_key_path = File.join(Dir.home, ".vagrant.d", "insecure_private_key") private_key = IO.read(private_key_path) public_key = IO.read(public_key_path) # Set the environment details here Vagrant.configure("2") do |config| config.vm.box = "hashicorp/precise64" config.vm.hostname = "bookshelf-dev" # using a private network here, so don't forget to update your /etc/host file. # 192.168.50.4 bookshelf.example config.vm.network "private_network", ip: "192.168.50.4" config.ssh.insert_key = false config.ssh.private_key_path = [ private_key_path, insecure_key_path # to provision the first time ] # reference: https://github.com/hashicorp/vagrant/issues/992 @dwickern # use host/personal public and private key for security reasons config.vm.provision :shell, :inline => <<-SCRIPT set -e mkdir -p /vagrant/.ssh/ echo '#{private_key}' > /vagrant/.ssh/id_rsa chmod 600 /vagrant/.ssh/id_rsa echo '#{public_key}' > /vagrant/.ssh/authorized_keys chmod 600 /vagrant/.ssh/authorized_keys SCRIPT # Use a shell provisioner here config.vm.provision "shell" do |s| s.path = ".provision/setup_env.sh" s.args = ["set_up_python"] end config.vm.provision "shell" do |s| s.path = ".provision/setup_nginx.sh" s.args = ["set_up_nginx"] end if Vagrant.has_plugin?("vagrant-vbguest") config.vbguest.auto_update = false end # set your environment parameters here config.vm.provider 'virtualbox' do |v| v.memory = 2048 v.cpus = 2 end config.vm.post_up_message = "At this point use `vagrant ssh` to ssh into the development environment" end ``` Something to note here, notice the config `config.vm.network "private_network", ip: "192.168.50.4"` where I configured the Virtual machine network to use a private network "192.168.59.4", I edited my `/etc/hosts` file to map that IP address to the fully qualified domain name (FQDN) of the application called `bookshelf.example`. So, don't forget to edit your `/etc/hosts/` as well it should look like this ``` ## # /etc/host # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost 192.168.50.4 bookshelf.example ``` The provision scripts can be found in the `.provision` [folder][13] of the repository ![provision_sd.png][14] There you would see all the scripts used in the setup, the `start_app.sh` is used to run the application once you are in the virtual machine via ssh. To start the process run `vagrant up && vagrant ssh`, this will start the application and take you via ssh into the VM, inside the VM navigate to the `/vagrant/` folder to start the app via the command `./start_app.sh` With our application up and running, next would be to create a load testing script to run against our setup. ### NB: The current application setup here makes use of sqlite3 for the database config, you can change that to Postgres by uncommenting that in the settings file. Also, `setup_env.sh` provisions the environment to use Postgres. To set up a more comprehensive and robust production replica environment I would suggest you reference the docs [here][15], you can also check out [vagrant][5] to understand and play with vagrant. ### Set up locust for load-testing In other to perform load testing we are going to make use of locust. Source code can be found [here][9] First, we create our locust file ``` # locustfile.py # script used against vagrant set up on bookshelf git repo # url to repo: https://github.com/andela-sjames/bookshelf from locust import HttpLocust, TaskSet, task class SampleTrafficTask(TaskSet): @task(2) def index(self): self.client.get("/") @task(1) def search_for_book_that_contains_string_space(self): self.client.get("/?q=space") @task(1) def search_for_book_that_contains_string_man(self): self.client.get("/?q=man") class WebsiteUser(HttpLocust): host = "http://bookshelf.example" task_set = SampleTrafficTask min_wait = 5000 max_wait = 9000 ``` Here is a simple locust file called `locustfile.py`, where we define a number of locust task grouped under the `TaskSet class`. Then we have the `HttpLocust class` which represents a user, where we define how long a simulated user should wait between executing tasks, as well as what TaskSet class should define the user’s “behavior”. using the filename locustfile.py allows us to start the process by simply running the command `locust`. If you choose to give your file a different name then you just need to reference the path using `locust -f /path/to/the/locust/file` to start the script. If you're getting excited and want to know more then the [quick start][16] guide will get up to speed. ### Execute test and check perfomance It's time to see some action ![😮][17] Bookshelf app: Run the application via `vagrant up && vagrant ssh` navigate to the `/vagrant` and run `./start_app.sh` Vagrant allows you to shut down the running machine using `vagrant halt` and to destroy the machine and all the resources that were created with it using `vagrant destroy`. Use this [link][18] to know more about the vagrant command line. ![bookshelf_str.png][14] Go to your browser and use the private_ip address `192.168.50.4` or preferably `http://bookshelf.example` what we set in our `/etc/host` file of the system `192.168.50.4 bookshelf.example` ![bookshelf_app_web.png][14] Locust Swarm: Within your load-testing folder, activate your `virtualenv`, get your dependencies down via `pip install -r requirements.txt` and run `locust` ![locust_str.png][14] We're almost done: Now got to `http://127.0.0.1:8089/` on your browser ![locust_rate.png][14] Enter the number of users you want to simulate and the hatch rate (i.e how many users you want to be generated per second) and start swarming your development environment **NB: You can also run locust against a development environment hosted via a cloud service if that is your use case. You don't have to confine yourself to vagrant.** With the generated report and metric from the process, you should be able to make a well-informed decision on with regards to your system architecture or at least know the limit of your system and prepare for an anticipated event. ![locust_1.png][14] ![locust_a.png][14] ![locust_b.png][14] ![locust_error.png][14] ### Conclusion Congrats!!! if you made it to the end. As a recap, we were able to talk about what load-testing is, why you would want to perform a load test on your application and how to do it using locust and vagrant with a VirtualBox provider and a Shell provisioner. We also looked at the metrics and data generated from the test. **NB: If you want a more concise vagrant production environment you can reference the docs [here][15].** Thanks for reading and feel free to like/share this post. -------------------------------------------------------------------------------- via: https://www.codementor.io/samueljames/locust-io-load-testing-using-vagrant-ffwnjger9 作者:[Samuel James][a] 译者:[译者ID](https://github.com/译者ID) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]: [1]:https://en.wikipedia.org/wiki/Non-functional_testing [2]:https://en.wikipedia.org/wiki/Load_testing [3]:https://locust.io/ [4]:https://twemoji.maxcdn.com/2/72x72/1f603.png [5]:https://www.vagrantup.com/intro/index.html [6]:https://www.vagrantup.com/downloads.html [7]:https://www.virtualbox.org/wiki/Downloads [8]:https://github.com/andela-sjames/bookshelf [9]:https://github.com/andela-sjames/load-testing [10]:https://en.wikipedia.org/wiki/Vagrant_(software) [11]:https://twemoji.maxcdn.com/2/72x72/1f609.png [12]:https://www.vagrantup.com/intro/getting-started/install.html [13]:https://github.com/andela-sjames/bookshelf/tree/master/.provision [14]:data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== [15]:http://vagrant-django.readthedocs.io/en/latest/intro.html [16]:https://docs.locust.io/en/latest/quickstart.html [17]:https://twemoji.maxcdn.com/2/72x72/1f62e.png [18]:https://www.vagrantup.com/docs/cli/