Lightweight Web Load Testing Tool with Curl and Ruby

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา

This is a simple web load testing tool using Curl. It is written in Ruby, but you don't have to know much Ruby to use it.

First you model your visitors in some file, e.g., load_test.rb:

visitor "Viewer" do       # The visitor type name should be Capitalized, 
                          # and follow the Ruby constant naming rule, 
                          # because it shall be used to create a class on that name
  stores_cookies

  site_url "http://mysite"

  get "/"
  post "/login", {:login => 'guest', :password => 'hello-world'}
  post "/list"
  get "/"
end

visitor "Poster" do
  stores_cookies

  site_url "http://mysite"

  get "/"
  post "/login", {:login => 'user', :password => 'hello'}
  post "/list"
  post "/submit", {
    :image => {:type => :file, :data => 'picture.png'},
    'category' => 58
  }, :multipart => true
end

Then you call

ruby runner.rb load_test Poster 10 Viewer 20 -t 60

which loads your definition, creates 10 Poster and 20 Viewer, and executes them for 60 seconds. After it runs, it'll run and give you some report.

Want to try?

What do you need: you must have ruby and curl (command line) installed on your system.

Download: Just go to its github repository.

How to install? You don't install. There are two files, just place it anywhere you like.

Documents

After you untar the package and place it somewhere, you have to specify how each type of visitors uses you web. Then you just call the runner.

How to specify visitor types

You write that as a simple ruby code.

You place each type of visitor in a visitor block:

visitor "YourVisitorType" do
  # you will write some code here
end

You can have many visitor types.

Technically, this block will create a class named YourVisitorType; therefore, as a ruby naming rule, it has to be capitalized and does not contain any weird characters.

Inside the block you can place the following options:

  • site_url base_url
This base_url will be used to prefix every http request.
  • stores_cookies
Use this to enable cookies.

It's time for actions.

  • get
Formally, it is a class method with the following signature
     get(url,params=nil)
You pass the url as a string, and the GET parameters as a ruby hash. The url is prefixed with the site_url. You have to specify the whole url if you do not provide the site_url. The parameter is optional. For example if you want to get from "/view" with parameter page=10, you write
     get "/view", {"page" => 10}
You can also use symbols as a key, e.g.,
     get "/view", {:page => 10}
  • post
This method signature is
     post(url,params=nil,options=nil)
params and options are ruby hash. The general idea of params is pretty much the same as in get, except when you want to post a file. In that case, your data is also a hash with two keys: :type and :data; you set :type to :file, and :data to your posting file name. Furthermore, to post a file you have to set the :multipart option to true, which is the only option for now. See the example above.

You might notice that when calling get and post you do not have to put their arguments in parentheses: this is because Ruby does not require that. Also, you may also notice that when setting the :multipart option to true, you do not have to put them in a hash (i.e., in curly brackets); this is, again, done automatically by Ruby. The last line from the above example can be written as

       post("/submit", {
         :image => {:type => :file, :data => 'picture.png'},
         'category' => 58
       }, {:multipart => true})

as well, but it looks kind of ugly.

visitor's id substitution

Each visitor object has an auto-generated id, starting from 1, which can be used when describing its operations. Currently, the feature is minimal.

On the post parameter values or the post parameter values, if you put ${id}, it will be substitute with the visitor's id. If you want the string ${id} in your parameters, put in $${id}. For example,

"user${id}"     # => "user10"
"user$${id}"    # => "user${id}"

Calling the runner

The runner can be called with

ruby runner.rb arguments

It usage reads.

using: ruby runner.rb <visitor_file> [<type> <number>] [<type> <number>] ... [options]
  * visitor_file : your visitor definition file, (with or without .rb)
  * type, number : the type and the number of visitors of that type
  * options      : any of the following
                     -t <sec>   specify how long (in seconds)
                     -d         dry-run: run, but make no real http requests
I'll add more document later

Releases

Current release is 0.03. The following is the release note.

Release 0.03
============
Date: 3 apr 2008
Problems:
* If some curl process goes to sleep mode and never comes back, the
  runner will wait forver.
Changes:
* Add some work around for the above problem, by intercepting
  Interrupt exception (when user presses c-break) during thread.join.
  The program still produces statistics

Known problems

  • When running a large number of threads (say 100), the cURL processes may go to sleep mode and never wake up. In this case runner will wait forever.

Suggestions and bug report

You can leave your comments at the talk page. Or you can send e-mail to me at gmail. My account name is jittat.