stella 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +14 -10
- data/Rakefile +22 -36
- data/lib/daemonize.rb +56 -0
- data/lib/stella/adapter/ab.rb +49 -39
- data/lib/stella/adapter/base.rb +17 -8
- data/lib/stella/adapter/httperf.rb +24 -18
- data/lib/stella/adapter/pcap_watcher.rb +1 -1
- data/lib/stella/adapter/siege.rb +15 -12
- data/lib/stella/cli/localtest.rb +2 -3
- data/lib/stella/cli/sysinfo.rb +0 -1
- data/lib/stella/cli.rb +10 -55
- data/lib/stella/command/base.rb +0 -62
- data/lib/stella/command/localtest.rb +35 -36
- data/lib/stella/data/domain.rb +18 -11
- data/lib/stella/data/http.rb +23 -16
- data/lib/stella/logger.rb +29 -19
- data/lib/stella/response.rb +5 -2
- data/lib/stella/storable.rb +138 -52
- data/lib/stella/support.rb +107 -8
- data/lib/stella/sysinfo.rb +26 -16
- data/lib/stella/test/definition.rb +1 -1
- data/lib/stella/test/run/summary.rb +23 -13
- data/lib/stella/test/stats.rb +114 -0
- data/lib/stella/text/resource.rb +1 -1
- data/lib/stella.rb +29 -4
- data/lib/utils/mathutil.rb +0 -76
- data/lib/utils/stats.rb +88 -0
- data/lib/win32/Console/ANSI.rb +305 -305
- data/lib/win32/Console.rb +970 -970
- data/support/ruby-pcap-takuma-patch.txt +13 -13
- data/support/text/en.yaml +11 -8
- data/support/text/nl.yaml +7 -1
- data/{spec/show-agents_spec.rb → tests/01-util_test.rb} +0 -0
- data/tests/02-stella-util_test.rb +42 -0
- data/tests/10-stella_test.rb +104 -0
- data/tests/11-stella-storable_test.rb +68 -0
- data/tests/60-stella-command_test.rb +248 -0
- data/tests/80-stella-cli_test.rb +45 -0
- data/tests/spec-helper.rb +31 -0
- data/vendor/{frylock/README.textile → drydock/LICENSE.txt} +2 -52
- data/vendor/drydock/README.textile +57 -0
- data/vendor/{frylock → drydock}/bin/example +14 -14
- data/vendor/{frylock/frylock.gemspec → drydock/drydock.gemspec} +1 -1
- data/vendor/{frylock/lib/frylock → drydock/lib/drydock}/exceptions.rb +1 -1
- data/vendor/{frylock/lib/frylock.rb → drydock/lib/drydock.rb} +8 -8
- data/vendor/{frylock → drydock}/test/command_test.rb +0 -0
- metadata +34 -61
- data/lib/stella/test/base.rb +0 -38
- data/lib/stella/test/summary.rb +0 -82
- data/vendor/hitimes-0.4.0/HISTORY +0 -28
- data/vendor/hitimes-0.4.0/LICENSE.txt +0 -19
- data/vendor/hitimes-0.4.0/README +0 -80
- data/vendor/hitimes-0.4.0/Rakefile +0 -63
- data/vendor/hitimes-0.4.0/examples/benchmarks.rb +0 -86
- data/vendor/hitimes-0.4.0/examples/stats.rb +0 -29
- data/vendor/hitimes-0.4.0/ext/extconf.rb +0 -15
- data/vendor/hitimes-0.4.0/ext/hitimes_ext.c +0 -21
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_clock_gettime.c +0 -20
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_osx.c +0 -16
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_windows.c +0 -27
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.c +0 -340
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.h +0 -73
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.c +0 -242
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.h +0 -30
- data/vendor/hitimes-0.4.0/ext/rbconfig-mingw.rb +0 -178
- data/vendor/hitimes-0.4.0/ext/rbconfig.rb +0 -178
- data/vendor/hitimes-0.4.0/gemspec.rb +0 -54
- data/vendor/hitimes-0.4.0/lib/hitimes/mutexed_stats.rb +0 -23
- data/vendor/hitimes-0.4.0/lib/hitimes/paths.rb +0 -54
- data/vendor/hitimes-0.4.0/lib/hitimes/stats.rb +0 -29
- data/vendor/hitimes-0.4.0/lib/hitimes/timer.rb +0 -223
- data/vendor/hitimes-0.4.0/lib/hitimes/version.rb +0 -42
- data/vendor/hitimes-0.4.0/lib/hitimes.rb +0 -24
- data/vendor/hitimes-0.4.0/spec/interval_spec.rb +0 -115
- data/vendor/hitimes-0.4.0/spec/mutex_stats_spec.rb +0 -34
- data/vendor/hitimes-0.4.0/spec/paths_spec.rb +0 -14
- data/vendor/hitimes-0.4.0/spec/spec_helper.rb +0 -6
- data/vendor/hitimes-0.4.0/spec/stats_spec.rb +0 -72
- data/vendor/hitimes-0.4.0/spec/timer_spec.rb +0 -105
- data/vendor/hitimes-0.4.0/spec/version_spec.rb +0 -27
- data/vendor/hitimes-0.4.0/tasks/announce.rake +0 -39
- data/vendor/hitimes-0.4.0/tasks/config.rb +0 -107
- data/vendor/hitimes-0.4.0/tasks/distribution.rake +0 -53
- data/vendor/hitimes-0.4.0/tasks/documentation.rake +0 -33
- data/vendor/hitimes-0.4.0/tasks/extension.rake +0 -64
- data/vendor/hitimes-0.4.0/tasks/rspec.rake +0 -31
- data/vendor/hitimes-0.4.0/tasks/rubyforge.rake +0 -52
- data/vendor/hitimes-0.4.0/tasks/utils.rb +0 -80
data/README.textile
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
h1. Stella - Your Performance Testing Friend
|
2
2
|
|
3
|
-
Release: 0.5.
|
3
|
+
Release: 0.5.5 (2009-01-14)
|
4
4
|
|
5
5
|
This is a BETA release. Proceed in double verify mode!
|
6
6
|
|
7
|
+
h2. Overview
|
8
|
+
|
9
|
+
Stella is a command-line tool for running, reporting, and analyzing performance tests.
|
10
|
+
|
7
11
|
|
8
12
|
h2. Prerequisites
|
9
13
|
|
@@ -17,9 +21,10 @@ h2. Prerequisites
|
|
17
21
|
** Ruby-Pcap (optional, for packet sniffing)
|
18
22
|
|
19
23
|
* One of:
|
20
|
-
** "Apache Bench":http://httpd.apache.org/docs/2.
|
24
|
+
** "Apache Bench":http://httpd.apache.org/docs/2.2/programs/ab.html
|
21
25
|
** "Siege":http://www.joedog.org/index/siege-home
|
22
26
|
** "Httperf":http://www.hpl.hp.com/research/linux/httperf/
|
27
|
+
*** _Note: Argument handling for Httperf is incomplete_
|
23
28
|
|
24
29
|
|
25
30
|
h2. Installation
|
@@ -59,14 +64,14 @@ On Ruby, 1.8.6, Ruby-Pcap produces the following warnings at runtime: "pcap.bund
|
|
59
64
|
|
60
65
|
h2. Usage Examples
|
61
66
|
|
62
|
-
Run Apache Bench with a warmup and rampup from
|
63
|
-
$ stella --warmup=0.5 --rampup=
|
67
|
+
Run Apache Bench with a warmup and rampup from 10 to 20 virtual users in increments of 5
|
68
|
+
$ stella --warmup=0.5 --rampup=5,20 ab -c 10 -n 50 http://stellaaahhhh.com/search?term=trooper
|
64
69
|
|
65
70
|
Run Siege, repeat the test 5 times. Automatically creates a summary averages and standard deviations.
|
66
|
-
$ stella --agent=ff-3-osx --testruns=5 siege -c
|
71
|
+
$ stella --agent=ff-3-osx --testruns=5 siege -c 10 -r 5 -b http://stellaaahhhh.com/search?term=flock+of+seagulls
|
67
72
|
|
68
73
|
Run Httperf like you normally would (but all the test data will be collected for you)
|
69
|
-
$ stella httperf --hog --client=0/1 --server=127.0.0.1 --port=5600 --uri=/ --rate=50 --num-conns=
|
74
|
+
$ stella httperf --hog --client=0/1 --server=127.0.0.1 --port=5600 --uri=/ --rate=50 --num-conns=100 --timeout=5
|
70
75
|
|
71
76
|
Monitor DNS traffic using Pcap
|
72
77
|
$ stella watch -C dns
|
@@ -81,7 +86,7 @@ h2. Usage Examples
|
|
81
86
|
h3. Sample Output
|
82
87
|
|
83
88
|
<pre><code>
|
84
|
-
$ stella -f csv -x 5 -w 0.75 -r 25,125 -m "httpd 2.2.9-prefork" siege -c 75 -r 10 -b http://
|
89
|
+
$ stella -f csv -x 5 -w 0.75 -r 25,125 -m "httpd 2.2.9-prefork" siege -c 75 -r 10 -b http://testapp:5600/
|
85
90
|
Writing test data to: stella/testruns/2008-12-23/test-054
|
86
91
|
|
87
92
|
Warmup: 3750@37/1 100% 264.29/s 0.140s 0.024MB/s 0.340MB 14.000s .
|
@@ -137,10 +142,9 @@ h2. Known Issues
|
|
137
142
|
|
138
143
|
* The output for the REQ@VU/s columns is a work in progress. It's not aligned across tools and it will likely change in the next release.
|
139
144
|
* The summary data has not been audited. Don't trust and double verify!
|
140
|
-
* httperf is functional but
|
145
|
+
* httperf is functional but not all parameters are supported.
|
141
146
|
* The Ruby API has not been finalized. It's functional but there's no example because it is subject to change.
|
142
|
-
* There
|
143
|
-
* There is an issue with parsing ipv6 ip addresses with Ruby-Pcap or Net-DNS. This affects only dns sniffing with pcap. Reproduce by running "stella watch -P dns" and requesting "apple.com"
|
147
|
+
* There is an issue with parsing ipv6 ip addresses with Ruby-Pcap or Net-DNS. This affects only dns sniffing with pcap. Reproduce by running "stella watch -C dns" and requesting "apple.com"
|
144
148
|
|
145
149
|
|
146
150
|
h2. Report an issue
|
data/Rakefile
CHANGED
@@ -1,42 +1,29 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'spec/rake/spectask'
|
3
1
|
|
4
|
-
|
5
|
-
Spec::Rake::SpecTask.new('spec') do |t|
|
6
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
7
|
-
end
|
8
|
-
|
9
|
-
desc "Print specdocs"
|
10
|
-
Spec::Rake::SpecTask.new(:doc) do |t|
|
11
|
-
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
12
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
13
|
-
end
|
14
|
-
|
15
|
-
desc "Run all examples with RCov"
|
16
|
-
Spec::Rake::SpecTask.new('rcov') do |t|
|
17
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
18
|
-
t.rcov = true
|
19
|
-
t.rcov_opts = ['--exclude', 'examples']
|
20
|
-
end
|
21
|
-
|
22
|
-
task :default => :spec
|
23
|
-
|
24
|
-
######################################################
|
25
|
-
|
26
|
-
require 'rake'
|
27
|
-
require 'rake/testtask'
|
2
|
+
require 'rubygems'
|
28
3
|
require 'rake/clean'
|
29
4
|
require 'rake/gempackagetask'
|
30
5
|
require 'rake/rdoctask'
|
31
6
|
require 'fileutils'
|
32
7
|
include FileUtils
|
8
|
+
|
9
|
+
task :default => :test
|
10
|
+
|
11
|
+
# SPECS ===============================================================
|
12
|
+
|
13
|
+
desc 'Run specs with unit test style output'
|
14
|
+
task :test do |t|
|
15
|
+
# sh "specrb -s tests/*_test.rb"
|
16
|
+
sh "specrb -s tests/*_test.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
# PACKAGE =============================================================
|
20
|
+
|
33
21
|
|
34
22
|
STELLA_HOME = File.expand_path(File.join(File.dirname(__FILE__)))
|
35
23
|
$: << File.join(STELLA_HOME, 'lib')
|
36
24
|
|
37
25
|
require 'stella'
|
38
26
|
version = Stella::VERSION.to_s
|
39
|
-
|
40
27
|
name = "stella"
|
41
28
|
|
42
29
|
spec = Gem::Specification.new do |s|
|
@@ -52,15 +39,14 @@ spec = Gem::Specification.new do |s|
|
|
52
39
|
s.extra_rdoc_files = ['README.textile']
|
53
40
|
|
54
41
|
# NOTE: how to make optional dependencies?
|
55
|
-
|
42
|
+
s.add_dependency 'mongrel'
|
56
43
|
s.add_dependency 'rspec'
|
57
44
|
s.add_dependency 'net-dns'
|
58
|
-
#s.add_dependency 'session'
|
59
45
|
|
60
46
|
s.platform = Gem::Platform::RUBY
|
61
47
|
s.has_rdoc = true
|
62
48
|
|
63
|
-
s.files = %w(Rakefile) + Dir.glob("{bin,doc,lib,
|
49
|
+
s.files = %w(Rakefile) + Dir.glob("{bin,doc,lib,tests,support,vendor}/**/**/*")
|
64
50
|
|
65
51
|
s.require_path = "lib"
|
66
52
|
s.bindir = "bin"
|
@@ -71,6 +57,7 @@ Rake::GemPackageTask.new(spec) do |p|
|
|
71
57
|
end
|
72
58
|
|
73
59
|
|
60
|
+
|
74
61
|
task :install => [ :rdoc, :package ] do
|
75
62
|
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
76
63
|
end
|
@@ -79,11 +66,7 @@ task :uninstall => [ :clean ] do
|
|
79
66
|
sh %{sudo gem uninstall #{name}}
|
80
67
|
end
|
81
68
|
|
82
|
-
|
83
|
-
t.libs << "spec"
|
84
|
-
t.test_files = FileList['spec/*_spec.rb']
|
85
|
-
t.verbose = true
|
86
|
-
end
|
69
|
+
|
87
70
|
|
88
71
|
Rake::RDocTask.new do |t|
|
89
72
|
t.rdoc_dir = 'doc'
|
@@ -91,7 +74,8 @@ Rake::RDocTask.new do |t|
|
|
91
74
|
t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
|
92
75
|
t.options << '--charset' << 'utf-8'
|
93
76
|
t.rdoc_files.include('LICENSE.txt')
|
94
|
-
t.rdoc_files.include('README.
|
77
|
+
t.rdoc_files.include('README.textile')
|
78
|
+
t.rdoc_files.include('CHANGES.txt')
|
95
79
|
t.rdoc_files.include('lib/utils/*.rb')
|
96
80
|
t.rdoc_files.include('lib/stella.rb')
|
97
81
|
t.rdoc_files.include('lib/stella/*.rb')
|
@@ -100,3 +84,5 @@ end
|
|
100
84
|
|
101
85
|
CLEAN.include [ 'pkg', '*.gem', '.config', 'doc' ]
|
102
86
|
|
87
|
+
|
88
|
+
|
data/lib/daemonize.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
module Daemonize
|
2
|
+
VERSION = "0.1.2"
|
3
|
+
|
4
|
+
# Try to fork if at all possible retrying every 5 sec if the
|
5
|
+
# maximum process limit for the system has been reached
|
6
|
+
def safefork
|
7
|
+
tryagain = true
|
8
|
+
|
9
|
+
while tryagain
|
10
|
+
tryagain = false
|
11
|
+
begin
|
12
|
+
if pid = fork
|
13
|
+
return pid
|
14
|
+
end
|
15
|
+
rescue Errno::EWOULDBLOCK
|
16
|
+
sleep 5
|
17
|
+
tryagain = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# This method causes the current running process to become a daemon
|
23
|
+
# If closefd is true, all existing file descriptors are closed
|
24
|
+
def daemonize(oldmode=0, closefd=false)
|
25
|
+
srand # Split rand streams between spawning and daemonized process
|
26
|
+
safefork and exit # Fork and exit from the parent
|
27
|
+
|
28
|
+
# Detach from the controlling terminal
|
29
|
+
unless sess_id = Process.setsid
|
30
|
+
raise 'Cannot detach from controlled terminal'
|
31
|
+
end
|
32
|
+
|
33
|
+
# Prevent the possibility of acquiring a controlling terminal
|
34
|
+
if oldmode.zero?
|
35
|
+
trap 'SIGHUP', 'IGNORE'
|
36
|
+
exit if pid = safefork
|
37
|
+
end
|
38
|
+
|
39
|
+
Dir.chdir "/" # Release old working directory
|
40
|
+
File.umask 0000 # Insure sensible umask
|
41
|
+
|
42
|
+
if closefd
|
43
|
+
# Make sure all file descriptors are closed
|
44
|
+
ObjectSpace.each_object(IO) do |io|
|
45
|
+
unless [STDIN, STDOUT, STDERR].include?(io)
|
46
|
+
io.close rescue nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
STDIN.reopen "/dev/null" # Free file descriptors and
|
52
|
+
STDOUT.reopen "/dev/null", "a" # point them somewhere sensible
|
53
|
+
STDERR.reopen STDOUT # STDOUT/STDERR should go to a logfile
|
54
|
+
return oldmode ? sess_id : 0 # Return value is mostly irrelevant
|
55
|
+
end
|
56
|
+
end
|
data/lib/stella/adapter/ab.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
require 'fileutils'
|
3
3
|
|
4
4
|
module Stella
|
5
5
|
module Adapter
|
@@ -45,12 +45,14 @@ module Stella
|
|
45
45
|
attr_accessor :C, :H, :A, :P, :X, :V, :k, :d, :S, :e, :g, :r, :h, :Z, :f
|
46
46
|
|
47
47
|
def initialize(options={}, arguments=[])
|
48
|
-
super(options, arguments)
|
49
48
|
@private_variables = ['private_variables', 'name', 'arguments', 'load_factor', 'working_directory']
|
50
49
|
@c = 1
|
51
50
|
@n = 1
|
52
51
|
@name = 'ab'
|
53
52
|
@load_factor = 1
|
53
|
+
|
54
|
+
super(options, arguments)
|
55
|
+
|
54
56
|
end
|
55
57
|
|
56
58
|
def error
|
@@ -65,14 +67,17 @@ module Stella
|
|
65
67
|
vsn
|
66
68
|
end
|
67
69
|
|
70
|
+
def percentiles_file
|
71
|
+
@working_directory + "/ab-percentiles.log"
|
72
|
+
end
|
73
|
+
|
74
|
+
def requests_file
|
75
|
+
@working_directory + "/ab-requests.log"
|
76
|
+
end
|
77
|
+
|
68
78
|
def before
|
69
|
-
|
70
|
-
@
|
71
|
-
@e = File.expand_path(@e)
|
72
|
-
|
73
|
-
@g = @working_directory + "/ab-requests.log"
|
74
|
-
@g = File.expand_path(@g)
|
75
|
-
|
79
|
+
@e = percentiles_file if @e.nil?
|
80
|
+
@g = requests_file if @g.nil?
|
76
81
|
end
|
77
82
|
|
78
83
|
def command
|
@@ -83,12 +88,12 @@ module Stella
|
|
83
88
|
instance_variables.each do |name|
|
84
89
|
canon = name.to_s.tr('@', '') # instance_variables returns '@name'
|
85
90
|
next if @private_variables.member?(canon)
|
86
|
-
|
91
|
+
|
87
92
|
# It's important that we take the value from the getter method
|
88
93
|
# because it applies the load factor.
|
89
94
|
value = self.send(canon)
|
90
95
|
if (value.is_a? Array)
|
91
|
-
value.each { |el| command << "-#{canon} #{EscapeUtil.shell_single_word(
|
96
|
+
value.each { |el| command << "-#{canon} #{EscapeUtil.shell_single_word(value.to_s)} " }
|
92
97
|
else
|
93
98
|
command << "-#{canon} #{EscapeUtil.shell_single_word(value.to_s)} "
|
94
99
|
end
|
@@ -96,6 +101,7 @@ module Stella
|
|
96
101
|
end
|
97
102
|
|
98
103
|
command << (@arguments.map { |uri| "#{uri}" }).join(' ') unless @arguments.empty?
|
104
|
+
|
99
105
|
command
|
100
106
|
end
|
101
107
|
# loadtest
|
@@ -111,32 +117,34 @@ module Stella
|
|
111
117
|
end
|
112
118
|
|
113
119
|
|
114
|
-
def
|
115
|
-
options = OpenStruct.new
|
120
|
+
def process_arguments(arguments)
|
116
121
|
opts = OptionParser.new
|
117
122
|
|
123
|
+
# TODO: there's no need to use an OpenStruct here. It's confusing b/c we can
|
124
|
+
# use the instance var methods here instead of in Base::options=.
|
125
|
+
|
118
126
|
# TODO: Print a note for w that we don't parse the HTML results
|
119
127
|
%w{v w i V k d S r h}.each do |n|
|
120
|
-
opts.on("-#{n}") do |v|
|
128
|
+
opts.on("-#{n}") do |v| instance_variable_set("@#{n}", true) end
|
121
129
|
end
|
122
130
|
|
123
131
|
%w{e g p T x y z P Z f A}.each do |n|
|
124
|
-
opts.on("-#{n} S", String) do |v|
|
132
|
+
opts.on("-#{n} S", String) do |v| instance_variable_set("@#{n}", v) end
|
125
133
|
end
|
126
134
|
|
127
135
|
%w{c n t b}.each do |n|
|
128
|
-
opts.on("-#{n} S", Integer) do |v|
|
136
|
+
opts.on("-#{n} S", Integer) do |v| instance_variable_set("@#{n}", v) end
|
129
137
|
end
|
130
138
|
|
131
|
-
opts.on('-H S', String) do |v|
|
132
|
-
opts.on('-C S', String) do |v|
|
139
|
+
opts.on('-H S', String) do |v| @H ||= []; @H << v; end
|
140
|
+
opts.on('-C S', String) do |v| @C ||= []; @C << v; end
|
133
141
|
|
134
142
|
opts.on('-b') do |v|
|
135
|
-
Stella
|
143
|
+
Stella.warn("-b is not an ab option. I'll pretend it's not there.")
|
136
144
|
end
|
137
145
|
|
138
146
|
opts.on('-r N',Integer) do |v|
|
139
|
-
Stella
|
147
|
+
Stella.error("-r is not an ab parameter. You probably want -n.")
|
140
148
|
exit 1
|
141
149
|
end
|
142
150
|
|
@@ -145,10 +153,10 @@ module Stella
|
|
145
153
|
opts.parse!(arguments)
|
146
154
|
|
147
155
|
if arguments.empty?
|
148
|
-
Stella
|
156
|
+
Stella.error("You need to provide a URI")
|
149
157
|
exit 1
|
150
158
|
elsif arguments.size > 1
|
151
|
-
Stella
|
159
|
+
Stella.warn("ab can handle only one URI. The others will be ignored.")
|
152
160
|
arguments = arguments.first
|
153
161
|
else
|
154
162
|
# Let's make sure the URI has a path (at least a trailing slash). Otherwise
|
@@ -156,17 +164,17 @@ module Stella
|
|
156
164
|
begin
|
157
165
|
uri = URI.parse(arguments.first)
|
158
166
|
if !uri || uri.path.empty?
|
159
|
-
Stella
|
167
|
+
Stella.error("ab requires a trailing slash for #{uri.to_s}")
|
160
168
|
exit 1
|
161
169
|
end
|
162
170
|
rescue => ex
|
163
|
-
Stella
|
171
|
+
Stella.error("Bad URI: #{arguments.first}")
|
164
172
|
exit 1
|
165
173
|
end
|
166
174
|
end
|
167
175
|
|
176
|
+
self.arguments = arguments
|
168
177
|
|
169
|
-
options
|
170
178
|
rescue OptionParser::InvalidOption => ex
|
171
179
|
# We want to replace this text so we grab just the name of the argument
|
172
180
|
badarg = ex.message.gsub('invalid option: ', '')
|
@@ -176,17 +184,19 @@ module Stella
|
|
176
184
|
def after
|
177
185
|
# We want to maintain copies of all test output, even when the user has
|
178
186
|
# supplied other path names so we'll copy the files from the testrun directory
|
179
|
-
# to the location specified by the user
|
180
|
-
|
181
|
-
|
187
|
+
# to the location specified by the user.
|
188
|
+
# NOTE: For tests with more than one test run, the specified files will be
|
189
|
+
# overwritten after each run. Should we force append the run number?
|
190
|
+
[[@e, 'percentiles'], [@g, 'requests']].each do |tuple|
|
191
|
+
if File.expand_path(File.dirname(tuple[0])) != File.expand_path(@working_directory)
|
182
192
|
from = tuple[0]
|
183
|
-
to = @
|
193
|
+
to = @working_directory + "/ab-#{tuple[1]}.log"
|
184
194
|
next unless File.exists?(from)
|
185
|
-
|
195
|
+
FileUtils.cp(from, to)
|
186
196
|
end
|
187
197
|
end
|
188
198
|
|
189
|
-
|
199
|
+
|
190
200
|
end
|
191
201
|
|
192
202
|
|
@@ -257,14 +267,14 @@ module Stella
|
|
257
267
|
|
258
268
|
|
259
269
|
# Apache bench writes the summary to STDOUT
|
260
|
-
def
|
270
|
+
def summary_file
|
261
271
|
File.new(stdout_path) if File.exists?(stdout_path)
|
262
272
|
end
|
263
273
|
|
264
|
-
def
|
265
|
-
return unless
|
274
|
+
def summary
|
275
|
+
return unless summary_file
|
266
276
|
raw = {}
|
267
|
-
|
277
|
+
summary_file.each_line { |l|
|
268
278
|
l.chomp!
|
269
279
|
nvpair = l.split(':')
|
270
280
|
next unless nvpair && nvpair.size == 2
|
@@ -292,8 +302,8 @@ module Stella
|
|
292
302
|
# Transfer rate: 84.90 [Kbytes/sec] received
|
293
303
|
|
294
304
|
stats = Stella::Test::Run::Summary.new
|
295
|
-
|
296
|
-
|
305
|
+
|
306
|
+
if !raw.empty? && raw.has_key?(:time_taken_for_tests)
|
297
307
|
|
298
308
|
stats.elapsed_time = raw[:time_taken_for_tests]
|
299
309
|
|
@@ -312,10 +322,10 @@ module Stella
|
|
312
322
|
stats.failed = raw[:failed_requests].to_i
|
313
323
|
|
314
324
|
stats.transactions = stats.successful + stats.failed
|
315
|
-
|
325
|
+
|
316
326
|
#stats.raw = raw if @global_options.debug
|
317
327
|
end
|
318
|
-
|
328
|
+
|
319
329
|
stats
|
320
330
|
end
|
321
331
|
|
data/lib/stella/adapter/base.rb
CHANGED
@@ -10,12 +10,16 @@ module Stella::Adapter
|
|
10
10
|
class Base
|
11
11
|
|
12
12
|
|
13
|
-
attr_accessor :working_directory
|
13
|
+
attr_accessor :working_directory
|
14
14
|
attr_reader :load_factor, :arguments
|
15
15
|
|
16
16
|
def initialize(options={}, arguments=[])
|
17
|
-
|
18
|
-
|
17
|
+
if options.is_a? Array
|
18
|
+
self.process_arguments(options)
|
19
|
+
else
|
20
|
+
self.options = options
|
21
|
+
self.arguments = arguments
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
def load_factor=(load_factor)
|
@@ -33,22 +37,23 @@ module Stella::Adapter
|
|
33
37
|
File.join(@working_directory, "SUMMARY.#{ext}")
|
34
38
|
end
|
35
39
|
|
36
|
-
#
|
40
|
+
# process_arguments
|
37
41
|
#
|
38
42
|
# This method must be overridden by the implementing class. This is intended
|
39
43
|
# for processing the command-specific command-line arguments
|
40
|
-
|
41
|
-
def process_options
|
44
|
+
def process_arguments
|
42
45
|
raise Stella::TEXT.msg(:error_class_must_override, 'process_options')
|
43
46
|
end
|
44
47
|
|
45
48
|
# options=
|
46
49
|
#
|
47
|
-
# Takes a hash
|
50
|
+
# Takes a hash, OpenStruct and applies the values to the instance variables.
|
48
51
|
# The keys should conincide with with the command line argument names.
|
52
|
+
# by process_options first and
|
49
53
|
# i.e. The key for --help should be :help
|
50
54
|
def options=(options={})
|
51
55
|
options = options.marshal_dump if options.is_a? OpenStruct
|
56
|
+
|
52
57
|
unless options.nil? || options.empty?
|
53
58
|
options.each_pair do |name,value|
|
54
59
|
next if @private_variables.member?(name)
|
@@ -71,7 +76,7 @@ module Stella::Adapter
|
|
71
76
|
end
|
72
77
|
|
73
78
|
def rate
|
74
|
-
|
79
|
+
@rate || 0
|
75
80
|
end
|
76
81
|
def vuser_rate
|
77
82
|
"#{vusers}/#{rate}"
|
@@ -81,6 +86,10 @@ module Stella::Adapter
|
|
81
86
|
raise Stella::TEXT.msg(:error_class_must_override, 'command')
|
82
87
|
end
|
83
88
|
|
89
|
+
def summary
|
90
|
+
raise Stella::TEXT.msg(:error_class_must_override, 'summary')
|
91
|
+
end
|
92
|
+
|
84
93
|
def add_header
|
85
94
|
raise Stella::TEXT.msg(:error_class_must_override, 'add_header')
|
86
95
|
end
|
@@ -29,11 +29,12 @@ module Stella
|
|
29
29
|
attr_writer :version, :add_header, :wlog, :wsess, :wsesslog, :wset
|
30
30
|
|
31
31
|
def initialize(options={}, arguments=[])
|
32
|
-
super(options, arguments)
|
33
|
-
@name = 'httperf'
|
34
32
|
|
33
|
+
@name = 'httperf'
|
35
34
|
@private_variables = ['private_variables', 'name', 'arguments', 'load_factor', 'working_directory']
|
36
35
|
@load_factor = 1
|
36
|
+
|
37
|
+
super(options, arguments)
|
37
38
|
end
|
38
39
|
|
39
40
|
|
@@ -75,13 +76,10 @@ module Stella
|
|
75
76
|
def after
|
76
77
|
|
77
78
|
|
78
|
-
save_stats
|
79
79
|
end
|
80
80
|
|
81
|
-
|
82
|
-
def process_options(arguments)
|
81
|
+
def process_arguments(arguments)
|
83
82
|
|
84
|
-
options = OpenStruct.new
|
85
83
|
opts = OptionParser.new
|
86
84
|
opts.on('--hog') do @hog = true end
|
87
85
|
opts.on('--server=S', String) do |v| @server = v end
|
@@ -126,17 +124,21 @@ module Stella
|
|
126
124
|
|
127
125
|
|
128
126
|
opts.on('--wlog=S', String) do |v| @wlog = Stella::Util::expand_str(v) end
|
129
|
-
opts.on('--wsess=S', String) do |v| @wsess = Stella::Util::expand_str(v) end
|
127
|
+
opts.on('--wsess=S', String) do |v| @wsess = Stella::Util::expand_str(v, Integer) end
|
130
128
|
opts.on('--wsesslog=S', String) do |v| @wsesslog = Stella::Util::expand_str(v) end
|
131
129
|
opts.on('--wset=S', String) do |v| @wset = Stella::Util::expand_str(v) end
|
130
|
+
|
131
|
+
if @wsess
|
132
132
|
|
133
|
+
end
|
134
|
+
|
133
135
|
# parse! removes the options it finds.
|
134
136
|
# It also fails when it finds unknown switches (i.e. -X)
|
135
137
|
# Which should leave only the remaining arguments (URIs in this case)
|
136
138
|
opts.parse!(arguments)
|
137
|
-
|
138
139
|
|
139
|
-
|
140
|
+
self.arguments = arguments
|
141
|
+
|
140
142
|
rescue OptionParser::InvalidOption => ex
|
141
143
|
# We want to replace this text so we grab just the name of the argument
|
142
144
|
badarg = ex.message.gsub('invalid option: ', '')
|
@@ -181,13 +183,17 @@ module Stella
|
|
181
183
|
end
|
182
184
|
end
|
183
185
|
def vusers
|
184
|
-
@
|
186
|
+
@wsess[1]
|
185
187
|
end
|
188
|
+
def vuser_rate
|
189
|
+
"#{vusers}/#{rate}"
|
190
|
+
end
|
191
|
+
|
186
192
|
def vusers=(v)
|
187
193
|
0
|
188
194
|
end
|
189
195
|
def requests
|
190
|
-
@num_conns
|
196
|
+
@num_conns || (@wsess[0] * @wsess[1])
|
191
197
|
end
|
192
198
|
def requests=(v)
|
193
199
|
0
|
@@ -224,7 +230,7 @@ module Stella
|
|
224
230
|
|
225
231
|
|
226
232
|
# Siege writes the summary to STDERR
|
227
|
-
def
|
233
|
+
def summary_file
|
228
234
|
File.new(stdout_path) if File.exists?(stdout_path)
|
229
235
|
end
|
230
236
|
|
@@ -265,10 +271,10 @@ module Stella
|
|
265
271
|
# Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
|
266
272
|
# Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
|
267
273
|
|
268
|
-
def
|
269
|
-
return unless
|
274
|
+
def summary
|
275
|
+
return unless summary_file
|
270
276
|
|
271
|
-
raw =
|
277
|
+
raw = summary_file.readlines.join
|
272
278
|
stats = Stella::Test::Run::Summary.new
|
273
279
|
|
274
280
|
raw.scan(/Request rate: (\d+?\.\d+?) req.s .(\d+?\.\d+?) ms.req./) do |rate,time|
|
@@ -283,12 +289,12 @@ module Stella
|
|
283
289
|
stats.transactions = conn.to_i
|
284
290
|
end
|
285
291
|
|
286
|
-
raw.scan(/
|
287
|
-
stats.data_transferred = ((t.to_f || 0 ) / 1_048_576).to_f
|
292
|
+
raw.scan(/header (\d+\.\d+?)\s+.+?\s+.total (\d+\.\d+?)./) do |h,t|
|
293
|
+
stats.data_transferred = ((t.to_f || 0 ) / 1_048_576).to_f
|
294
|
+
stats.headers_transferred = ((h.to_f || 0 ) / 1_048_576).to_f
|
288
295
|
end
|
289
296
|
stats.vusers = self.vusers
|
290
297
|
|
291
|
-
|
292
298
|
stats
|
293
299
|
end
|
294
300
|
|
@@ -61,7 +61,7 @@ module Stella
|
|
61
61
|
@sport = options[:port] || @dport
|
62
62
|
|
63
63
|
@device = options[:device] || guess_device
|
64
|
-
@snaplen = options[:snaplen] ||
|
64
|
+
@snaplen = options[:snaplen] || 10000 # 10KB
|
65
65
|
@maxpacks = options[:maxpacks] || 100_000
|
66
66
|
|
67
67
|
Stella::LOGGER.info("Watching interface #{@device} for #{@service} activity on #{@protocol} port #{@dport}")
|