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/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/lib/hansel.rb
CHANGED
@@ -1,127 +1,12 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require '
|
3
|
-
require 'lib/httperf_result'
|
2
|
+
require 'yaml'
|
4
3
|
|
5
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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'
|
data/spec/arg_parser_spec.rb
CHANGED
@@ -1,57 +1,114 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
-
require 'arg_parser'
|
3
2
|
|
4
|
-
describe
|
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 "
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
26
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
34
|
-
|
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
|
-
|
38
|
-
|
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
|
-
|
42
|
-
|
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
|
-
|
46
|
-
|
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
|
-
|
50
|
-
|
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
|
-
|
54
|
-
|
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
|
data/spec/hansel_spec.rb
ADDED
@@ -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
|
31
|
+
describe HanselCore::HttperfResultParser, "#score" do
|
32
32
|
before(:each) do
|
33
|
-
@parser =
|
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 =
|
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
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
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-
|
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.
|
52
|
+
- README.md
|
30
53
|
files:
|
31
54
|
- .document
|
32
55
|
- .gitignore
|
33
56
|
- LICENSE
|
34
|
-
- README.
|
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/
|
44
|
-
- lib/
|
45
|
-
- lib/
|
46
|
-
- lib/
|
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.
|