-
Notifications
You must be signed in to change notification settings - Fork 23
/
autoperf.rb
113 lines (95 loc) · 3.28 KB
/
autoperf.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#--
# Copyright (C)2008 Ilya Grigorik
# You can redistribute this under the terms of the Ruby license
#++
require 'rubygems'
require 'optparse'
require 'ruport'
class AutoPerf
def initialize(opts = {})
@conf = {}
OptionParser.new do |opts|
opts.banner = "Usage: autoperf.rb [-c config]"
opts.on("-c", "--config [string]", String, "configuration file") do |v|
@conf = parse_config(v)
end
end.parse!
run()
end
def parse_config(config_file)
raise Errno::EACCES, "#{config_file} is not readable" unless File.readable?(config_file)
conf = {}
open(config_file).each { |line|
line.chomp
unless (/^\#/.match(line))
if(/\s*=\s*/.match(line))
param, value = line.split(/\s*=\s*/, 2)
var_name = "#{param}".chomp.strip
value = value.chomp.strip
new_value = ''
if (value)
if value =~ /^['"](.*)['"]$/
new_value = $1
else
new_value = value
end
else
new_value = ''
end
conf[var_name] = new_value
end
end
}
if conf['wlog']
conf['wlog'] = Dir[conf['wlog']].sort
end
return conf
end
def benchmark(conf)
httperf_opt = conf.keys.grep(/httperf/).collect {|k| "--#{k.gsub(/httperf_/, '')} #{conf[k]}"}.join(" ")
if conf['wlog']
wlog = conf['wlog'].shift
conf['wlog'].push wlog
wlog_opt = "--wlog n,#{wlog}"
end
httperf_cmd = "httperf --hog --server=#{conf['host']} --uri=#{conf['uri']} --port=#{conf['port']} #{httperf_opt} #{wlog_opt}"
res = Hash.new("")
IO.popen("#{httperf_cmd} 2>&1") do |pipe|
puts "\n#{httperf_cmd}"
while((line = pipe.gets))
res['output'] += line
case line
when /^Total: .*replies (\d+)/ then res['replies'] = $1
when /^Connection rate: (\d+\.\d)/ then res['conn/s'] = $1
when /^Request rate: (\d+\.\d)/ then res['req/s'] = $1
when /^Reply time .* response (\d+\.\d)/ then res['reply time'] = $1
when /^Net I\/O: (\d+\.\d)/ then res['net io (KB/s)'] = $1
when /^Errors: total (\d+)/ then res['errors'] = $1
when /^Reply rate .*min (\d+\.\d) avg (\d+\.\d) max (\d+\.\d) stddev (\d+\.\d)/ then
res['replies/s min'] = $1
res['replies/s avg'] = $2
res['replies/s max'] = $3
res['replies/s stddev'] = $4
when /^Reply status: 1xx=\d+ 2xx=\d+ 3xx=\d+ 4xx=\d+ 5xx=(\d+)/ then res['5xx status'] = $1
end
end
end
return res
end
def run
results = {}
report = Table(:column_names => ['rate', 'conn/s', 'req/s', 'replies/s avg',
'errors', '5xx status', 'net io (KB/s)'])
(@conf['low_rate'].to_i..@conf['high_rate'].to_i).step(@conf['rate_step'].to_i) do |rate|
results[rate] = benchmark(@conf.merge({'httperf_rate' => rate}))
report << results[rate].merge({'rate' => rate})
puts report.to_s
puts results[rate]['output'] if results[rate]['errors'].to_i > 0 || results[rate]['5xx status'].to_i > 0
end
end
end
trap("INT") {
puts "Terminating tests."
Process.exit
}
AutoPerf.new()