Blog

Victor is a full stack software engineer who loves travelling and building things. Most recently created Ewolo, a cross-platform workout logger.

    Load testing using Tsung

    Load testing is very difficult to get right and probably one of the more exciting types of testing that one gets to do. The most popular load testing tool is Apache's JMeter but in my experience Tsung allows me to squeeze more juice out of my machines and the fact that it is very easy to setup makes it a winner in my books.

    Installing Tsung

    You can find instructions for all erlang supported platforms here and the instructions for installation on Ubuntu are as follows:

    # install sphinx document generator
    sudo pip install -U Sphinx
    
    # install dependencies
    sudo apt-get install build-essential debhelper \
      erlang-nox erlang-dev \
      python-matplotlib gnuplot \
      libtemplate-perl
    
    # grab the binary
    wget http://tsung.erlang-projects.org/dist/tsung-1.6.0.tar.gz
    
    # make the package
    tar -xvzf tsung-1.6.0.tar.gz
    cd tsung-1.6.0
    ./configure
    make
    make deb
    cd ..
    
    # install
    sudo dpkg -i tsung_1.6.0-1_all.deb 
    
    # check to see if it installed ok
    tsung -v
    

    Note: There is a tsung package available for both Debian and Ubuntu, but using it can cause problems with mixed erlang versions so I would highly recommend simply building it from source. Also, when running a distributed setup please ensure that the erlang/tsung versions are exactly the same.

    Getting started with Tsung

    Setting up a tsung test scenario is done via xml, which is then executed to produce a series of output files which can then be used to produce a graphical report.

    If you want to sample the actual traffic being generated to make sure it looks correct, use dumptraffic="true" attribute on the top-level tsung tag, but do not use this for actual testing, because it slows down Tsung to a crawl.

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE tsung SYSTEM "/usr/share/tsung/tsung-1.0.dtd" []>
    <tsung loglevel="warning">
    
      <clients>
        <client host="localhost" cpu="2" maxusers="10000000"/>
      </clients>
    
      <servers>
        <server host="localhost" port="8001" type="tcp"/>
      </servers>
    
      <load>
        <arrivalphase phase="1" duration="2" unit="minute">
          <users arrivalrate="400" unit="second"/>
        </arrivalphase>
      </load>
    
      <sessions>
        <session name="load_via_db" weight="1" type="ts_http">
          <request>
            <http url="/api/cities/Armenia" method="GET" />
          </request>
        </session>
      </sessions>
    </tsung>
    

    As can be seen, one specifies the rate of arrival of clients and how long they remain, rather than specifying the number of simultaneous connections explicitly!

    Running

    Before firing up Tsung you might want to make sure that your machines can actually generate a large amout of concurrent requests. For my case, I needed to up the number of open file descriptors for my system. This was done by editing /etc/security/limits.conf to set the nofiles hard limit to 65000. You will need to relogin for the changes to take effect and the new limit can be set via ulimit -n 65000. Now we're ready to run:

    mkdir tsung-logs
    tsung -l tsung-logs -f scenario.xml start
    

    It takes some time to generate reports after the load is done, so be patient - for example, if you run the actual load-testing for 1 minute, then tsung finishes running in about 2.5 minutes. You can watch its progress by tailing the tsung.log file in the output directory it mentions when you start it.

    Reporting

    Tsung can generate an html report based on the log directory via the following:

    mkdir scenario-output
    cd scenario-output
    /usr/lib/tsung/bin/tsung_stats.pl --stats /npq/wheresvic.net/load/tsung-logs/20150826-1637/tsung.log
    chromium-browser graph.html
    
    Update September 5, 2015
    Here's a sample graph:
    sample tsung test report graph

    Distributed setup

    You will probably want to run Tsung from separate machines to properly load test your production setup. To do this, you need to ensure that:

    • Erlang and Tsung on all the machines are installed and have the same versions and be at the same locations.
    • All machines must have passwordless ssh login enabled (e.g. by exchanging public keys):
      # other hosts
      ssh-keygen
      ssh-copy-id tsung-2
      ssh tsung-2
      
      # localhost
      ssh-keygen
      cat id_rsa.pub >> ~/.ssh/authorized_keys
      
      # disable ssh from starting immediately
      echo manual | sudo tee /etc/init/ssh.override
      
    • All machines much have exactly the same user (name) created in the system.
    • All machines have hostnames configured for each other because the tsung configuration demands host names and not ips.
    We can now extend the client list in our scenario as follows:

    <clients>
      <client host="node1" cpu="2" maxusers="10000000"/>
      <client host="node2" cpu="2" maxusers="10000000"/>
    </clients>
    
    Wrap up

    There is quite a bit more that Tsung can do for you, such as simulating actual user behaviour and actions but I think that this much should be enough to get you up and running for now.

    HackerNews submission / discussion

    Back to the article list.

    SmallData newsletter

    Subscribe to get articles as they are published direct to your inbox!