Class: RFuzz::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/rfuzz/session.rb

Overview

Creates a small light DSL for running RFuzz sessions against a web server. It configures a basic client and randomizer that you then use to conduct sessions and record statistics about the activity.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Session

Sets up a session that you then operate by calling Session#run. Most of the functions do not work unless they are inside a Session#run call.

Available options are:

  • :host => Required. Which host.
  • :port => Required. Which port.
  • :words => Dictionary to load for the words passed to RandomGenerator.

You can then pass any options you need to pass to the created RFuzz::HttpClient.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rfuzz/session.rb', line 26

def initialize(options={})
  @host = options[:host]
  @port = options[:port]
  options.delete(:host)
  options.delete(:port)
  options[:notifier] = StatsTracker.new

  @word_file = options[:words] || File.join(File.dirname(__FILE__), "..", "..", "resources","words.txt")

  @client = HttpClient.new(@host, @port, options)
  @rand = RandomGenerator.new(open(@word_file).read.split("\n"))

  @runs = []
  @counts = []
  @tracking = []
end

Instance Attribute Details

#countsObject

Returns the value of attribute counts.



12
13
14
# File 'lib/rfuzz/session.rb', line 12

def counts
  @counts
end

#runsObject

Returns the value of attribute runs.



13
14
15
# File 'lib/rfuzz/session.rb', line 13

def runs
  @runs
end

#trackingObject

Returns the value of attribute tracking.



14
15
16
# File 'lib/rfuzz/session.rb', line 14

def tracking
  @tracking
end

Instance Method Details

#count(stat, count = 1) ⇒ Object

Called inside a run to do a count of a measurement.



87
88
89
90
# File 'lib/rfuzz/session.rb', line 87

def count(stat,count=1)
  cur_count[stat] ||= 0
  cur_count[stat] += count
end

#count_errors(as) ⇒ Object

Used inside Session#run to wrap an attempted request or potentially failing action and then count the exceptions thrown.



145
146
147
148
149
150
151
152
# File 'lib/rfuzz/session.rb', line 145

def count_errors(as)
  begin
    yield
  rescue 
    count as
    count $!.class.to_s.tr(":","")
  end
end

#counts_to_a(headers = false) ⇒ Object

Takes the counts for all the runs and produces an array suitable for CSV output. Use Session#counts to access the counts directly.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rfuzz/session.rb', line 109

def counts_to_a(headers=false)
  keys = @counts[0].keys
  results = []
  results << ["run"] + keys if headers

  @counts.length.times do |run|
    results << [run]
    keys.each do |k|
      results.last << @counts[run][k]
    end
  end

  return results
end

#cur_countObject



47
48
49
# File 'lib/rfuzz/session.rb', line 47

def cur_count
  @counts.last
end

#cur_runObject



43
44
45
# File 'lib/rfuzz/session.rb', line 43

def cur_run
  @runs.last
end

#run(count, options = {}) ⇒ Object

Begin a run of count length wher a block is run once and statistics are collected from the client passed to the block. When calls you can pass in the following options:

  • :sample => Defaults to [:request], but will record any of [:request, :connect, :send_request, :read_header, :read_body, :close]
  • :save_as => A tuple of ["runs.csv", "counts.csv"] (or whatever you want to call them).

Once you call run, the block you pass it is given an HttpClient and a RandomGenerator. Each run will reset the HttpClient so you can pretend it is brand new.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rfuzz/session.rb', line 59

def run(count, options={})
  sample = options[:sample] || [:request]
  count.times do |i|
    # setup for this latest sample run
    @runs << {}
    @counts << {}
    @tracking << {}
    yield @client, @rand

    # record the request stats then reset them
    sample.each {|s| cur_run[s] = @client.notifier.stats[s].clone }
    @client.notifier.reset
  end

  if options[:save_as]
    write_runs(options[:save_as][0])
    write_counts(options[:save_as][1])
  end
end

#runs_to_a(headers = false) ⇒ Object

Takes the samples for all runs and returns an array suitable for passing to CSV or some other table output. If you want to access the runs directly then just use the Session#runs attribute.



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rfuzz/session.rb', line 95

def runs_to_a(headers=false)
  keys = ["run"] + Sampler.keys
  results = []
  results << keys if headers

  @runs.length.times do |run|
    @runs[run].values.each {|stats| results << [run] + stats.values }
  end

  return results
end

#sample(stat, count) ⇒ Object

Called inside a run to collect a stat you want with the given count. The stat should be a string or symbol, and count should be a number (or float).



81
82
83
84
# File 'lib/rfuzz/session.rb', line 81

def sample(stat,count)
  cur_run[stat] ||= Sampler.new(stat)
  cur_run[stat].sample(count)
end

#track(name, value) ⇒ Object

Lets you track some value you need to report on later. Doesn't do any calculations and is matched for each run. You then access Session#tracking which is an Array of runs, each run being a Hash. Inside the hash is the tracking you registerd by => [val1, val2].



128
129
130
131
# File 'lib/rfuzz/session.rb', line 128

def track(name,value)
  @tracking.last[name] ||= []
  @tracking.last[name] << value
end

#write_counts(file) ⇒ Object

Writes the counts to the given file as a CSV.



139
140
141
# File 'lib/rfuzz/session.rb', line 139

def write_counts(file)
  CSV.open(file,"w") {|out| counts_to_a(headers=true).each {|c| out << c } }
end

#write_runs(file) ⇒ Object

Writes the runs to the given file as a CSV.



134
135
136
# File 'lib/rfuzz/session.rb', line 134

def write_runs(file)
  CSV.open(file,"w") {|out| runs_to_a(headers=true).each {|r| out << r } }
end