hansel 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/hansel.rb CHANGED
@@ -1,127 +1,12 @@
1
1
  require 'fileutils'
2
- require 'lib/httperf_result_parser'
3
- require 'lib/httperf_result'
2
+ require 'yaml'
4
3
 
5
- module Hansel
6
- #
7
- # Class wrapper over httperf.
8
- #
9
- class Hansel
10
- def initialize(options = {})
11
- @options = options
12
- @results = []
13
- @current_rate = nil
14
- end
4
+ $:.unshift File.dirname(__FILE__) + "/../lib/hansel"
15
5
 
16
- def build_httperf_cmd
17
- cookie = @options.cookie
18
- httperf_cmd = [
19
- "httperf --hog",
20
- "--server=#{@options.server}",
21
- "--port=#{@options.port}",
22
- "--uri=#{@options.uri}",
23
- "--num-conns=#{@options.num_conns}",
24
- "--rate=#{@current_rate}",
25
- cookie && "--add-header='Cookie: #{cookie}\\n'"
26
- ].compact.join ' '
27
- end
28
-
29
- #
30
- # Runs httperf with a given request rate. Parses the output and returns
31
- # a hash with the results.
32
- #
33
- def httperf
34
- httperf_cmd = build_httperf_cmd
35
- IO.popen("#{httperf_cmd} 2>&1") do |pipe|
36
- puts "\n#{httperf_cmd}"
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)
45
- end
46
- end
47
-
48
- def yaml_formatter
49
- load File.here '/../lib/yaml_formatter.rb'
50
- YamlFormatter.new(@results)
51
- end
52
-
53
- def csv_formatter
54
- load File.here '/../lib/csv_formatter.rb'
55
- CsvFormatter.new(@results)
56
- end
57
-
58
- def octave_formatter
59
- load File.here '/../lib/octave_formatter.rb'
60
- puts @output_file_name
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
77
- end
78
- end
79
-
80
- def formatted_output
81
- @output_file_name = [@options.server, @options.num_conns.to_s].join('.')
82
- output_file = File.join @options.output_dir, @output_file_name
83
- output_format = @options.output_format
84
- type = { :yaml => 'yml', :csv => 'csv', :octave => 'm' }[output_format]
85
- File.open([output_file, type].join('.'), "w+") do |file|
86
- file.puts format(output_format).format
87
- end
88
- end
89
-
90
- #
91
- # Output the results based on the requested output format
92
- #
93
- def output
94
- if @options.output
95
- FileUtils.mkdir_p @options.output_dir
96
- formatted_output
97
- end
98
- end
99
-
100
- def status text
101
- puts text if @options.verbose
102
- end
103
-
104
- def run_all
105
- (@options.low_rate.to_i..@options.high_rate.to_i).step(@options.rate_step.to_i) do |rate|
106
- status "running httperf at rate: #{rate}"
107
- @current_rate = rate
108
- httperf
109
- end
110
- end
111
-
112
- #
113
- # Run httperf from low_rate to high_rate, stepping by rate_step
114
- #
115
- def run
116
- status "starting run..."
117
- run_all
118
- output
119
- status "ending run..."
120
- end
121
-
122
- trap("INT") {
123
- puts "Terminating."
124
- Process.exit
125
- }
126
- end
127
- end
6
+ require 'arg_parser'
7
+ require 'formatting/formatting'
8
+ require 'httperf/httperf'
9
+ require 'httperf_result'
10
+ require 'httperf_result_parser'
11
+ require 'job_queue/job_queue'
12
+ require 'hansel'
@@ -1,57 +1,114 @@
1
1
  require File.dirname(__FILE__) + "/spec_helper"
2
- require 'arg_parser'
3
2
 
4
- describe Hansel::ArgParser, "#parse" do
3
+ describe HanselCore::ArgParser, "#parse" do
5
4
  before :each do
6
- @argv = [
7
- '--server=frunobulax.local',
8
- '--port=4000',
9
- '--uri=/',
10
- '--num_conns=1',
11
- '--low_rate=1',
12
- '--high_rate=5',
13
- '--rate_step=1',
14
- '--format=octave',
15
- '--output=true'
16
- ]
17
- @options = Hansel::ArgParser.new(@argv).parse
18
5
  end
19
6
 
20
- describe "should set the" do
21
- it "server to 'frunobulax.local'" do
22
- @options.server.should == 'frunobulax.local'
23
- end
7
+ describe "when the option" do
8
+ describe "master is set to 'localhost:4000'" do
9
+ it "should set master" do
10
+ @argv = [ '--master=localhost:4000' ]
11
+ @options = HanselCore::ArgParser.new(@argv).parse
12
+ @options.master.should == 'localhost:4000'
13
+ end
24
14
 
25
- it "port to 4000" do
26
- @options.port.should == 4000
15
+ it "should set master" do
16
+ @argv = [ '-mlocalhost:4000' ]
17
+ @options = HanselCore::ArgParser.new(@argv).parse
18
+ @options.master.should == 'localhost:4000'
19
+ end
27
20
  end
28
21
 
29
- it "uri to '/" do
30
- @options.uri.should == '/'
22
+ describe "dir is set to '/tmp/hansel_output'" do
23
+ it "should set output_dir" do
24
+ @argv = [ '--dir=/tmp/hansel_output' ]
25
+ @options = HanselCore::ArgParser.new(@argv).parse
26
+ @options.output_dir.should == '/tmp/hansel_output'
27
+ end
28
+
29
+ it "should set output_dir" do
30
+ @argv = [ '-d/tmp/hansel_output' ]
31
+ @options = HanselCore::ArgParser.new(@argv).parse
32
+ @options.output_dir.should == '/tmp/hansel_output'
33
+ end
34
+
35
+ it "should set template" do
36
+ @argv = [ '--template=/home/templates' ]
37
+ @options = HanselCore::ArgParser.new(@argv).parse
38
+ @options.template.should == '/home/templates'
39
+ end
40
+
41
+ it "should set template" do
42
+ @argv = [ '-t/home/templates' ]
43
+ @options = HanselCore::ArgParser.new(@argv).parse
44
+ @options.template.should == '/home/templates'
45
+ end
31
46
  end
32
47
 
33
- it "num_conns to 1" do
34
- @options.num_conns.should == 1
48
+ %w(yaml csv octave).each do |format|
49
+ describe "output --format is set to #{format}" do
50
+ it "should set format #{format}" do
51
+ @argv = [ "--format=#{format}" ]
52
+ @options = HanselCore::ArgParser.new(@argv).parse
53
+ @options.format.should == format
54
+ end
55
+
56
+ it "should set format to #{format}" do
57
+ @argv = [ "-f#{format}" ]
58
+ @options = HanselCore::ArgParser.new(@argv).parse
59
+ @options.format.should == format
60
+ end
61
+ end
35
62
  end
36
63
 
37
- it "low_rate to 1" do
38
- @options.low_rate.should == 1
64
+ describe "verbose is set" do
65
+ it "should set verbose to true" do
66
+ @argv = [ '--verbose' ]
67
+ @options = HanselCore::ArgParser.new(@argv).parse
68
+ @options.verbose.should == true
69
+ end
70
+ it "should set verbose to true" do
71
+ @argv = [ '-v' ]
72
+ @options = HanselCore::ArgParser.new(@argv).parse
73
+ @options.verbose.should == true
74
+ end
39
75
  end
40
76
 
41
- it "high_rate to 5" do
42
- @options.high_rate.should == 5
77
+ describe "no-verbose is set" do
78
+ it "should set verbose to false" do
79
+ @argv = [ '--verbose', '--no-verbose' ]
80
+ @options = HanselCore::ArgParser.new(@argv).parse
81
+ @options.verbose.should == false
82
+ end
43
83
  end
44
84
 
45
- it "rate_step to 1" do
46
- @options.rate_step.should == 1
85
+ describe "verbose is not set" do
86
+ it "verbose defaults to false" do
87
+ @argv = [ ]
88
+ @options = HanselCore::ArgParser.new(@argv).parse
89
+ @options.verbose.should == false
90
+ end
47
91
  end
48
92
 
49
- it "output_format to 'octave'" do
50
- @options.output_format.should == :octave
93
+ describe "help is set" do
94
+ it "should set exit to true" do
95
+ @argv = [ '--help' ]
96
+ @options = HanselCore::ArgParser.new(@argv).parse
97
+ @options.exit.should == true
98
+ end
99
+ it "should set exit to true" do
100
+ @argv = [ '-h' ]
101
+ @options = HanselCore::ArgParser.new(@argv).parse
102
+ @options.exit.should == true
103
+ end
51
104
  end
52
105
 
53
- it "output to 'true'" do
54
- @options.output.should == true
106
+ describe "version is set" do
107
+ it "should set exit to true" do
108
+ @argv = [ '--version' ]
109
+ @options = HanselCore::ArgParser.new(@argv).parse
110
+ @options.exit.should == true
111
+ end
55
112
  end
56
113
  end
57
114
  end
@@ -0,0 +1,134 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ require 'typhoeus'
4
+ require 'json'
5
+ require 'yaml'
6
+ require 'ostruct'
7
+
8
+ describe HanselCore, "in general" do
9
+ before :each do
10
+ @hansel = HanselCore::Hansel.new
11
+ @hansel.stub(:config_path).and_return 'spec'
12
+ end
13
+
14
+ it "should have an empty job queue" do
15
+ @hansel.should respond_to :push_job
16
+ @hansel.should respond_to :jobs
17
+ @hansel.jobs.length.should == 0
18
+ end
19
+
20
+ describe "adding to the job queue" do
21
+ before :each do
22
+ jobs = YAML.load_file(File.join ['spec', 'jobs.yml']).map{ |job| OpenStruct.new job }
23
+ jobs.each{ |job| @hansel.push_job job }
24
+ end
25
+
26
+ it "should have some jobs" do
27
+ @hansel.jobs.length.should > 0
28
+ end
29
+ end
30
+
31
+ describe "when calling run" do
32
+ before :each do
33
+ @hansel.stub( :httperf ).and_return @hansel
34
+ @hansel.load_job_queue
35
+ end
36
+
37
+ describe "initially" do
38
+ it "should have some jobs" do
39
+ @hansel.jobs.length.should > 0
40
+ end
41
+ end
42
+
43
+ describe "on completion" do
44
+ before :each do
45
+ @hansel.run
46
+ end
47
+
48
+ it "should have an empty job queue" do
49
+ @hansel.jobs.length.should == 0
50
+ end
51
+
52
+ it "should have results to output" do
53
+ @hansel.should respond_to :results
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "after a run" do
59
+ before :each do
60
+ result = HanselCore::HttperfResult.new :server => "localhost",
61
+ :port => 80,
62
+ :rate => 1,
63
+ :uri => "/",
64
+ :num_conns => 1
65
+
66
+ result.reply_time = 0.0
67
+ result.status = 0
68
+ result.reply_rate_avg = 0.0
69
+ result.request_rate = 0.0
70
+ result.reply_rate_min = 0.0
71
+ result.connection_rate = 6754.1
72
+ result.errors = 1
73
+ result.reply_rate_stddev = 0.0
74
+ result.net_io = 0.0
75
+ result.replies = 0
76
+ result.reply_rate_max = 0.0
77
+
78
+ @hansel.stub( :results ).and_return [ result ]
79
+ @hansel.stub( :options ).and_return HanselCore::ArgParser.
80
+ new( [ '--format=yaml', '--dir=/tmp/hansel_output' ] ).parse
81
+ end
82
+
83
+ describe "calling output" do
84
+ before :each do
85
+ @default_name = File.join [ @hansel.options.output_dir, 'localhost:80.yml' ]
86
+ FileUtils.rm @default_name if File.exists? @default_name
87
+ @hansel.output
88
+ end
89
+
90
+ it "should have stubbed results" do
91
+ @hansel.results.size.should > 0
92
+ end
93
+
94
+ describe "should put the output into a file in the specified format" do
95
+ it "should be in a file with the default file name" do
96
+ @default_name.should == @hansel.output_filename
97
+ File.exists?( @default_name ).should be_true
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ describe HanselCore, "in distributed mode" do
105
+ before :each do
106
+ @options = HanselCore::ArgParser.new( [ '--master=localhost:4000' ] ).parse
107
+ end
108
+
109
+ describe "should register with the master" do
110
+ before :each do
111
+ response = Typhoeus::Response.new(
112
+ :code => 200,
113
+ :headers => "",
114
+ :body => { :token => '0123456789' }.to_json,
115
+ :time => 0.3)
116
+ Typhoeus::Request.stub(:get, @options.master).and_return response
117
+ end
118
+
119
+ describe "when initialized" do
120
+ before :each do
121
+ @hansel = HanselCore::Hansel.new @options
122
+ @hansel.stub(:config_path).and_return 'spec'
123
+ end
124
+
125
+ it "should be able to register with the master server" do
126
+ @hansel.should respond_to :register
127
+ end
128
+
129
+ it "should return the access token when registring with the master server" do
130
+ @hansel.register.should == '0123456789'
131
+ end
132
+ end
133
+ end
134
+ end
@@ -28,14 +28,14 @@ Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
28
28
  Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
29
29
  EOS
30
30
 
31
- describe Hansel::HttperfResultParser, "#score" do
31
+ describe HanselCore::HttperfResultParser, "#score" do
32
32
  before(:each) do
33
- @parser = Hansel::HttperfResultParser.new SAMPLE_HTTPERF_OUTPUT
33
+ @parser = HanselCore::HttperfResultParser.new SAMPLE_HTTPERF_OUTPUT
34
34
  end
35
35
 
36
36
  describe "when calling parse" do
37
37
  before(:each) do
38
- @httperf_result = Hansel::HttperfResult.new(
38
+ @httperf_result = HanselCore::HttperfResult.new(
39
39
  :rate => 10,
40
40
  :server => 'www.example.com',
41
41
  :port => 80,
data/spec/jobs.yml ADDED
@@ -0,0 +1,8 @@
1
+ ---
2
+ - :server: localhost
3
+ :uri: /
4
+ :format: octave
5
+ :num_conns: 1
6
+ :low_rate: 1
7
+ :high_rate: 5
8
+ :rate_step: 1
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "rubygems"
2
2
  require 'spec'
3
-
4
- $:.unshift File.dirname(__FILE__) + "/../lib"
3
+ require 'lib/hansel'
5
4
 
6
5
  module Helpers
7
6
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 7
9
- version: 0.1.7
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Paul Mylchreest
@@ -14,10 +14,33 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-08 00:00:00 -04:00
17
+ date: 2010-06-13 00:00:00 -04:00
18
18
  default_executable: hansel
19
- dependencies: []
20
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: typhoeus
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :runtime
43
+ version_requirements: *id002
21
44
  description: Ruby driver for httperf - automated load and performance testing
22
45
  email: paul.mylchreest@mac.com
23
46
  executables:
@@ -26,26 +49,31 @@ extensions: []
26
49
 
27
50
  extra_rdoc_files:
28
51
  - LICENSE
29
- - README.rdoc
52
+ - README.md
30
53
  files:
31
54
  - .document
32
55
  - .gitignore
33
56
  - LICENSE
34
- - README.rdoc
57
+ - README.md
35
58
  - Rakefile
36
59
  - VERSION
37
60
  - bin/hansel
38
61
  - hansel.gemspec
39
- - lib/arg_parser.rb
40
- - lib/config.rb
41
- - lib/csv_formatter.rb
42
62
  - lib/hansel.rb
43
- - lib/httperf_result.rb
44
- - lib/httperf_result_parser.rb
45
- - lib/octave_formatter.rb
46
- - lib/yaml_formatter.rb
63
+ - lib/hansel/arg_parser.rb
64
+ - lib/hansel/formatting/csv_formatter.rb
65
+ - lib/hansel/formatting/formatting.rb
66
+ - lib/hansel/formatting/octave_formatter.rb
67
+ - lib/hansel/formatting/yaml_formatter.rb
68
+ - lib/hansel/hansel.rb
69
+ - lib/hansel/httperf/httperf.rb
70
+ - lib/hansel/httperf_result.rb
71
+ - lib/hansel/httperf_result_parser.rb
72
+ - lib/hansel/job_queue/job_queue.rb
47
73
  - spec/arg_parser_spec.rb
74
+ - spec/hansel_spec.rb
48
75
  - spec/httperf_result_parser_spec.rb
76
+ - spec/jobs.yml
49
77
  - spec/spec_helper.rb
50
78
  - templates/octave.m.erb
51
79
  has_rdoc: true
@@ -80,5 +108,6 @@ specification_version: 3
80
108
  summary: Ruby driver for httperf - automated load and performance testing
81
109
  test_files:
82
110
  - spec/arg_parser_spec.rb
111
+ - spec/hansel_spec.rb
83
112
  - spec/httperf_result_parser_spec.rb
84
113
  - spec/spec_helper.rb
data/README.rdoc DELETED
@@ -1,22 +0,0 @@
1
- = hansel
2
-
3
- Description goes here.
4
-
5
- == Note on Patches/Pull Requests
6
-
7
- * Fork the project.
8
- * Make your feature addition or bug fix.
9
- * Add tests for it. This is important so I don't break it in a
10
- future version unintentionally.
11
- * Commit, do not mess with rakefile, version, or history.
12
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
- * Send me a pull request. Bonus points for topic branches.
14
-
15
- == References
16
-
17
- "HTTP Perforance Testing with httperf":http://agiletesting.blogspot.com/2005/04/http-performance-testing-with-httperf.html
18
- "Perforance vs Load Testing":http://agiletesting.blogspot.com/2005/04/more-on-performance-vs-load-testing.html
19
-
20
- == Copyright
21
-
22
- Copyright (c) 2010 Paul Mylchreest. See LICENSE for details.