hansel 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,6 +1,9 @@
1
1
  ## MAC OS
2
2
  .DS_Store
3
3
 
4
+ ## metric_fu
5
+ tmp/*
6
+
4
7
  ## TEXTMATE
5
8
  *.tmproj
6
9
  tmtags
data/Rakefile CHANGED
@@ -1,5 +1,19 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require "spec/rake/spectask"
4
+
5
+ task :default => :spec
6
+
7
+ Spec::Rake::SpecTask.new do |t|
8
+ t.spec_opts = %w(-fs -c)
9
+ t.spec_files = FileList["spec/**_spec.rb"]
10
+ end
11
+
12
+ begin
13
+ require 'metric_fu'
14
+ rescue LoadError
15
+ puts "metric_fu (or a dependency) not available. Install it with: gem install metric_fu"
16
+ end
3
17
 
4
18
  begin
5
19
  require 'jeweler'
@@ -16,3 +30,36 @@ begin
16
30
  rescue LoadError
17
31
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
32
  end
33
+
34
+ MetricFu::Configuration.run do |config|
35
+ #define which metrics you want to use
36
+ config.metrics = [:churn, :saikuro, :flog, :flay, :reek, :roodi]
37
+ config.graphs = [:flog, :flay, :reek, :roodi]
38
+ config.flay = { :dirs_to_flay => ['app', 'lib'],
39
+ :minimum_score => 100 }
40
+ config.flog = { :dirs_to_flog => ['app', 'lib'] }
41
+ config.reek = { :dirs_to_reek => ['app', 'lib'] }
42
+ config.roodi = { :dirs_to_roodi => ['app', 'lib'] }
43
+
44
+ config.saikuro = { :output_directory => 'scratch_directory/saikuro',
45
+ :input_directory => ['app', 'lib'],
46
+ :cyclo => "",
47
+ :filter_cyclo => "0",
48
+ :warn_cyclo => "5",
49
+ :error_cyclo => "7",
50
+ :formater => "text"} #this needs to be set to "text"
51
+ config.churn = { :start_date => "1 year ago", :minimum_churn_count => 10}
52
+
53
+ config.rcov = { :environment => 'test',
54
+ :test_files => ['test/**/*_test.rb',
55
+ 'spec/**/*_spec.rb'],
56
+ :rcov_opts => ["--sort coverage",
57
+ "--no-html",
58
+ "--text-coverage",
59
+ "--no-color",
60
+ "--profile",
61
+ "--rails",
62
+ "--exclude /gems/,/Library/,spec"]}
63
+
64
+ config.graph_engine = :bluff
65
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.1.6
data/hansel.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{hansel}
8
- s.version = "0.1.5"
8
+ s.version = "0.1.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Paul Mylchreest"]
12
- s.date = %q{2010-04-27}
12
+ s.date = %q{2010-05-05}
13
13
  s.default_executable = %q{hansel}
14
14
  s.description = %q{Ruby driver for httperf - automated load and performance testing}
15
15
  s.email = %q{paul.mylchreest@mac.com}
@@ -31,14 +31,23 @@ Gem::Specification.new do |s|
31
31
  "lib/config.rb",
32
32
  "lib/csv_formatter.rb",
33
33
  "lib/hansel.rb",
34
+ "lib/httperf_result.rb",
35
+ "lib/httperf_result_parser.rb",
34
36
  "lib/octave_formatter.rb",
35
- "lib/yaml_formatter.rb"
37
+ "lib/yaml_formatter.rb",
38
+ "spec/httperf_result_parser_spec.rb",
39
+ "spec/spec_helper.rb",
40
+ "templates/octave.m.erb"
36
41
  ]
37
42
  s.homepage = %q{http://github.com/xlymian/hansel}
38
43
  s.rdoc_options = ["--charset=UTF-8"]
39
44
  s.require_paths = ["lib"]
40
45
  s.rubygems_version = %q{1.3.6}
41
46
  s.summary = %q{Ruby driver for httperf - automated load and performance testing}
47
+ s.test_files = [
48
+ "spec/httperf_result_parser_spec.rb",
49
+ "spec/spec_helper.rb"
50
+ ]
42
51
 
43
52
  if s.respond_to? :specification_version then
44
53
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
data/lib/arg_parser.rb CHANGED
@@ -11,20 +11,22 @@ module Hansel
11
11
  def initialize args
12
12
  @args = args
13
13
  @options = OpenStruct.new(
14
- :verbose => false,
15
- :server => 'localhost',
16
- :port => '80',
17
- :uri => '/',
18
- :num_conns => 1,
19
- :rate => 1,
20
- :cookie => nil,
21
- :low_rate => 1,
22
- :high_rate => 2,
23
- :rate_step => 1,
24
- :output_format => :yaml,
25
- :output => nil,
26
- :output_dir => File.join(ENV['HOME'], 'hansel_output'),
27
- :exit => false
14
+ :verbose => false,
15
+ :server => 'localhost',
16
+ :port => '80',
17
+ :uri => '/',
18
+ :num_conns => 1,
19
+ :rate => 1,
20
+ :cookie => nil,
21
+ :low_rate => 1,
22
+ :high_rate => 2,
23
+ :rate_step => 1,
24
+ :output_format => :yaml,
25
+ :output => nil,
26
+ :output_dir => File.join(ENV['HOME'], 'hansel_output'),
27
+ :template_path => 'templates',
28
+ :template => nil,
29
+ :exit => false
28
30
  )
29
31
  end
30
32
 
@@ -83,6 +85,17 @@ module Hansel
83
85
  end
84
86
  end
85
87
 
88
+ def template_options options
89
+ options.on("-m", "--template_path=PATH", "Specify template path.") do |template_path|
90
+ @options.template_path = template_path
91
+ end
92
+
93
+ options.on("-t", "--template=TEMPLATE_NAME",
94
+ "Specify a template for output.") do |template|
95
+ @options.template = template
96
+ end
97
+ end
98
+
86
99
  def other_options options
87
100
  options.on("-c", "--cookie=C", "Specify a cookie.") do |cookie|
88
101
  @options.cookie = cookie
data/lib/csv_formatter.rb CHANGED
@@ -1,22 +1,17 @@
1
1
  require 'csv'
2
+
2
3
  module Hansel
3
- #
4
+
4
5
  # Output to csv format
5
6
  #
6
7
  class CsvFormatter
8
+ COLUMNS = %w(rate replies connection_rate request_rate reply_time net_io
9
+ errors status reply_rate_min reply_rate_avg reply_rate_max
10
+ reply_rate_stddev)
11
+
7
12
  def initialize(data)
8
- return if data.empty?
9
13
  @data = data
10
14
  @csv = ""
11
- @info_keys = []
12
- @data_keys = []
13
- @data.keys.each do |key|
14
- @info_keys << key if key.instance_of? Symbol
15
- @data_keys << key if key.instance_of? Fixnum
16
- end
17
- @keys ||= @data[@data_keys.first].keys
18
- @info = @info_keys.collect{|key| @data[key]}
19
- line header
20
15
  end
21
16
 
22
17
  def line text
@@ -24,17 +19,13 @@ module Hansel
24
19
  @csv << "\n"
25
20
  end
26
21
 
27
- def header
28
- @header ||= CSV.generate_line((@info_keys + @keys).map(&:to_s))
29
- end
30
-
31
- def format_line data_key
32
- line CSV.generate_line(@info + @keys.collect{|key| @data[data_key][key]})
22
+ def format_line data
23
+ line CSV.generate_line( COLUMNS.map { |column| data.send column.to_sym } )
33
24
  end
34
25
 
35
26
  def format
36
- return result if @data.empty?
37
- @data_keys.each { |data_key| format_line data_key }
27
+ line CSV.generate_line(COLUMNS)
28
+ @data.each { |data| format_line data } unless @data.empty?
38
29
  @csv
39
30
  end
40
31
  end
data/lib/hansel.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  require 'fileutils'
2
+ require 'lib/httperf_result_parser'
3
+ require 'lib/httperf_result'
4
+
2
5
  module Hansel
3
6
  #
4
7
  # Class wrapper over httperf.
@@ -6,66 +9,10 @@ module Hansel
6
9
  class Hansel
7
10
  def initialize(options = {})
8
11
  @options = options
9
- @results = {}
12
+ @results = []
10
13
  @current_rate = nil
11
14
  end
12
15
 
13
- def options
14
- @options
15
- end
16
-
17
- def parse_replies line
18
- @result[:replies] = $1 if line =~ /^Total: .*replies (\d+)/
19
- end
20
-
21
- def parse_connection_rate line
22
- @result[:connection_rate] = $1 if line =~ /^Connection rate: (\d+\.\d)/
23
- end
24
-
25
- def parse_request_rate line
26
- @result[:request_rate] = $1 if line =~ /^Request rate: (\d+\.\d)/
27
- end
28
-
29
- def parse_reply_time line
30
- @result[:reply_time] = $1 if line =~ /^Reply time .* response (\d+\.\d)/
31
- end
32
-
33
- def parse_net_io line
34
- @result[:net_io] = $1 if line =~ /^Net I\/O: (\d+\.\d)/
35
- end
36
-
37
- def parse_errors line
38
- @result[:errors] = $1 if line =~ /^Errors: total (\d+)/
39
- end
40
-
41
- def parse_status line
42
- @result[:status] = $1 if line =~ /^Reply status: 1xx=\d+ 2xx=\d+ 3xx=\d+ 4xx=\d+ 5xx=(\d+)/
43
- end
44
-
45
- def parse_reply_rate line
46
- if line =~ /^Reply rate .*min (\d+\.\d) avg (\d+\.\d) max (\d+\.\d) stddev (\d+\.\d)/
47
- @result[:reply_rate_min] = $1
48
- @result[:reply_rate_avg] = $2
49
- @result[:reply_rate_max] = $3
50
- @result[:reply_rate_stddev] = $4
51
- end
52
- end
53
-
54
- def parse_line line
55
- %w(parse_replies parse_connection_rate parse_request_rate
56
- parse_reply_time parse_net_io parse_errors parse_status
57
- parse_reply_rate).map(&:to_sym).each do |method|
58
- self.send method, line
59
- end
60
- end
61
-
62
- def parse pipe
63
- @result = {:output => ""}
64
- while line = pipe.gets
65
- parse_line line
66
- end
67
- end
68
-
69
16
  def build_httperf_cmd
70
17
  cookie = @options.cookie
71
18
  httperf_cmd = [
@@ -79,17 +26,23 @@ module Hansel
79
26
  ].compact.join ' '
80
27
  end
81
28
 
82
- #
29
+ #
83
30
  # Runs httperf with a given request rate. Parses the output and returns
84
31
  # a hash with the results.
85
- #
32
+ #
86
33
  def httperf
87
34
  httperf_cmd = build_httperf_cmd
88
35
  IO.popen("#{httperf_cmd} 2>&1") do |pipe|
89
36
  puts "\n#{httperf_cmd}"
90
- parse pipe
37
+ @results << (httperf_result = HttperfResult.new({
38
+ :rate => @current_rate,
39
+ :server => @options.server,
40
+ :port => @options.port,
41
+ :uri => @options.uri,
42
+ :num_conns => @options.num_conns
43
+ }))
44
+ HttperfResultParser.new(pipe).parse(httperf_result)
91
45
  end
92
- @results[@current_rate] = @result
93
46
  end
94
47
 
95
48
  def yaml_formatter
@@ -105,17 +58,22 @@ module Hansel
105
58
  def octave_formatter
106
59
  load File.here '/../lib/octave_formatter.rb'
107
60
  puts @output_file_name
108
- OctaveFormatter.new(@results, {:output_file_name => @output_file_name})
109
- end
110
-
111
- def make_formatter format
112
- case format
113
- when :yaml
114
- yaml_formatter
115
- when :csv
116
- csv_formatter
117
- when :octave
118
- octave_formatter
61
+ OctaveFormatter.new(@results, {
62
+ :output_file_name => @output_file_name,
63
+ :template => File.join([@options.template_path,
64
+ @options.template || 'octave.m.erb']),
65
+ }
66
+ )
67
+ end
68
+
69
+ def format format
70
+ formatter = "#{format}_formatter".to_sym
71
+ unless self.respond_to? formatter
72
+ puts "Using default octave_formatter"
73
+ octave_formatter
74
+ else
75
+ puts "Using #{formatter}"
76
+ self.send formatter
119
77
  end
120
78
  end
121
79
 
@@ -125,13 +83,13 @@ module Hansel
125
83
  output_format = @options.output_format
126
84
  type = { :yaml => 'yml', :csv => 'csv', :octave => 'm' }[output_format]
127
85
  File.open([output_file, type].join('.'), "w+") do |file|
128
- file.puts make_formatter(output_format).format
86
+ file.puts format(output_format).format
129
87
  end
130
88
  end
131
89
 
132
- #
90
+ #
133
91
  # Output the results based on the requested output format
134
- #
92
+ #
135
93
  def output
136
94
  if @options.output
137
95
  FileUtils.mkdir_p @options.output_dir
@@ -143,31 +101,22 @@ module Hansel
143
101
  puts text if @options.verbose
144
102
  end
145
103
 
146
- def one_run
147
- @results[:server] = @options.server
148
- @results[:port] = @options.port
149
- @results[:uri] = @options.uri
150
- @results[:num_conns] = @options.num_conns
151
- httperf
152
- end
153
-
154
104
  def run_all
155
105
  (@options.low_rate.to_i..@options.high_rate.to_i).step(@options.rate_step.to_i) do |rate|
156
106
  status "running httperf at rate: #{rate}"
157
107
  @current_rate = rate
158
- one_run
108
+ httperf
159
109
  end
160
110
  end
161
111
 
162
- #
112
+ #
163
113
  # Run httperf from low_rate to high_rate, stepping by rate_step
164
- #
114
+ #
165
115
  def run
166
116
  status "starting run..."
167
117
  run_all
168
- status "ending run..."
169
118
  output
170
- @results
119
+ status "ending run..."
171
120
  end
172
121
 
173
122
  trap("INT") {
@@ -0,0 +1,19 @@
1
+ module Hansel
2
+ #
3
+ # Wrapper for parsing of the httperf run result.
4
+ #
5
+ class HttperfResult
6
+ attr_accessor :rate, :server, :port, :uri, :num_conns, :replies,
7
+ :connection_rate, :request_rate, :reply_time, :net_io,
8
+ :errors, :status, :reply_rate_min, :reply_rate_avg,
9
+ :reply_rate_max, :reply_rate_stddev
10
+
11
+ def initialize opt
12
+ @rate = opt[:rate]
13
+ @server = opt[:server]
14
+ @port = opt[:port]
15
+ @uri = opt[:uri]
16
+ @num_conns = opt[:num_conns]
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,67 @@
1
+ module Hansel
2
+ #
3
+ # Parse httperf output.
4
+ #
5
+ class HttperfResultParser
6
+ attr_accessor :rate, :replies, :connection_rate, :request_rate, :reply_time,
7
+ :net_io, :errors, :status, :reply_rate_min, :reply_rate_avg,
8
+ :reply_rate_max, :reply_rate_stddev
9
+
10
+ def initialize input
11
+ @input = input
12
+ end
13
+
14
+ def parse_replies line
15
+ @httperf_result.replies = $1.to_i if line =~ /^Total: .*replies (\d+)/
16
+ end
17
+
18
+ def parse_connection_rate line
19
+ @httperf_result.connection_rate = $1.to_f if line =~ /^Connection rate: (\d+\.\d)/
20
+ end
21
+
22
+ def parse_request_rate line
23
+ @httperf_result.request_rate = $1.to_f if line =~ /^Request rate: (\d+\.\d)/
24
+ end
25
+
26
+ def parse_reply_time line
27
+ @httperf_result.reply_time = $1.to_f if line =~ /^Reply time .* response (\d+\.\d)/
28
+ end
29
+
30
+ def parse_net_io line
31
+ @httperf_result.net_io = $1.to_f if line =~ /^Net I\/O: (\d+\.\d)/
32
+ end
33
+
34
+ def parse_errors line
35
+ @httperf_result.errors = $1.to_i if line =~ /^Errors: total (\d+)/
36
+ end
37
+
38
+ def parse_status line
39
+ @httperf_result.status = $1.to_i if line =~ /^Reply status: 1xx=\d+ 2xx=\d+ 3xx=\d+ 4xx=\d+ 5xx=(\d+)/
40
+ end
41
+
42
+ def parse_reply_rate line
43
+ if line =~ /^Reply rate .*min (\d+\.\d) avg (\d+\.\d) max (\d+\.\d) stddev (\d+\.\d)/
44
+ @httperf_result.reply_rate_min = $1.to_f
45
+ @httperf_result.reply_rate_avg = $2.to_f
46
+ @httperf_result.reply_rate_max = $3.to_f
47
+ @httperf_result.reply_rate_stddev = $4.to_f
48
+ end
49
+ end
50
+
51
+ def parse_line line
52
+ %w(parse_replies parse_connection_rate parse_request_rate
53
+ parse_reply_time parse_net_io parse_errors parse_status
54
+ parse_reply_rate).map(&:to_sym).each do |method|
55
+ self.send method, line
56
+ end
57
+ end
58
+
59
+ def parse httperf_result
60
+ @httperf_result = httperf_result
61
+ @input.each_line do |line|
62
+ parse_line line
63
+ end
64
+ self
65
+ end
66
+ end
67
+ end
@@ -1,69 +1,22 @@
1
+ require 'erb'
2
+
1
3
  module Hansel
2
4
  #
3
5
  # Output to a Octave script.
4
6
  #
5
7
  class OctaveFormatter
6
8
  def initialize(data, options = {})
7
- @data = data
8
- @options = options
9
+ @data = data
10
+ @template = options[:template]
11
+ @rates = @data.map(&:rate)
12
+ @max_rate = @rates.max
9
13
  @png_output = [(options[:output_file_name] || 'stats'), 'png'].join('.')
10
- @rates = @data.keys.select{|key| key.instance_of? Fixnum}.map(&:to_i).sort
11
- @max_rate = @rates.last
12
- @results = OpenStruct.new(
13
- :request_rate => [],
14
- :connection_rate => [],
15
- :reply_rate_avg => [],
16
- :reply_rate_max => [],
17
- :reply_time => [],
18
- :reply_rate_stddev => [],
19
- :errors => []
20
- )
21
- end
22
-
23
- def build_arrays rate, data
24
- %w(request_rate connection_rate reply_rate_avg reply_rate_max
25
- reply_time reply_rate_stddev errors).map(&:to_sym).each do |method|
26
- (@results.send method) << data[method]
27
- end
28
14
  end
29
15
 
16
+ # For each value of rate, collate the values in each variable in @vars
17
+ # and format using the erb template
30
18
  def format
31
- # TODO: render an erb template instead.
32
- @rates.each { |rate| build_arrays rate, @data[rate] }
33
- result = <<-EOS
34
- rate = [#{@rates.join(',')}];
35
- request_rate = [#{@results.request_rate.join(',')}];
36
- connection_rate = [#{@results.connection_rate.join(',')}];
37
- reply_rate_avg = [#{@results.reply_rate_avg.join(',')}];
38
- reply_rate_max = [#{@results.reply_rate_max.join(',')}];
39
- reply_time = [#{@results.reply_time.join(',')}];
40
- reply_rate_stddev = [#{@results.reply_rate_stddev.join(',')}];
41
- errors = [#{@results.errors.join(',')}];
42
-
43
- plot(rate, request_rate, '-k*');
44
- hold on;
45
- plot(rate, connection_rate, '-kd');
46
- hold on;
47
- plot(rate, reply_rate_max, '-kp');
48
- hold on;
49
- plot(rate, reply_rate_max, '-k+');
50
- hold on;
51
- plot(rate, reply_rate_stddev, '-kh');
52
- hold on;
53
- plot(rate, reply_time, '-g*');
54
- hold on;
55
- plot(rate, errors, '-r*');
56
-
57
- grid on;
58
-
59
- axis([0 #{@max_rate} 0 #{@max_rate}]);
60
- title('Hansel report for #{@data[:server]}:#{@data[:port]}#{@data[:uri]} (#{@data[:num_conns]} connections per run)')
61
- xlabel('Demanded Request Rate');
62
- legend('Request Rate', 'Connection Rate', 'Avg. reply rate', 'Max. reply rate', 'Reply rate StdDev', 'Reply time', 'Errors');
63
- print('#{@png_output}', '-dpng')
64
- EOS
65
- result = result.gsub ' ', ''
66
- result
19
+ ERB.new(File.read(@template)).result(binding)
67
20
  end
68
21
  end
69
22
  end
@@ -0,0 +1,119 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+ require 'httperf_result_parser'
3
+ require 'httperf_result'
4
+
5
+ SAMPLE_HTTPERF_OUTPUT = <<-EOS
6
+
7
+ Maximum connect burst length: 1
8
+
9
+ Total: connections 100 requests 99 replies 98 test-duration 10.082 s
10
+
11
+ Connection rate: 9.9 conn/s (100.8 ms/conn, <=3 concurrent connections)
12
+ Connection time [ms]: min 173.3 avg 180.0 max 205.1 median 178.5 stddev 5.6
13
+ Connection time [ms]: connect 89.8
14
+ Connection length [replies/conn]: 1.000
15
+
16
+ Request rate: 9.9 req/s (100.8 ms/req)
17
+ Request size [B]: 68.0
18
+
19
+ Reply rate [replies/s]: min 9.8 avg 9.9 max 10.0 stddev 0.1 (2 samples)
20
+ Reply time [ms]: response 90.1 transfer 0.0
21
+ Reply size [B]: header 287.0 content 438.0 footer 0.0 (total 725.0)
22
+ Reply status: 1xx=0 2xx=100 3xx=0 4xx=0 5xx=1
23
+
24
+ CPU time [s]: user 1.57 system 8.50 (user 15.6% system 84.3% total 99.8%)
25
+ Net I/O: 7.7 KB/s (0.1*10^6 bps)
26
+
27
+ Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
28
+ Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
29
+ EOS
30
+
31
+ describe Hansel::HttperfResultParser, "#score" do
32
+ before(:each) do
33
+ @parser = Hansel::HttperfResultParser.new SAMPLE_HTTPERF_OUTPUT
34
+ end
35
+
36
+ describe "when calling parse" do
37
+ before(:each) do
38
+ @httperf_result = Hansel::HttperfResult.new(
39
+ :rate => 10,
40
+ :server => 'www.example.com',
41
+ :port => 80,
42
+ :uri => '/',
43
+ :num_conns => 100
44
+ )
45
+ @parser.parse @httperf_result
46
+ end
47
+
48
+ it "should set the passed HttperfResult object" do
49
+ @httperf_result.class.name =~ /HttperfResult/
50
+ end
51
+
52
+ describe "the HttperfResult object" do
53
+ it "initialize the rate should be 10" do
54
+ @httperf_result.rate.should == 10
55
+ end
56
+
57
+ it "initialize the server to 'www.example.com'" do
58
+ @httperf_result.server.should == 'www.example.com'
59
+ end
60
+
61
+ it "initialize the port to 80" do
62
+ @httperf_result.port.should == 80
63
+ end
64
+
65
+ it "initialize the uri to '/'" do
66
+ @httperf_result.uri.should == '/'
67
+ end
68
+
69
+ it "initialize the num_conns to 100" do
70
+ @httperf_result.num_conns.should == 100
71
+ end
72
+
73
+ it "the should be replies to 98" do
74
+ @httperf_result.replies.should == 98
75
+ end
76
+
77
+ it "the connection_rate should be 9.9" do
78
+ @httperf_result.connection_rate.should == 9.9
79
+ end
80
+
81
+ it "the request_rate should be 9.9" do
82
+ @httperf_result.request_rate.should == 9.9
83
+ end
84
+
85
+ it "should set the reply_time to 90.1" do
86
+ @httperf_result.reply_time.should == 90.1
87
+ end
88
+
89
+ it "the net_io should be 7.7" do
90
+ @httperf_result.net_io.should == 7.7
91
+ end
92
+
93
+ it "the errors should be 0" do
94
+ @httperf_result.errors.should == 0
95
+ end
96
+
97
+ it "the status should be 1" do
98
+ @httperf_result.status.should == 1
99
+ end
100
+
101
+ it "reply_rate_min should be 9.8" do
102
+ @httperf_result.reply_rate_min.should == 9.8
103
+ end
104
+
105
+ it "the reply_rate_avg should be 9.9" do
106
+ @httperf_result.reply_rate_avg.should == 9.9
107
+ end
108
+
109
+ it "the reply_rate_max should be 10.0" do
110
+ @httperf_result.reply_rate_max.should == 10.0
111
+ end
112
+
113
+ it "the reply_rate_stddev should be 0.1" do
114
+ @httperf_result.reply_rate_stddev.should == 0.1
115
+ end
116
+ end
117
+ end
118
+ end
119
+
@@ -0,0 +1,11 @@
1
+ require "rubygems"
2
+ require 'spec'
3
+
4
+ $:.unshift File.dirname(__FILE__) + "/../lib"
5
+
6
+ module Helpers
7
+ end
8
+
9
+ Spec::Runner.configure do |config|
10
+ config.include Helpers
11
+ end
@@ -0,0 +1,30 @@
1
+ rate = [<%= @data.map(&:rate).join(', ') %>];
2
+ request_rate = [<%= @data.map(&:request_rate).join(', ') %>];
3
+ connection_rate = [<%= @data.map(&:connection_rate).join(', ') %>];
4
+ reply_rate_avg = [<%= @data.map(&:reply_rate_avg).join(', ') %>];
5
+ reply_rate_max = [<%= @data.map(&:reply_rate_max).join(', ') %>];
6
+ reply_time = [<%= @data.map(&:reply_time).join(', ') %>];
7
+ reply_rate_stddev = [<%= @data.map(&:reply_rate_stddev).join(', ') %>];
8
+ errors = [<%= @data.map(&:errors).join(', ') %>];
9
+
10
+ plot(rate, request_rate, '-k*');
11
+ hold on;
12
+ plot(rate, connection_rate, '-kd');
13
+ hold on;
14
+ plot(rate, reply_rate_max, '-kp');
15
+ hold on;
16
+ plot(rate, reply_rate_max, '-k+');
17
+ hold on;
18
+ plot(rate, reply_rate_stddev, '-kh');
19
+ hold on;
20
+ plot(rate, reply_time, '-g*');
21
+ hold on;
22
+ plot(rate, errors, '-r*');
23
+
24
+ grid on;
25
+
26
+ axis([0 <%= @max_rate %> 0 <%= @max_rate %>]);
27
+ title('Hansel report for <%= "#{@data.first.server}:#{@data.first.port}#{@data.first.uri} (#{@data.first.num_conns}" %> connections per run)')
28
+ xlabel('Demanded Request Rate');
29
+ legend('Request Rate', 'Connection Rate', 'Avg. reply rate', 'Max. reply rate', 'Reply rate StdDev', 'Reply time', 'Errors');
30
+ print('<%= @png_output %>', '-dpng')
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 5
9
- version: 0.1.5
8
+ - 6
9
+ version: 0.1.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Paul Mylchreest
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-27 00:00:00 -04:00
17
+ date: 2010-05-05 00:00:00 -04:00
18
18
  default_executable: hansel
19
19
  dependencies: []
20
20
 
@@ -40,8 +40,13 @@ files:
40
40
  - lib/config.rb
41
41
  - lib/csv_formatter.rb
42
42
  - lib/hansel.rb
43
+ - lib/httperf_result.rb
44
+ - lib/httperf_result_parser.rb
43
45
  - lib/octave_formatter.rb
44
46
  - lib/yaml_formatter.rb
47
+ - spec/httperf_result_parser_spec.rb
48
+ - spec/spec_helper.rb
49
+ - templates/octave.m.erb
45
50
  has_rdoc: true
46
51
  homepage: http://github.com/xlymian/hansel
47
52
  licenses: []
@@ -72,5 +77,6 @@ rubygems_version: 1.3.6
72
77
  signing_key:
73
78
  specification_version: 3
74
79
  summary: Ruby driver for httperf - automated load and performance testing
75
- test_files: []
76
-
80
+ test_files:
81
+ - spec/httperf_result_parser_spec.rb
82
+ - spec/spec_helper.rb