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/README.md +103 -0
- data/Rakefile +9 -1
- data/VERSION +1 -1
- data/bin/hansel +2 -5
- data/hansel.gemspec +23 -11
- data/lib/hansel/arg_parser.rb +84 -0
- data/lib/{csv_formatter.rb → hansel/formatting/csv_formatter.rb} +8 -13
- data/lib/hansel/formatting/formatting.rb +51 -0
- data/lib/{octave_formatter.rb → hansel/formatting/octave_formatter.rb} +1 -1
- data/lib/hansel/formatting/yaml_formatter.rb +10 -0
- data/lib/hansel/hansel.rb +77 -0
- data/lib/hansel/httperf/httperf.rb +36 -0
- data/lib/{httperf_result.rb → hansel/httperf_result.rb} +1 -1
- data/lib/{httperf_result_parser.rb → hansel/httperf_result_parser.rb} +1 -1
- data/lib/hansel/job_queue/job_queue.rb +27 -0
- data/lib/hansel.rb +9 -124
- data/spec/arg_parser_spec.rb +91 -34
- data/spec/hansel_spec.rb +134 -0
- data/spec/httperf_result_parser_spec.rb +3 -3
- data/spec/jobs.yml +8 -0
- data/spec/spec_helper.rb +1 -2
- metadata +44 -15
- data/README.rdoc +0 -22
- data/lib/arg_parser.rb +0 -143
- data/lib/config.rb +0 -60
- data/lib/yaml_formatter.rb +0 -14
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# hansel
|
2
|
+
|
3
|
+
Hansel is a pure ruby driver for httperf for automated load and performance testing. It will load
|
4
|
+
a job queue file, in a yaml format, run httperf with each job
|
5
|
+
|
6
|
+
# Installing Httperf and Hansel
|
7
|
+
|
8
|
+
## Httperf
|
9
|
+
|
10
|
+
For Linux (Ubuntu):
|
11
|
+
|
12
|
+
apt-get update && apt-get -y install rubygems httperf
|
13
|
+
|
14
|
+
On MacOS X using homebrew:
|
15
|
+
|
16
|
+
brew install httperf
|
17
|
+
|
18
|
+
finally:
|
19
|
+
|
20
|
+
gem install hansel
|
21
|
+
|
22
|
+
## Optional -- Installing Octave using macports (warning: long!)
|
23
|
+
|
24
|
+
sudo port install octave
|
25
|
+
|
26
|
+
# Example usage
|
27
|
+
|
28
|
+
Create a job queue file in ~/.hansel/jobs.yml:
|
29
|
+
|
30
|
+
---
|
31
|
+
- :server: www.example.com
|
32
|
+
:uri: /
|
33
|
+
:num_conns: 50
|
34
|
+
:low_rate: 10
|
35
|
+
:high_rate: 50
|
36
|
+
:rate_step: 10
|
37
|
+
|
38
|
+
- :server: www.apple.com
|
39
|
+
:uri: /
|
40
|
+
:num_conns: 50
|
41
|
+
:low_rate: 10
|
42
|
+
:high_rate: 50
|
43
|
+
:rate_step: 10
|
44
|
+
|
45
|
+
and run Hansel
|
46
|
+
|
47
|
+
hansel --verbose --format=octave
|
48
|
+
|
49
|
+
By default, the output is written into the ~/hansel_output directory. When the octave format is
|
50
|
+
specified, it uses the default template octave.m.erb in the project templates. Here is a sample
|
51
|
+
output from the previous job:
|
52
|
+
|
53
|
+
rate = [5, 10, 15, 20];
|
54
|
+
request_rate = [5.1, 9.3, 12.9, 15.8];
|
55
|
+
connection_rate = [5.1, 9.3, 12.9, 15.8];
|
56
|
+
reply_rate_avg = [0.0, 0.0, 0.0, 0.0];
|
57
|
+
reply_rate_max = [0.0, 0.0, 0.0, 0.0];
|
58
|
+
reply_time = [88.4, 93.4, 89.2, 89.1];
|
59
|
+
reply_rate_stddev = [0.0, 0.0, 0.0, 0.0];
|
60
|
+
errors = [0, 0, 0, 0];
|
61
|
+
|
62
|
+
plot(rate, request_rate, '-k*');
|
63
|
+
hold on;
|
64
|
+
plot(rate, connection_rate, '-kd');
|
65
|
+
hold on;
|
66
|
+
plot(rate, reply_rate_max, '-kp');
|
67
|
+
hold on;
|
68
|
+
plot(rate, reply_rate_max, '-k+');
|
69
|
+
hold on;
|
70
|
+
plot(rate, reply_rate_stddev, '-kh');
|
71
|
+
hold on;
|
72
|
+
plot(rate, reply_time, '-g*');
|
73
|
+
hold on;
|
74
|
+
plot(rate, errors, '-r*');
|
75
|
+
|
76
|
+
grid on;
|
77
|
+
|
78
|
+
axis([0 20 0 20]);
|
79
|
+
title('Hansel report for www.example.com:80/ (10 connections per run)')
|
80
|
+
xlabel('Demanded Request Rate');
|
81
|
+
legend('Request Rate', 'Connection Rate', 'Avg. reply rate', 'Max. reply rate', 'Reply rate StdDev', 'Reply time', 'Errors');
|
82
|
+
print('/Users/paulm/hansel_output/hansel-10.m.png', '-dpng')
|
83
|
+
|
84
|
+
Run octave on it will produce graph as a png file.
|
85
|
+
|
86
|
+
## Note on Patches/Pull Requests
|
87
|
+
|
88
|
+
* Fork the project.
|
89
|
+
* Make your feature addition or bug fix.
|
90
|
+
* Add tests for it. This is important so I don't break it in a
|
91
|
+
future version unintentionally.
|
92
|
+
* Commit, do not mess with rakefile, version, or history.
|
93
|
+
(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)
|
94
|
+
* Send me a pull request. Bonus points for topic branches.
|
95
|
+
|
96
|
+
## References
|
97
|
+
|
98
|
+
"HTTP Perforance Testing with httperf":http://agiletesting.blogspot.com/2005/04/http-performance-testing-with-httperf.html
|
99
|
+
"Perforance vs Load Testing":http://agiletesting.blogspot.com/2005/04/more-on-performance-vs-load-testing.html
|
100
|
+
|
101
|
+
## Copyright
|
102
|
+
|
103
|
+
Copyright (c) 2010 Paul Mylchreest. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
-
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "spec/rake/spectask"
|
6
|
+
rescue LoadError
|
7
|
+
puts "rspec (or a dependency) not available. Install it with: gem install rspec"
|
8
|
+
end
|
4
9
|
|
5
10
|
task :default => :spec
|
6
11
|
|
@@ -19,11 +24,14 @@ begin
|
|
19
24
|
require 'jeweler'
|
20
25
|
Jeweler::Tasks.new do |gem|
|
21
26
|
gem.name = "hansel"
|
27
|
+
gem.executables = "hansel"
|
22
28
|
gem.summary = %Q{Ruby driver for httperf - automated load and performance testing}
|
23
29
|
gem.description = %Q{Ruby driver for httperf - automated load and performance testing}
|
24
30
|
gem.email = "paul.mylchreest@mac.com"
|
25
31
|
gem.homepage = "http://github.com/xlymian/hansel"
|
26
32
|
gem.authors = ["Paul Mylchreest"]
|
33
|
+
gem.add_dependency('rspec')
|
34
|
+
gem.add_dependency 'typhoeus'
|
27
35
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
28
36
|
end
|
29
37
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/bin/hansel
CHANGED
@@ -10,10 +10,7 @@ class File
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
require File.here '/../lib/arg_parser'
|
14
|
-
require File.here '/../lib/config'
|
15
13
|
require File.here '/../lib/hansel'
|
16
|
-
|
17
|
-
options = Hansel::Config.new(ARGV).options
|
14
|
+
options = HanselCore::ArgParser.new( ARGV ).parse
|
18
15
|
exit if options.exit
|
19
|
-
|
16
|
+
HanselCore::Hansel.new( options ).load_job_queue.run
|
data/hansel.gemspec
CHANGED
@@ -5,38 +5,43 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hansel}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
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-
|
12
|
+
s.date = %q{2010-06-13}
|
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}
|
16
16
|
s.executables = ["hansel"]
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE",
|
19
|
-
"README.
|
19
|
+
"README.md"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".document",
|
23
23
|
".gitignore",
|
24
24
|
"LICENSE",
|
25
|
-
"README.
|
25
|
+
"README.md",
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"bin/hansel",
|
29
29
|
"hansel.gemspec",
|
30
|
-
"lib/arg_parser.rb",
|
31
|
-
"lib/config.rb",
|
32
|
-
"lib/csv_formatter.rb",
|
33
30
|
"lib/hansel.rb",
|
34
|
-
"lib/
|
35
|
-
"lib/
|
36
|
-
"lib/
|
37
|
-
"lib/
|
31
|
+
"lib/hansel/arg_parser.rb",
|
32
|
+
"lib/hansel/formatting/csv_formatter.rb",
|
33
|
+
"lib/hansel/formatting/formatting.rb",
|
34
|
+
"lib/hansel/formatting/octave_formatter.rb",
|
35
|
+
"lib/hansel/formatting/yaml_formatter.rb",
|
36
|
+
"lib/hansel/hansel.rb",
|
37
|
+
"lib/hansel/httperf/httperf.rb",
|
38
|
+
"lib/hansel/httperf_result.rb",
|
39
|
+
"lib/hansel/httperf_result_parser.rb",
|
40
|
+
"lib/hansel/job_queue/job_queue.rb",
|
38
41
|
"spec/arg_parser_spec.rb",
|
42
|
+
"spec/hansel_spec.rb",
|
39
43
|
"spec/httperf_result_parser_spec.rb",
|
44
|
+
"spec/jobs.yml",
|
40
45
|
"spec/spec_helper.rb",
|
41
46
|
"templates/octave.m.erb"
|
42
47
|
]
|
@@ -47,6 +52,7 @@ Gem::Specification.new do |s|
|
|
47
52
|
s.summary = %q{Ruby driver for httperf - automated load and performance testing}
|
48
53
|
s.test_files = [
|
49
54
|
"spec/arg_parser_spec.rb",
|
55
|
+
"spec/hansel_spec.rb",
|
50
56
|
"spec/httperf_result_parser_spec.rb",
|
51
57
|
"spec/spec_helper.rb"
|
52
58
|
]
|
@@ -56,9 +62,15 @@ Gem::Specification.new do |s|
|
|
56
62
|
s.specification_version = 3
|
57
63
|
|
58
64
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
65
|
+
s.add_runtime_dependency(%q<rspec>, [">= 0"])
|
66
|
+
s.add_runtime_dependency(%q<typhoeus>, [">= 0"])
|
59
67
|
else
|
68
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
69
|
+
s.add_dependency(%q<typhoeus>, [">= 0"])
|
60
70
|
end
|
61
71
|
else
|
72
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
73
|
+
s.add_dependency(%q<typhoeus>, [">= 0"])
|
62
74
|
end
|
63
75
|
end
|
64
76
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module HanselCore
|
2
|
+
#
|
3
|
+
# Parse the command configuration file options and command line arguments.
|
4
|
+
# Command line arguments override those from the configuration file
|
5
|
+
# See http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html
|
6
|
+
#
|
7
|
+
class ArgParser
|
8
|
+
#
|
9
|
+
# Setup default values for the parsed options
|
10
|
+
#
|
11
|
+
def initialize args
|
12
|
+
@args = args
|
13
|
+
@options = OpenStruct.new(
|
14
|
+
:verbose => false,
|
15
|
+
:output_format => :yaml,
|
16
|
+
:output_dir => File.join(ENV['HOME'], 'hansel_output'),
|
17
|
+
:template_path => 'templates',
|
18
|
+
:template => nil,
|
19
|
+
:exit => false,
|
20
|
+
:master => nil
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Uses OptionParser to return an OpenStruct object describing the options.
|
26
|
+
#
|
27
|
+
def parse
|
28
|
+
# The options specified on the command line will be collected in *options*.
|
29
|
+
# We set default values here.
|
30
|
+
OptionParser.new { |options| parse_options options}.parse!(@args)
|
31
|
+
@options
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def output_options options
|
37
|
+
options.on("-f", "--format=format",
|
38
|
+
"Specify the ouptut format for the results.") do |format|
|
39
|
+
@options.format = format
|
40
|
+
end
|
41
|
+
options.on("-d", "--dir=output directory",
|
42
|
+
"Specify the ouptut directory for the results.") do |format|
|
43
|
+
@options.output_dir = format
|
44
|
+
end
|
45
|
+
options.on("-t", "--template=template",
|
46
|
+
"Specify the ouptut erb template.") do |template|
|
47
|
+
@options.template = template
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def other_options options
|
52
|
+
options.on("-v", "--[no-]verbose", "Run verbosely") do |verbose|
|
53
|
+
@options.verbose = verbose
|
54
|
+
end
|
55
|
+
|
56
|
+
options.on_tail("-h", "--help", "Show this message") do
|
57
|
+
puts options
|
58
|
+
@options.exit = true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def distributed_mode_options options
|
63
|
+
options.on("-m", "--master=hostname[:port]",
|
64
|
+
"Specify the master command and control machine.") do |master|
|
65
|
+
@options.master = master
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def version options
|
70
|
+
options.on_tail("--version", "Show version") do
|
71
|
+
puts "Hansel version #{IO.foreach('VERSION').first.strip}"
|
72
|
+
@options.exit = true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_options options
|
77
|
+
options.banner = "Usage: hansel [options]"
|
78
|
+
options.separator "Options:"
|
79
|
+
%w( output_options other_options version distributed_mode_options ).map(&:to_sym).each do |method|
|
80
|
+
self.send method, options
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,31 +1,26 @@
|
|
1
1
|
require 'csv'
|
2
2
|
|
3
|
-
module
|
3
|
+
module HanselCore
|
4
4
|
|
5
5
|
# Output to csv format
|
6
6
|
#
|
7
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)
|
8
|
+
COLUMNS = %w(server port num_conns rate replies connection_rate request_rate reply_time net_io
|
9
|
+
errors status reply_rate_min reply_rate_avg reply_rate_max reply_rate_stddev)
|
11
10
|
|
12
|
-
def
|
13
|
-
@data = data
|
14
|
-
@csv = ""
|
15
|
-
end
|
16
|
-
|
17
|
-
def line text
|
11
|
+
def self.line text
|
18
12
|
@csv << text
|
19
13
|
@csv << "\n"
|
20
14
|
end
|
21
15
|
|
22
|
-
def format_line data
|
16
|
+
def self.format_line data
|
23
17
|
line CSV.generate_line( COLUMNS.map { |column| data.send column.to_sym } )
|
24
18
|
end
|
25
19
|
|
26
|
-
def format
|
20
|
+
def self.format results
|
21
|
+
@csv = ""
|
27
22
|
line CSV.generate_line(COLUMNS)
|
28
|
-
|
23
|
+
results.each { |data| format_line data } unless results.empty?
|
29
24
|
@csv
|
30
25
|
end
|
31
26
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module HanselCore
|
2
|
+
module Formatting
|
3
|
+
def yaml_formatter
|
4
|
+
load 'lib/hansel/formatting/yaml_formatter.rb'
|
5
|
+
File.open(output_filename, "w+") do |file|
|
6
|
+
file.puts YamlFormatter.format results
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def csv_formatter
|
11
|
+
load 'lib/hansel/formatting/csv_formatter.rb'
|
12
|
+
File.open(output_filename, "w+") do |file|
|
13
|
+
file.puts CsvFormatter.format results
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def octave_formatter
|
18
|
+
load 'lib/hansel/formatting/octave_formatter.rb'
|
19
|
+
num_conns = results.first.num_conns rescue nil
|
20
|
+
file_name = output_filename{ "-#{num_conns.to_s}" }
|
21
|
+
File.open(file_name, "w+") do |file|
|
22
|
+
file.puts OctaveFormatter.new(results,
|
23
|
+
{
|
24
|
+
:output_file_name => file_name,
|
25
|
+
:template => options.template ||
|
26
|
+
File.join( [ options.template_path, 'octave.m.erb' ] ),
|
27
|
+
}
|
28
|
+
).format
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def formatted_output
|
33
|
+
formatter = "#{options.format}_formatter".to_sym
|
34
|
+
unless self.respond_to? formatter
|
35
|
+
status "Using default octave_formatter"
|
36
|
+
octave_formatter
|
37
|
+
else
|
38
|
+
status "Using #{formatter}"
|
39
|
+
self.send formatter
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def output_filename
|
44
|
+
part = block_given? ? yield : ''
|
45
|
+
type = { :yaml => 'yml', :csv => 'csv', :octave => 'm' }[options.format.to_sym]
|
46
|
+
server = results.first.server
|
47
|
+
port = results.first.port
|
48
|
+
[File.join([options.output_dir, ("#{server}:#{port}" + part)]), type].join('.')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module HanselCore
|
2
|
+
#
|
3
|
+
# Class wrapper over httperf.
|
4
|
+
#
|
5
|
+
class Hansel
|
6
|
+
include Formatting
|
7
|
+
include Httperf
|
8
|
+
include JobQueue
|
9
|
+
|
10
|
+
attr_reader :results, :options
|
11
|
+
|
12
|
+
def initialize options = OpenStruct.new {}
|
13
|
+
@options = options
|
14
|
+
@results = []
|
15
|
+
@current_rate = nil
|
16
|
+
@jobs = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def config_path
|
20
|
+
@config_path ||= File.join [ENV['HOME'], '.hansel']
|
21
|
+
FileUtils.mkdir_p @config_path unless File.exists? @config_path
|
22
|
+
@config_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def output_dir
|
26
|
+
@output_dir ||= File.join [ENV['HOME'], 'hansel_output']
|
27
|
+
@output_dir
|
28
|
+
end
|
29
|
+
|
30
|
+
def register
|
31
|
+
response = Typhoeus::Request.get options.master
|
32
|
+
@token = JSON.parse(response.body)['token']
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Output the results based on the requested output format
|
37
|
+
#
|
38
|
+
def output
|
39
|
+
if options.format
|
40
|
+
FileUtils.mkdir_p options.output_dir
|
41
|
+
formatted_output
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def status text
|
46
|
+
puts text if options.verbose
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Run httperf from low_rate to high_rate, stepping by rate_step
|
51
|
+
#
|
52
|
+
def run
|
53
|
+
status "starting run..."
|
54
|
+
while @jobs.length > 0 do
|
55
|
+
@current_job = @jobs.pop
|
56
|
+
(@current_job.low_rate.to_i..@current_job.high_rate.to_i).step(@current_job.rate_step.to_i) do |rate|
|
57
|
+
status "running httperf at rate: #{rate}"
|
58
|
+
@current_rate = rate
|
59
|
+
httperf
|
60
|
+
end
|
61
|
+
output
|
62
|
+
@results.clear
|
63
|
+
end
|
64
|
+
status "ending run..."
|
65
|
+
end
|
66
|
+
|
67
|
+
def run_server
|
68
|
+
HanselSlaveServer.hansel = self
|
69
|
+
HanselSlaveServer.run! :host => 'localhost', :port => 4000
|
70
|
+
end
|
71
|
+
|
72
|
+
trap("INT") {
|
73
|
+
puts "Terminating."
|
74
|
+
Process.exit
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module HanselCore
|
2
|
+
module Httperf
|
3
|
+
def build_httperf_cmd
|
4
|
+
httperf_cmd = [
|
5
|
+
"httperf --hog",
|
6
|
+
"--server=#{@current_job.server}",
|
7
|
+
"--port=#{@current_job.port}",
|
8
|
+
"--uri=#{@current_job.uri}",
|
9
|
+
"--num-conns=#{@current_job.num_conns}",
|
10
|
+
"--rate=#{@current_rate}",
|
11
|
+
@current_job.cookie && "--add-header='Cookie: #{@current_job.cookie}\\n'"
|
12
|
+
].compact.join ' '
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Runs httperf with a given request rate. Parses the output and returns
|
17
|
+
# a hash with the results.
|
18
|
+
#
|
19
|
+
def httperf
|
20
|
+
httperf_cmd = build_httperf_cmd
|
21
|
+
IO.popen("#{httperf_cmd} 2>&1") do |pipe|
|
22
|
+
status "\n#{httperf_cmd}"
|
23
|
+
@results << (httperf_result = HttperfResult.new({
|
24
|
+
:rate => @current_rate,
|
25
|
+
:server => @current_job.server,
|
26
|
+
:port => @current_job.port,
|
27
|
+
:uri => @current_job.uri,
|
28
|
+
:num_conns => @current_job.num_conns
|
29
|
+
}))
|
30
|
+
HttperfResultParser.new(pipe).parse(httperf_result)
|
31
|
+
end
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module HanselCore
|
2
|
+
module JobQueue
|
3
|
+
def jobs
|
4
|
+
@jobs
|
5
|
+
end
|
6
|
+
|
7
|
+
def push_job job
|
8
|
+
job.port = 80 unless job.port
|
9
|
+
@jobs.push job
|
10
|
+
end
|
11
|
+
|
12
|
+
def pop_job job
|
13
|
+
@jobs.pop
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Load jobs from queue
|
18
|
+
#
|
19
|
+
def load_job_queue
|
20
|
+
(YAML.load_file File.join(config_path, 'jobs.yml')).map do |job|
|
21
|
+
self.push_job(OpenStruct.new job)
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|