rfuzz
... and with strange æons, even death may die.
home
quick info about rfuzz
sample
get the idea
design
how rfuzz's designed
theory
the theory behind rfuzz
practice
using rfuzz for real
statistics
learn statistics
docs
API and other info
project
rubyforge project page
credit
people who helped
How’s it used?
RFuzz is really easy to use for just basic HTTP requests and running simple tests. It’s even easier if you follow the REST paradigm.
The following are the examles that come with the gem.
hpricot_pudding.rb
Simple client that lets you search google from the command line. Run it with:
ruby hpricot_pudding.rb "ruby zed"
and it will return all the results printed out. (requires hpricot)
require 'rubygems'
require 'hpricot'
require 'rfuzz/session'
include RFuzz
agent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.4) Firefox/1.5.0.4"
google = HttpClient.new("www.google.com", 80)
r = google.get("/search",
:head => {"User-Agent" => agent},
:query => {"q" => ARGV[0],
"hl" => "en",
"btnG" => "Google Search"})
if r.http_status != "200"
puts "Wrong Status: #{r.http_status}?"
else
doc = Hpricot(r.http_body)
(doc/:a).each do |link|
if link.attributes["class"] == "l"
puts link.attributes["href"]
puts " -- " + link.children.join
end
end
end
kill_routes.rb
Demonstrates hitting a Ruby on Rails application with randomly generated long and insanely long URIs to see if you can choke the Rails routes system. When running under Mongrel you’ll find that Mongrel’s explicit limit of 512 characters on URIs protects Rails quite well.
It is also saving the results in the runs.csv and counts.csv files so you can analyze them after the run. It assumes the rails application is running on port 3000.
require 'rfuzz/session'
include RFuzz
s = Session.new :host => "localhost", :port => 3000
s.run 10, :save_as => ["runs.csv","counts.csv"] do |c,r|
len = r.num(90) + 1
s.count :len, len
uris = r.uris(ARGV[0].to_i,len)
uris.each do |u|
s.count_errors(:legal) do
# first sample for legal uris
resp = c.get(u)
s.count resp.http_status
end
# next sample for illegal uris
s.count_errors(:illegal) do
resp = c.get(u * 512)
s.count resp.http_status
end
end
end
perftest.rb
A simplistic performance test that actually tests the speed of processing a full request/response cycle by both the server and RFuzz. This isn’t how fast your server is, but how fast RFuzz and your server are when combined.
This sample is more low level not using the RFuzz::Session class and its DSL (which would simplify this code).
require 'rfuzz/client'
require 'rfuzz/stats'
include RFuzz
if ARGV.length != 4
STDERR.puts "usage: ruby perftest.rb host port uri count"
exit 1
end
host, port, uri, count = ARGV[0], ARGV[1], ARGV[2], ARGV[3].to_i
codes = {}
cl = HttpClient.new(host, port, :notifier => StatsTracker.new)
count.times do
begin
resp = cl.get(uri)
code = resp.http_status.to_i
codes[code] ||= 0
codes[code] += 1
rescue Object
end
end
puts cl.notifier.to_s
puts "Status Codes: #{codes.inspect}"
REST Client Sample
I used this in a project recently in order to do simple REST queries against a backend service:
class RESTClientError < Exception; end
class RESTClient
def initialize(host,port, base="")
@host, @port = host, port
@base = base
@client = RFuzz::HttpClient.new(host,port)
end
def target_uri(symbol)
uri = @base + "/" + symbol.to_s.tr("_","/")
end
def method_missing(symbol, *args)
res = @client.get(target_uri(symbol), :query => (args[0] || {}))
raise_error_if(res.http_status != "200",
"Invalid Status #{res.http_status} from server #{@host}:#{@port}")
return REXML::Document.new(res.http_body).root
end
def raise_error_if(test, msg)
raise RESTClientError.new(msg) if test
end
end
It basically takes any function call of the format client.call_that_thing :with => "this"
and translates it to the request ”/call/that/thing?with=this” then does a GET request.
If the response is not 200 it throws an error, otherwise it uses REXML to make into a
document for the caller to work with.