solutious-stella 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/CHANGES.txt +39 -2
  2. data/LICENSE.txt +19 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +54 -59
  5. data/bin/example_test.rb +82 -0
  6. data/bin/example_webapp.rb +63 -0
  7. data/lib/{stella/logger.rb → logger.rb} +6 -11
  8. data/lib/stella.rb +76 -58
  9. data/lib/stella/clients.rb +161 -0
  10. data/lib/stella/command/base.rb +4 -24
  11. data/lib/stella/command/form.rb +36 -0
  12. data/lib/stella/command/get.rb +44 -0
  13. data/lib/stella/common.rb +53 -0
  14. data/lib/stella/crypto.rb +88 -0
  15. data/lib/stella/data/domain.rb +2 -2
  16. data/lib/stella/data/http.rb +164 -36
  17. data/lib/stella/environment.rb +66 -0
  18. data/lib/stella/functest.rb +105 -0
  19. data/lib/stella/loadtest.rb +186 -0
  20. data/lib/{utils → stella}/stats.rb +16 -20
  21. data/lib/stella/testplan.rb +237 -0
  22. data/lib/stella/testrunner.rb +64 -0
  23. data/lib/storable.rb +280 -0
  24. data/lib/threadify.rb +171 -0
  25. data/lib/timeunits.rb +65 -0
  26. data/lib/util/httputil.rb +266 -0
  27. data/stella.gemspec +69 -0
  28. data/tryouts/drb/drb_test.rb +65 -0
  29. data/tryouts/drb/open4.rb +19 -0
  30. data/tryouts/drb/slave.rb +27 -0
  31. data/tryouts/oo_tryout.rb +30 -0
  32. metadata +39 -107
  33. data/README.textile +0 -162
  34. data/bin/stella +0 -12
  35. data/bin/stella.bat +0 -12
  36. data/lib/daemonize.rb +0 -56
  37. data/lib/pcaplet.rb +0 -180
  38. data/lib/stella/adapter/ab.rb +0 -337
  39. data/lib/stella/adapter/base.rb +0 -106
  40. data/lib/stella/adapter/httperf.rb +0 -305
  41. data/lib/stella/adapter/pcap_watcher.rb +0 -221
  42. data/lib/stella/adapter/proxy_watcher.rb +0 -76
  43. data/lib/stella/adapter/siege.rb +0 -341
  44. data/lib/stella/cli.rb +0 -258
  45. data/lib/stella/cli/agents.rb +0 -73
  46. data/lib/stella/cli/base.rb +0 -55
  47. data/lib/stella/cli/language.rb +0 -18
  48. data/lib/stella/cli/localtest.rb +0 -78
  49. data/lib/stella/cli/sysinfo.rb +0 -16
  50. data/lib/stella/cli/watch.rb +0 -278
  51. data/lib/stella/command/localtest.rb +0 -358
  52. data/lib/stella/response.rb +0 -85
  53. data/lib/stella/storable.rb +0 -201
  54. data/lib/stella/support.rb +0 -276
  55. data/lib/stella/sysinfo.rb +0 -257
  56. data/lib/stella/test/definition.rb +0 -79
  57. data/lib/stella/test/run/summary.rb +0 -70
  58. data/lib/stella/test/stats.rb +0 -114
  59. data/lib/stella/text.rb +0 -64
  60. data/lib/stella/text/resource.rb +0 -38
  61. data/lib/utils/crypto-key.rb +0 -84
  62. data/lib/utils/domainutil.rb +0 -47
  63. data/lib/utils/escape.rb +0 -302
  64. data/lib/utils/fileutil.rb +0 -78
  65. data/lib/utils/httputil.rb +0 -266
  66. data/lib/utils/mathutil.rb +0 -15
  67. data/lib/utils/textgraph.rb +0 -267
  68. data/lib/utils/timerutil.rb +0 -58
  69. data/lib/win32/Console.rb +0 -970
  70. data/lib/win32/Console/ANSI.rb +0 -305
  71. data/support/kvm.h +0 -91
  72. data/support/ruby-pcap-takuma-notes.txt +0 -19
  73. data/support/ruby-pcap-takuma-patch.txt +0 -30
  74. data/support/text/en.yaml +0 -80
  75. data/support/text/nl.yaml +0 -7
  76. data/support/useragents.txt +0 -75
  77. data/tests/01-util_test.rb +0 -0
  78. data/tests/02-stella-util_test.rb +0 -42
  79. data/tests/10-stella_test.rb +0 -104
  80. data/tests/11-stella-storable_test.rb +0 -68
  81. data/tests/60-stella-command_test.rb +0 -248
  82. data/tests/80-stella-cli_test.rb +0 -45
  83. data/tests/spec-helper.rb +0 -31
data/bin/stella.bat DELETED
@@ -1,12 +0,0 @@
1
- @echo off
2
-
3
- rem Check for funkiness when called from another batch script.
4
- rem We want FULL_PATH to contain the full path to the stella bin directory.
5
- IF EXIST "%~dp0stella.bat" (set FULL_PATH=%~dp0) ELSE (set FULL_PATH=%~dp$PATH:0)
6
-
7
- rem Check for JRuby, otherwise use Ruby.
8
- rem We want EXECUTABLE to contain either "jruby" or "ruby"
9
- IF EXIST "%JRUBY_HOME%" (set EXECUTABLE=jruby) ELSE (set EXECUTABLE=ruby)
10
-
11
- rem Call the Ruby script, passing it all the arguments.
12
- @%EXECUTABLE% %FULL_PATH%stella %*
data/lib/daemonize.rb DELETED
@@ -1,56 +0,0 @@
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/pcaplet.rb DELETED
@@ -1,180 +0,0 @@
1
- require 'pcap'
2
-
3
-
4
- # Pcaplet
5
- #
6
- # Adapted from Ruby portion of Ruby-Pcap:
7
- # http://www.goto.info.waseda.ac.jp/~fukusima/ruby/pcap-e.html
8
- # The lib/pcaplet.rb and lib/pcap_misc.rb files are in merge into this file
9
- # and cleaned up. The Ruby-Pcap C extension was modified to apply several fixes
10
- # so it would compile on OS X and to remove several warning messages. With
11
- # help from: http://d.hatena.ne.jp/takuma104/20080210/1202638583
12
- # We specifically removed the dependency on ARGV and OptParse. It was messy
13
- # and required ARGV to be specifically modified before requiring this package.
14
- # Manual: http://www.goto.info.waseda.ac.jp/~fukusima/ruby/pcap/doc/index.html
15
- class Pcaplet
16
-
17
- attr_accessor :debug, :verbose
18
- # do not convert address to name
19
- attr_accessor :convert
20
- attr_accessor :device, :rfile, :count, :snaplen, :filter
21
-
22
- def initialize(args = {})
23
-
24
- @debug = args[:debug] || false
25
- @verbose = args[:verbose] || false
26
- @device = args[:device] || guess_device
27
- @rfile = args[:rfile]
28
- @convert = args[:convert] || false
29
- @count = args[:count].to_i || 1000
30
- @snaplen = args[:snaplen].to_i > 0 ? args[:snaplen] : 1500
31
- @filter = args[:filter] || ''
32
-
33
- Pcap.convert = @convert
34
-
35
- # check option consistency
36
- usage(1) if @device && @rfile
37
- if !@device and !@rfile
38
- @device = Pcap.lookupdev
39
- end
40
-
41
- # open
42
- begin
43
- if @device
44
- @capture = Pcap::Capture.open_live(@device, @snaplen)
45
- elsif @rfile
46
- if @rfile !~ /\.gz$/
47
- @capture = Capture.open_offline(@rfile)
48
- else
49
- $stdin = IO.popen("gzip -dc < #@rfile", 'r')
50
- @capture = Capture.open_offline('-')
51
- end
52
- end
53
- @capture.setfilter(@filter) if @filter
54
- rescue Pcap::PcapError, ArgumentError
55
- $stdout.flush
56
- $stderr.puts $!
57
- exit(1)
58
- end
59
- end
60
-
61
- attr('capture')
62
-
63
-
64
- def add_filter(f)
65
- if @filter == nil || @filter =~ /^\s*$/ # if empty
66
- #puts "filter is nil or empty"
67
- @filter = f
68
- else
69
- #puts "filter is #{@filter}"
70
- f = f.source if f.is_a? Filter
71
- @filter = "( #{@filter} ) and ( #{f} )"
72
- end
73
- #puts "filter being set #{@filter}"
74
- @capture.setfilter(@filter)
75
- end
76
-
77
- def each_packet(&block)
78
-
79
- begin
80
- duplicated = (RUBY_PLATFORM =~ /linux/ && @device == "lo")
81
- unless duplicated
82
- @capture.loop(@count, &block)
83
- else
84
- flip = true
85
- @capture.loop(@count) do |pkt|
86
- flip = (! flip)
87
- next if flip
88
- block.call pkt
89
- end
90
- end
91
- end
92
- end
93
-
94
- alias each each_packet
95
-
96
- def close
97
- @capture.close
98
- end
99
- end
100
-
101
-
102
-
103
- module Pcap
104
- class Packet
105
- def to_s
106
- 'Some packet'
107
- end
108
-
109
- def inspect
110
- "#<#{type}: #{self}>"
111
- end
112
- end
113
-
114
- class IPPacket
115
- def to_s
116
- "#{ip_src} > #{ip_dst}"
117
- end
118
- end
119
-
120
- class TCPPacket
121
- def tcp_data_len
122
- ip_len - 4 * (ip_hlen + tcp_hlen)
123
- end
124
-
125
- # The 3-way handshake that initiates a request
126
- # ....S. --->
127
- # .A..S. <---
128
- # .A.... --->
129
- #
130
- # The teardown procedure at the end of the request
131
- # .A...F --->
132
- # .A.... <---
133
- # .A...F --->
134
- # .A.... <...
135
- def tcp_flags_s
136
- return \
137
- (tcp_urg? ? 'U' : '.') + # Urgent
138
- (tcp_ack? ? 'A' : '.') + # ACKnowledgement: Successful transfer
139
- (tcp_psh? ? 'P' : '.') + # Push
140
- (tcp_rst? ? 'R' : '.') + # Reset
141
- (tcp_syn? ? 'S' : '.') + # SYNchronization: this is the first segment in a new transaction
142
- (tcp_fin? ? 'F' : '.') # FINal: final transaction
143
- end
144
-
145
- def to_s
146
- "#{src}:#{sport} > #{dst}:#{dport} #{tcp_flags_s}"
147
- end
148
- end
149
-
150
- class UDPPacket
151
- def to_s
152
- "#{src}:#{sport} > #{dst}:#{dport} len #{udp_len} sum #{udp_sum}"
153
- end
154
- end
155
-
156
- class ICMPPacket
157
- def to_s
158
- "#{src} > #{dst}: icmp: #{icmp_typestr}"
159
- end
160
- end
161
-
162
- #
163
- # Backword compatibility
164
- #
165
- IpPacket = IPPacket unless defined? IpPacket
166
- IpAddress = IPAddress unless defined? IpAddress
167
- TcpPacket = TCPPacket unless defined? TcpPacket
168
- UdpPacket = UDPPacket unless defined? UdpPacket
169
-
170
- end
171
-
172
- class Time
173
- # tcpdump style format
174
- def tcpdump
175
- sprintf "%0.2d:%0.2d:%0.2d.%0.6d", hour, min, sec, tv_usec
176
- end
177
- end
178
-
179
-
180
-
@@ -1,337 +0,0 @@
1
-
2
- require 'fileutils'
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
- attr_writer :n, :c
44
- attr_accessor :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
- @private_variables = ['private_variables', 'name', 'arguments', 'load_factor', 'working_directory']
49
- @c = 1
50
- @n = 1
51
- @name = 'ab'
52
- @load_factor = 1
53
-
54
- super(options, arguments)
55
-
56
- end
57
-
58
- def error
59
- (File.exists? stderr_path) ? FileUtil.read_file(stderr_path) : "Unknown error"
60
- end
61
-
62
- def version
63
- vsn = 0
64
- Stella::Util.capture_output("#{@name} -V") do |stdout, stderr|
65
- stdout.join.scan(/Version (\d+?\.\d+)/) { |v| vsn = v[0] }
66
- end
67
- vsn
68
- end
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
-
78
- def before
79
- @e = percentiles_file if @e.nil?
80
- @g = requests_file if @g.nil?
81
- end
82
-
83
- def command
84
- raise CommandNotReady.new(self.class.to_s) unless ready?
85
-
86
- command = "#{@name} "
87
-
88
- instance_variables.each do |name|
89
- canon = name.to_s.tr('@', '') # instance_variables returns '@name'
90
- next if @private_variables.member?(canon)
91
-
92
- # It's important that we take the value from the getter method
93
- # because it applies the load factor.
94
- value = self.send(canon)
95
- if (value.is_a? Array)
96
- value.each { |el| command << "-#{canon} #{EscapeUtil.shell_single_word(value.to_s)} " }
97
- else
98
- command << "-#{canon} #{EscapeUtil.shell_single_word(value.to_s)} "
99
- end
100
-
101
- end
102
-
103
- command << (@arguments.map { |uri| "#{uri}" }).join(' ') unless @arguments.empty?
104
-
105
- command
106
- end
107
- # loadtest
108
- #
109
- # True or false: is the call to ab a load test? If it's a call to help or version or
110
- # to display the config this with return false. It's no reason for someone to make this
111
- # call through Stella but it's here for goodness sake.
112
- def loadtest?
113
- !@arguments.empty? # The argument is a URI
114
- end
115
- def ready?
116
- (!self.loadtest?) || (@name && !instance_variables.empty? && !@arguments.empty?)
117
- end
118
-
119
-
120
- def process_arguments(arguments)
121
- opts = OptionParser.new
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
-
126
- # TODO: Print a note for w that we don't parse the HTML results
127
- %w{v w i V k d S r h}.each do |n|
128
- opts.on("-#{n}") do |v| instance_variable_set("@#{n}", true) end
129
- end
130
-
131
- %w{e g p T x y z P Z f A}.each do |n|
132
- opts.on("-#{n} S", String) do |v| instance_variable_set("@#{n}", v) end
133
- end
134
-
135
- %w{c n t b}.each do |n|
136
- opts.on("-#{n} S", Integer) do |v| instance_variable_set("@#{n}", v) end
137
- end
138
-
139
- opts.on('-H S', String) do |v| @H ||= []; @H << v; end
140
- opts.on('-C S', String) do |v| @C ||= []; @C << v; end
141
-
142
- opts.on('-b') do |v|
143
- Stella.warn("-b is not an ab option. I'll pretend it's not there.")
144
- end
145
-
146
- opts.on('-r N',Integer) do |v|
147
- Stella.error("-r is not an ab parameter. You probably want -n.")
148
- exit 1
149
- end
150
-
151
- # NOTE: parse! removes the options it finds in @arguments. It will leave
152
- # all unnamed arguments and throw a fit about unknown ones.
153
- opts.parse!(arguments)
154
-
155
- if arguments.empty?
156
- Stella.error("You need to provide a URI")
157
- exit 1
158
- elsif arguments.size > 1
159
- Stella.warn("ab can handle only one URI. The others will be ignored.")
160
- arguments = arguments.first
161
- else
162
- # Let's make sure the URI has a path (at least a trailing slash). Otherwise
163
- # ab gives a cryptic error.
164
- begin
165
- uri = URI.parse(arguments.first)
166
- if !uri || uri.path.empty?
167
- Stella.error("ab requires a trailing slash for #{uri.to_s}")
168
- exit 1
169
- end
170
- rescue => ex
171
- Stella.error("Bad URI: #{arguments.first}")
172
- exit 1
173
- end
174
- end
175
-
176
- self.arguments = arguments
177
-
178
- rescue OptionParser::InvalidOption => ex
179
- # We want to replace this text so we grab just the name of the argument
180
- badarg = ex.message.gsub('invalid option: ', '')
181
- raise InvalidArgument.new(badarg)
182
- end
183
-
184
- def after
185
- # We want to maintain copies of all test output, even when the user has
186
- # supplied other path names so we'll copy the files from the testrun directory
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)
192
- from = tuple[0]
193
- to = @working_directory + "/ab-#{tuple[1]}.log"
194
- next unless File.exists?(from)
195
- FileUtils.cp(from, to)
196
- end
197
- end
198
-
199
-
200
- end
201
-
202
-
203
-
204
-
205
- def add_header(name, value)
206
- @H ||= []
207
- @H << "#{name}: #{value}"
208
- end
209
-
210
- def user_agent=(list=[])
211
- return unless list && !list.empty?
212
- list = list.to_ary
213
- list.each do |agent|
214
- add_header("User-Agent", agent)
215
- end
216
- end
217
-
218
- def vusers
219
- c || 0
220
- end
221
- def vusers=(v)
222
- ratio = vuser_requests
223
- @c = v
224
- @n = ratio * @c
225
- end
226
- def requests
227
- n || 0
228
- end
229
- def requests=(v)
230
- @n = v
231
- end
232
- def vuser_requests
233
- ratio = 1
234
- # The request ratio tells us how many requests will be
235
- # generated per vuser. It helps us later when we need to
236
- # warmp up and ramp up.
237
- if @n > 0 && @c > 0
238
- ratio = (@n.to_f / @c.to_f).to_f
239
- # If concurrency isn't set, we'll assume the total number of requests
240
- # is intended to be per request
241
- elsif @n > 0
242
- ratio = @n
243
- end
244
- ratio
245
- end
246
- def c
247
- (@c * @load_factor).to_i
248
- end
249
- def n
250
- (@n * @load_factor).to_i
251
- end
252
-
253
- def hosts
254
- hosts = @arguments || []
255
- #hosts << get_hosts_from_file
256
- hosts = hosts.map{ |h| tmp = URI.parse(h.strip); "#{tmp.host}:#{tmp.port}" }
257
- hosts
258
- end
259
-
260
- def paths
261
- paths = @arguments || []
262
- #hosts << get_hosts_from_file
263
- paths = paths.map{ |h| tmp = URI.parse(h.strip); "#{tmp.path}?#{tmp.query}" }
264
- paths
265
- end
266
-
267
-
268
-
269
- # Apache bench writes the summary to STDOUT
270
- def summary_file
271
- File.new(stdout_path) if File.exists?(stdout_path)
272
- end
273
-
274
- def summary
275
- return unless summary_file
276
- raw = {}
277
- summary_file.each_line { |l|
278
- l.chomp!
279
- nvpair = l.split(':')
280
- next unless nvpair && nvpair.size == 2
281
- n = nvpair[0].strip.tr(' ', '_').downcase[/\w+/]
282
- v = nvpair[1].strip[/[\.\d]+/]
283
-
284
- # Apache Bench outputs two fields with the name "Time per request".
285
- # We want only the first one so we don't overwrite values.
286
- raw[n.to_sym] = v.to_f unless raw.has_key? n.to_sym
287
- }
288
-
289
- # Document Path: /
290
- # Document Length: 96 bytes
291
- #
292
- # Concurrency Level: 75
293
- # Time taken for tests: 2.001 seconds
294
- # Complete requests: 750
295
- # Failed requests: 0
296
- # Write errors: 0
297
- # Total transferred: 174000 bytes
298
- # HTML transferred: 72000 bytes
299
- # Requests per second: 374.74 [#/sec] (mean)
300
- # Time per request: 200.138 [ms] (mean)
301
- # Time per request: 2.669 [ms] (mean, across all concurrent requests)
302
- # Transfer rate: 84.90 [Kbytes/sec] received
303
-
304
- stats = Stella::Test::Run::Summary.new
305
-
306
- if !raw.empty? && raw.has_key?(:time_taken_for_tests)
307
-
308
- stats.elapsed_time = raw[:time_taken_for_tests]
309
-
310
- # We want this in MB, Apache Bench gives Bytes.
311
- stats.data_transferred = ((raw[:html_transferred] || 0) / 1_048_576)
312
-
313
- # total_transferred is header data + response data (html_transfered)
314
- stats.headers_transferred = ((raw[:total_transferred] || 0) / 1_048_576) - stats.data_transferred
315
-
316
- # Apache Bench returns ms
317
- stats.response_time = (raw[:time_per_request] || 0) / 1000
318
- stats.transaction_rate = raw[:requests_per_second]
319
-
320
- stats.vusers = raw[:concurrency_level].to_i
321
- stats.successful = raw[:complete_requests].to_i
322
- stats.failed = raw[:failed_requests].to_i
323
-
324
- stats.transactions = stats.successful + stats.failed
325
-
326
- #stats.raw = raw if @global_options.debug
327
- end
328
-
329
- stats
330
- end
331
-
332
-
333
-
334
- end
335
-
336
- end
337
- end