hansel 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.