stella 0.3.2

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.
Files changed (56) hide show
  1. data/README.txt +135 -0
  2. data/Rakefile +100 -0
  3. data/bin/stella +12 -0
  4. data/lib/stella.rb +58 -0
  5. data/lib/stella/adapter/ab.rb +303 -0
  6. data/lib/stella/adapter/base.rb +87 -0
  7. data/lib/stella/adapter/httperf.rb +296 -0
  8. data/lib/stella/adapter/siege.rb +321 -0
  9. data/lib/stella/cli.rb +291 -0
  10. data/lib/stella/cli/agents.rb +73 -0
  11. data/lib/stella/cli/base.rb +19 -0
  12. data/lib/stella/cli/language.rb +18 -0
  13. data/lib/stella/cli/localtest.rb +80 -0
  14. data/lib/stella/command/base.rb +111 -0
  15. data/lib/stella/command/localtest.rb +339 -0
  16. data/lib/stella/logger.rb +63 -0
  17. data/lib/stella/response.rb +82 -0
  18. data/lib/stella/storable.rb +116 -0
  19. data/lib/stella/support.rb +106 -0
  20. data/lib/stella/test/base.rb +34 -0
  21. data/lib/stella/test/definition.rb +79 -0
  22. data/lib/stella/test/run/summary.rb +50 -0
  23. data/lib/stella/test/summary.rb +82 -0
  24. data/lib/stella/text.rb +64 -0
  25. data/lib/stella/text/resource.rb +39 -0
  26. data/lib/utils/crypto-key.rb +84 -0
  27. data/lib/utils/escape.rb +302 -0
  28. data/lib/utils/fileutil.rb +59 -0
  29. data/lib/utils/httputil.rb +210 -0
  30. data/lib/utils/mathutil.rb +78 -0
  31. data/lib/utils/textgraph.rb +267 -0
  32. data/lib/utils/timerutil.rb +58 -0
  33. data/support/text/en.yaml +54 -0
  34. data/support/text/nl.yaml +1 -0
  35. data/support/useragents.txt +75 -0
  36. data/vendor/useragent/MIT-LICENSE +20 -0
  37. data/vendor/useragent/README +21 -0
  38. data/vendor/useragent/init.rb +1 -0
  39. data/vendor/useragent/lib/user_agent.rb +83 -0
  40. data/vendor/useragent/lib/user_agent/browsers.rb +24 -0
  41. data/vendor/useragent/lib/user_agent/browsers/all.rb +69 -0
  42. data/vendor/useragent/lib/user_agent/browsers/gecko.rb +43 -0
  43. data/vendor/useragent/lib/user_agent/browsers/internet_explorer.rb +40 -0
  44. data/vendor/useragent/lib/user_agent/browsers/opera.rb +49 -0
  45. data/vendor/useragent/lib/user_agent/browsers/webkit.rb +94 -0
  46. data/vendor/useragent/lib/user_agent/comparable.rb +25 -0
  47. data/vendor/useragent/lib/user_agent/operating_systems.rb +19 -0
  48. data/vendor/useragent/spec/browsers/gecko_user_agent_spec.rb +209 -0
  49. data/vendor/useragent/spec/browsers/internet_explorer_user_agent_spec.rb +99 -0
  50. data/vendor/useragent/spec/browsers/opera_user_agent_spec.rb +59 -0
  51. data/vendor/useragent/spec/browsers/other_user_agent_spec.rb +19 -0
  52. data/vendor/useragent/spec/browsers/webkit_user_agent_spec.rb +373 -0
  53. data/vendor/useragent/spec/spec_helper.rb +1 -0
  54. data/vendor/useragent/spec/user_agent_spec.rb +331 -0
  55. data/vendor/useragent/useragent.gemspec +12 -0
  56. metadata +139 -0
data/README.txt ADDED
@@ -0,0 +1,135 @@
1
+ Stella - Your Performance Testing Friend
2
+
3
+ Release: 0.3.2-preview (2008-12-23)
4
+
5
+ This is a PREVIEW release. Don't trust and double verify!
6
+
7
+
8
+ == Prerequisites
9
+
10
+ * Linux, *BSD, Solaris
11
+ * Ruby 1.8.x or 1.9.x
12
+ * Ruby Libraries
13
+ * fastthread
14
+ * mongrel
15
+ * rspec
16
+ * rdoc
17
+
18
+ * One of:
19
+ * Apache Bench
20
+ * Siege
21
+ * Httperf
22
+
23
+
24
+ == Installation
25
+
26
+ Get it in one of the following ways:
27
+ * RubyForge: http://stella.rubyforge.org/
28
+ * gem install stella
29
+
30
+ Use ab, siege, and httperf like you normally would with the addition of stella at the beginning (examples are below).
31
+
32
+ === Debian (and derivatives)
33
+
34
+ Debian and its derivative (Ubunutu) handling packing a bit differently (see: http://pkg-ruby-extras.alioth.debian.org/rubygems.html). There are a couple errors to watch out for during the installation. The solutions are below:
35
+
36
+ "no such file to load -- mkmf (LoadError)"
37
+
38
+ apt-get install ruby1.8-dev
39
+
40
+ "ERROR: RDoc documentation generator not installed!"
41
+
42
+ apt-get install rdoc
43
+
44
+
45
+ == Examples
46
+
47
+ Run Apache Bench with a warmup and rampup from 100 to 300 virtual users in increments of 25
48
+
49
+ stella --warmup=0.5 --rampup=25,300 ab -c 100 -n 10000 http://stellaaahhhh.com/search?term=trooper
50
+
51
+
52
+ Run Siege, repeat the test 5 times. Automatically creates a summary averages and standard deviations.
53
+
54
+ stella --agent=ff-3-osx --testruns=5 siege -c 100 -r 100 -b http://stellaaahhhh.com/search?term=flock+of+seagulls
55
+
56
+
57
+ Run Httperf like you normally would (but all the test data will be collected for you)
58
+
59
+ stella httperf --hog --client=0/1 --server=127.0.0.1 --port=5600 --uri=/ --rate=50 --num-conns=3000 --timeout=5
60
+
61
+
62
+ == Sample Output
63
+
64
+ $ stella -f csv -x 5 -w 0.75 -r 25,125 -m "httpd 2.2.9-prefork" siege -c 75 -r 10 -b http://stella:5600/
65
+ Writing test data to: stella/testruns/2008-12-23/test-054
66
+
67
+ Warmup: 3750@37/1 100% 264.29/s 0.140s 0.024MB/s 0.340MB 14.000s .
68
+
69
+ -------------------------------------------------------------------
70
+ REQ@VU/s AVAIL REQ/s RTIME DATA/s DATA TIME
71
+
72
+ Run 01: 7500@75/1 100% 345.30/s 0.210s 0.032MB/s 0.690MB 21.720s
73
+ Run 02: 7500@75/1 100% 360.58/s 0.200s 0.033MB/s 0.690MB 20.800s
74
+ Run 03: 7500@75/1 100% 359.02/s 0.210s 0.033MB/s 0.690MB 20.890s
75
+ -------------------------------------------------------------------
76
+ Total: 22500@73 100% 354.97/s 0.207s 0.033MB/s 2.070MB 63.410s
77
+ Std Dev: 6.86/s 0.005s 0.001MB/s 0.414s
78
+
79
+ Run 04: 10000@100/1 100% 384.47/s 0.260s 0.035MB/s 0.920MB 26.010s
80
+ Run 05: 10000@100/1 100% 385.06/s 0.260s 0.035MB/s 0.920MB 25.970s
81
+ Run 06: 10000@100/1 100% 380.95/s 0.260s 0.035MB/s 0.920MB 26.250s
82
+ -------------------------------------------------------------------
83
+ Total: 30000@98 100% 383.49/s 0.260s 0.035MB/s 2.760MB 78.230s
84
+ Std Dev: 1.81/s 0.000s 0.000MB/s 0.124s
85
+
86
+ Run 07: 12500@125/1 100% 397.20/s 0.310s 0.036MB/s 1.140MB 31.470s
87
+ Run 08: 12500@125/1 100% 397.08/s 0.310s 0.036MB/s 1.140MB 31.480s
88
+ Run 09: 12500@125/1 100% 397.58/s 0.310s 0.036MB/s 1.140MB 31.440s
89
+ -------------------------------------------------------------------
90
+ Total: 37500@123 100% 397.29/s 0.310s 0.036MB/s 3.420MB 94.390s
91
+ Std Dev: 0.21/s 0.000s 0.000MB/s 0.017s
92
+
93
+ -------------------------------------------------------------------
94
+ Total: 90000@98 100% 378.58/s 0.259s 0.035MB/s 8.250MB 236.030s
95
+ Std Dev: 18.09/s 0.042s 0.002MB/s 4.225s
96
+
97
+
98
+ All test data is collected under ./stella (this can be changed with the parameter --datapath):
99
+
100
+ $ ls -l ./stella/testruns/2008-12-23/
101
+ test-001 test-002 test-003 test-004 test-005 test-006 ... test-054
102
+
103
+
104
+ A symbolic link points to the most recent test:
105
+
106
+ $ ls -l ./stella/latest/
107
+ ID.txt MESSAGE.txt SUMMARY.csv run01 run02 run03 run04 run05 warmup
108
+
109
+
110
+ Each run directory contains all associated data, including the command and configuration
111
+
112
+ $ ls -l ./stella/latest/run01/
113
+ COMMAND.txt STDOUT.txt siege.log STDERR.txt SUMMARY.csv siegerc
114
+
115
+
116
+ == Known Issues
117
+
118
+ * 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.
119
+ * The summary data has not been audited. Don't trust and double verify!
120
+ * httperf is functional but needs a lot more testing (most dev was done with ab and siege).
121
+ * The Ruby API has not been finalized. It's functional but there's no example because it is subject to change.
122
+ * There are no specs.
123
+
124
+ == Report an issue
125
+
126
+ Email issues and bugs to stella@solutious.com
127
+
128
+
129
+ == Even More Information
130
+
131
+ http://www.youtube.com/watch?v=wmq-JDonTpc
132
+
133
+ == License
134
+
135
+ See LICENSE.txt
data/Rakefile ADDED
@@ -0,0 +1,100 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ desc "Run all specs"
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'
28
+ require 'rake/clean'
29
+ require 'rake/gempackagetask'
30
+ require 'rake/rdoctask'
31
+ require 'fileutils'
32
+ include FileUtils
33
+
34
+ STELLA_HOME = File.expand_path(File.join(File.dirname(__FILE__)))
35
+ $: << File.join(STELLA_HOME, 'lib')
36
+
37
+ require 'stella'
38
+ version = Stella::VERSION.to_s
39
+
40
+ name = "stella"
41
+
42
+ spec = Gem::Specification.new do |s|
43
+ s.name = name
44
+ s.version = version
45
+ s.summary = "A friend in performance testing."
46
+ s.description = "Run Apache Bench, Siege, or httperf tests in batches and aggregate results."
47
+ s.author = "Delano Mandelbaum"
48
+ s.email = "delano@solutious.com"
49
+ s.homepage = "http://stella.solutious.com/"
50
+ s.executables = [ "stella" ]
51
+ s.rubyforge_project = "stella"
52
+ s.extra_rdoc_files = ['README.txt']
53
+
54
+ s.add_dependency 'mongrel'
55
+ s.add_dependency 'rspec'
56
+ #s.add_dependency 'session'
57
+
58
+ s.platform = Gem::Platform::RUBY
59
+ s.has_rdoc = true
60
+
61
+ s.files = %w(Rakefile) + Dir.glob("{bin,doc,lib,spec,support,vendor}/**/**/*")
62
+
63
+ s.require_path = "lib"
64
+ s.bindir = "bin"
65
+ end
66
+
67
+ Rake::GemPackageTask.new(spec) do |p|
68
+ p.need_tar = true if RUBY_PLATFORM !~ /mswin/
69
+ end
70
+
71
+
72
+ task :install => [ :rdoc, :package ] do
73
+ sh %{sudo gem install pkg/#{name}-#{version}.gem}
74
+ end
75
+
76
+ task :uninstall => [ :clean ] do
77
+ sh %{sudo gem uninstall #{name}}
78
+ end
79
+
80
+ Rake::TestTask.new do |t|
81
+ t.libs << "spec"
82
+ t.test_files = FileList['spec/*_spec.rb']
83
+ t.verbose = true
84
+ end
85
+
86
+ Rake::RDocTask.new do |t|
87
+ t.rdoc_dir = 'doc'
88
+ t.title = "stella, a friend in performance testing"
89
+ t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
90
+ t.options << '--charset' << 'utf-8'
91
+ t.rdoc_files.include('LICENSE.txt')
92
+ t.rdoc_files.include('README.txt')
93
+ t.rdoc_files.include('lib/utils/*.rb')
94
+ t.rdoc_files.include('lib/stella.rb')
95
+ t.rdoc_files.include('lib/stella/*.rb')
96
+ t.rdoc_files.include('lib/stella/**/*.rb')
97
+ end
98
+
99
+ CLEAN.include [ 'pkg', '*.gem', '.config', 'doc' ]
100
+
data/bin/stella ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ STELLA_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..'))
4
+ $: << File.join(STELLA_HOME, 'lib')
5
+
6
+ require 'stella'
7
+ require 'stella/cli'
8
+
9
+ ## Create and run the application
10
+ app = Stella::CLI.new(ARGV, STDIN)
11
+ app.run
12
+
data/lib/stella.rb ADDED
@@ -0,0 +1,58 @@
1
+
2
+ $: << File.join(STELLA_HOME, 'vendor', 'useragent', 'lib')
3
+
4
+
5
+ require 'date'
6
+ require 'open3'
7
+
8
+ # Common utilities
9
+ require 'utils/httputil'
10
+ require 'utils/crypto-key'
11
+ require 'utils/fileutil'
12
+ require 'utils/mathutil'
13
+ require 'utils/escape'
14
+
15
+ # Common dependencies
16
+ require 'stella/support'
17
+ require 'stella/storable'
18
+ require 'user_agent'
19
+
20
+ # Common objects
21
+ require 'stella/text'
22
+ require 'stella/logger'
23
+ require 'stella/response'
24
+ require 'stella/test/definition'
25
+ require 'stella/test/run/summary'
26
+ require 'stella/test/summary'
27
+
28
+ # Commands
29
+ require 'stella/command/base'
30
+ require 'stella/command/localtest'
31
+
32
+ # Adapters
33
+ require 'stella/adapter/base'
34
+ require 'stella/adapter/ab'
35
+ require 'stella/adapter/siege'
36
+ require 'stella/adapter/httperf'
37
+
38
+ # = Stella
39
+ # A friend in performance testing.
40
+ #
41
+ module Stella
42
+ LOGGER = Stella::Logger.new(:debug=>false)
43
+ TEXT = Stella::Text.new('en')
44
+
45
+ module VERSION #:nodoc:
46
+ MAJOR = 0.freeze unless defined? MAJOR
47
+ MINOR = 3.freeze unless defined? MINOR
48
+ TINY = 2.freeze unless defined? TINY
49
+ def self.to_s
50
+ [MAJOR, MINOR, TINY].join('.')
51
+ end
52
+ def self.to_f
53
+ self.to_s.to_f
54
+ end
55
+ end
56
+
57
+ end
58
+
@@ -0,0 +1,303 @@
1
+
2
+
3
+
4
+ module Stella
5
+ module Adapter
6
+
7
+ #Usage: ab [options] [http[s]://]hostname[:port]/path
8
+ #Options are:
9
+ # -n requests Number of requests to perform
10
+ # -c concurrency Number of multiple requests to make
11
+ # -t timelimit Seconds to max. wait for responses
12
+ # -b windowsize Size of TCP send/receive buffer, in bytes
13
+ # -p postfile File containing data to POST. Remember also to set -T
14
+ # -T content-type Content-type header for POSTing, eg.
15
+ # 'application/x-www-form-urlencoded'
16
+ # Default is 'text/plain'
17
+ # -v verbosity How much troubleshooting info to print
18
+ # -w Print out results in HTML tables
19
+ # -i Use HEAD instead of GET
20
+ # -x attributes String to insert as table attributes
21
+ # -y attributes String to insert as tr attributes
22
+ # -z attributes String to insert as td or th attributes
23
+ # -C attribute Add cookie, eg. 'Apache=1234. (repeatable)
24
+ # -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
25
+ # Inserted after all normal header lines. (repeatable)
26
+ # -A attribute Add Basic WWW Authentication, the attributes
27
+ # are a colon separated username and password.
28
+ # -P attribute Add Basic Proxy Authentication, the attributes
29
+ # are a colon separated username and password.
30
+ # -X proxy:port Proxyserver and port number to use
31
+ # -V Print version number and exit
32
+ # -k Use HTTP KeepAlive feature
33
+ # -d Do not show percentiles served table.
34
+ # -S Do not show confidence estimators and warnings.
35
+ # -g filename Output collected data to gnuplot format file.
36
+ # -e filename Output CSV file with percentages served
37
+ # -r Don't exit on socket receive errors.
38
+ # -h Display usage information (this message)
39
+ # -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)
40
+ # -f protocol Specify SSL/TLS protocol (SSL2, SSL3, TLS1, or ALL)
41
+ class ApacheBench < Stella::Adapter::Base
42
+
43
+
44
+ attr_accessor :n, :c, :t, :b, :p, :T, :v, :w, :i, :x, :z, :y
45
+ attr_accessor :C, :H, :A, :P, :X, :V, :k, :d, :S, :e, :g, :r, :h, :Z, :f
46
+
47
+ def initialize(options={}, arguments=[])
48
+ super(options, arguments)
49
+ @private_variables = ['private_variables', 'name', 'arguments', 'load_factor', 'working_directory']
50
+ @c = 1
51
+ @n = 1
52
+ @name = 'ab'
53
+ @load_factor = 1
54
+ end
55
+
56
+
57
+ def version
58
+ vsn = 0
59
+ text = ""
60
+ Open3.popen3("#{@name} -V") do |stdin, stdout, stderr|
61
+ text = stdout.readlines.join
62
+ text.scan(/Version (\d+?\.\d+)/) { |v| vsn = v[0] }
63
+ end
64
+ vsn
65
+ end
66
+
67
+ def before
68
+
69
+ @e = @working_directory + "/ab-percentiles.log"
70
+ @e = File.expand_path(@e)
71
+
72
+ @g = @working_directory + "/ab-requests.log"
73
+ @g = File.expand_path(@g)
74
+
75
+ end
76
+ def command
77
+ raise CommandNotReady.new(self.class.to_s) unless ready?
78
+
79
+ command = "#{@name} "
80
+
81
+ instance_variables.each do |name|
82
+ canon = name.tr('@', '') # instance_variables returns '@name'
83
+ next if @private_variables.member?(canon)
84
+
85
+ # It's important that we take the value from the getter method
86
+ # because it applies the load factor.
87
+ value = self.send(canon)
88
+ if (value.is_a? Array)
89
+ value.each { |el| command << "-#{canon} #{EscapeUtil.shell_single_word(el.to_s)} " }
90
+ else
91
+ command << "-#{canon} #{EscapeUtil.shell_single_word(value.to_s)} "
92
+ end
93
+
94
+ end
95
+
96
+ command << (@arguments.map { |uri| "'#{uri}'" }).join(' ') unless @arguments.empty?
97
+ command
98
+ end
99
+ # loadtest
100
+ #
101
+ # True or false: is the call to ab a load test? If it's a call to help or version or
102
+ # to display the config this with return false. It's no reason for someone to make this
103
+ # call through Stella but it's here for goodness sake.
104
+ def loadtest?
105
+ !@arguments.empty? # The argument is a URI
106
+ end
107
+ def ready?
108
+ (!self.loadtest?) || (@name && !instance_variables.empty? && !@arguments.empty?)
109
+ end
110
+
111
+
112
+ def process_options(arguments)
113
+ options = OpenStruct.new
114
+ opts = OptionParser.new
115
+ opts.on('-v') do |v| options.v = true end
116
+ opts.on('-w') do |v| options.w = true end # TODO: Print a note that we don't parse the HTML results
117
+ opts.on('-i') do |v| options.i = true end
118
+ opts.on('-V') do |v| options.V = true end
119
+ opts.on('-k') do |v| options.k = true end
120
+ opts.on('-d') do |v| options.d = true end
121
+ opts.on('-S') do |v| options.S = true end
122
+ opts.on('-r') do |v| options.r = true end
123
+ opts.on('-h') do |v| options.h = true end
124
+ opts.on('-e S', String) do |v| options.e = v end
125
+ opts.on('-g S', String) do |v| options.g = v end
126
+ opts.on('-p S', String) do |v| options.p = v end
127
+ opts.on('-T S', String) do |v| options.t = v end
128
+ opts.on('-x S', String) do |v| options.x = v end
129
+ opts.on('-y S', String) do |v| options.y = v end
130
+ opts.on('-z S', String) do |v| options.z = v end
131
+ opts.on('-P S', String) do |v| options.P = v end
132
+ opts.on('-Z S', String) do |v| options.Z = v end
133
+ opts.on('-f S', String) do |v| options.f = v end
134
+ opts.on('-c N', Integer) do |v| options.c = v end
135
+ opts.on('-n N', Integer) do |v| options.n = v end
136
+ opts.on('-t N', Integer) do |v| options.t = v end
137
+ opts.on('-b N', Integer) do |v| options.b = v end
138
+ opts.on('-H S', String) do |v| options.H ||= []; options.H << v; end
139
+ opts.on('-C S', String) do |v| options.C ||= []; options.C << v; end
140
+
141
+ # NOTE: parse! removes the options it finds in @arguments. It will leave
142
+ # all unnamed arguments and throw a fit about unknown ones.
143
+ opts.parse!(arguments)
144
+
145
+ options
146
+ rescue OptionParser::InvalidOption => ex
147
+ # We want to replace this text so we grab just the name of the argument
148
+ badarg = ex.message.gsub('invalid option: ', '')
149
+ raise InvalidArgument.new(badarg)
150
+ end
151
+
152
+ def after
153
+ # We want to maintain copies of all test output, even when the user has
154
+ # supplied other path names so we'll copy the files from the testrun directory
155
+ # to the location specified by the user
156
+ [[@options.e, 'csv'], [@options.g, 'tsv']].each do |tuple|
157
+ if File.expand_path(File.dirname(tuple[0])) != File.expand_path(@runpath)
158
+ from = tuple[0]
159
+ to = @runpath + "/ab-#{tuple[1]}.log"
160
+ next unless File.exists?(from)
161
+ File.copy(from, to)
162
+ end
163
+ end
164
+
165
+ save_stats
166
+ end
167
+
168
+
169
+
170
+
171
+ def add_header(name, value)
172
+ @H ||= []
173
+ @H << "#{name}: #{value}"
174
+ end
175
+
176
+ def user_agent=(list=[])
177
+ return unless list && !list.empty?
178
+ list = list.to_ary
179
+ list.each do |agent|
180
+ add_header("User-Agent", agent)
181
+ end
182
+ end
183
+
184
+ def vusers
185
+ c || 0
186
+ end
187
+ def vusers=(v)
188
+ ratio = vuser_requests
189
+ @c = v
190
+ @n = ratio * @c
191
+ end
192
+ def requests
193
+ n || 0
194
+ end
195
+ def requests=(v)
196
+ @n = v
197
+ end
198
+ def vuser_requests
199
+ ratio = 1
200
+ # The request ratio tells us how many requests will be
201
+ # generated per vuser. It helps us later when we need to
202
+ # warmp up and ramp up.
203
+ if @n > 0 && @c > 0
204
+ ratio = (@n.to_f / @c.to_f).to_f
205
+ # If concurrency isn't set, we'll assume the total number of requests
206
+ # is intended to be per request
207
+ elsif @n > 0
208
+ ratio = @n
209
+ end
210
+ ratio
211
+ end
212
+ def c
213
+ (@c * @load_factor).to_i
214
+ end
215
+ def n
216
+ (@n * @load_factor).to_i
217
+ end
218
+
219
+ def hosts
220
+ hosts = @arguments || []
221
+ #hosts << get_hosts_from_file
222
+ hosts = hosts.map{ |h| tmp = URI.parse(h.strip); "#{tmp.host}:#{tmp.port}" }
223
+ hosts
224
+ end
225
+
226
+ def paths
227
+ paths = @arguments || []
228
+ #hosts << get_hosts_from_file
229
+ paths = paths.map{ |h| tmp = URI.parse(h.strip); "#{tmp.path}?#{tmp.query}" }
230
+ paths
231
+ end
232
+
233
+
234
+
235
+ # Apache bench writes the summary to STDOUT
236
+ def stats_file
237
+ File.new(stdout_path)
238
+ end
239
+
240
+ def stats
241
+ return unless stats_file
242
+ raw = {}
243
+ stats_file.each_line { |l|
244
+ l.chomp!
245
+ nvpair = l.split(':')
246
+ next unless nvpair && nvpair.size == 2
247
+ n = nvpair[0].strip.tr(' ', '_').downcase[/\w+/]
248
+ v = nvpair[1].strip[/[\.\d]+/]
249
+
250
+ # Apache Bench outputs two fields with the name "Time per request".
251
+ # We want only the first one so we don't overwrite values.
252
+ raw[n.to_sym] = v.to_f unless raw.has_key? n.to_sym
253
+ }
254
+
255
+ # Document Path: /
256
+ # Document Length: 96 bytes
257
+ #
258
+ # Concurrency Level: 75
259
+ # Time taken for tests: 2.001 seconds
260
+ # Complete requests: 750
261
+ # Failed requests: 0
262
+ # Write errors: 0
263
+ # Total transferred: 174000 bytes
264
+ # HTML transferred: 72000 bytes
265
+ # Requests per second: 374.74 [#/sec] (mean)
266
+ # Time per request: 200.138 [ms] (mean)
267
+ # Time per request: 2.669 [ms] (mean, across all concurrent requests)
268
+ # Transfer rate: 84.90 [Kbytes/sec] received
269
+
270
+ stats = Stella::Test::Run::Summary.new
271
+
272
+ unless raw.empty? || !raw.has_key?(:time_taken_for_tests)
273
+
274
+ stats.elapsed_time = raw[:time_taken_for_tests]
275
+
276
+ # We want this in MB, Apache Bench gives Bytes.
277
+ stats.data_transferred = ((raw[:html_transferred] || 0) / 1_048_576)
278
+
279
+ # total_transferred is header data + response data (html_transfered)
280
+ stats.headers_transferred = ((raw[:total_transferred] || 0) / 1_048_576) - stats.data_transferred
281
+
282
+ # Apache Bench returns ms
283
+ stats.response_time = (raw[:time_per_request] || 0) / 1000
284
+ stats.transaction_rate = raw[:requests_per_second]
285
+
286
+ stats.vusers = raw[:concurrency_level].to_i
287
+ stats.successful = raw[:complete_requests].to_i
288
+ stats.failed = raw[:failed_requests].to_i
289
+
290
+ stats.transactions = stats.successful + stats.failed
291
+
292
+ #stats.raw = raw if @global_options.debug
293
+ end
294
+
295
+ stats
296
+ end
297
+
298
+
299
+
300
+ end
301
+
302
+ end
303
+ end