stella 0.8.8.001 → 2.0.1.001
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +9 -1
- data/Gemfile +19 -0
- data/Gemfile.lock +50 -0
- data/README.md +5 -79
- data/Rakefile +10 -7
- data/Rudyfile +1 -1
- data/TODO +31 -0
- data/VERSION.yml +3 -4
- data/bin/stella +23 -81
- data/certs/README.txt +17 -0
- data/certs/cacerts.pem +1529 -0
- data/certs/gd-class2-root.crt +24 -0
- data/certs/gd_bundle.crt +76 -0
- data/certs/gd_intermediate.crt +29 -0
- data/certs/startssl-ca.pem +44 -0
- data/certs/startssl-sub.class1.server.ca.pem +36 -0
- data/certs/stella-master.crt +1738 -0
- data/lib/stella.rb +191 -123
- data/lib/stella/cli.rb +47 -67
- data/lib/stella/client.rb +424 -360
- data/lib/stella/core_ext.rb +527 -0
- data/lib/stella/engine.rb +126 -419
- data/lib/stella/report.rb +391 -0
- data/lib/stella/testplan.rb +432 -306
- data/lib/stella/utils.rb +227 -2
- data/stella.gemspec +56 -55
- data/try/00_basics_try.rb +29 -0
- data/try/01_selectable_try.rb +25 -0
- data/try/09_utils_try.rb +67 -0
- data/try/10_stella_object_try.rb +49 -0
- data/try/40_report_try.rb +133 -0
- data/try/90_class_syntax_try.rb +13 -0
- data/try/emhttp.rb +62 -0
- data/try/rubyroute.rb +70 -0
- data/try/support/file.bmp +0 -0
- data/try/support/file.gif +0 -0
- data/try/support/file.ico +0 -0
- data/try/support/file.jpeg +0 -0
- data/try/support/file.jpg +0 -0
- data/try/support/file.png +0 -0
- data/try/traceviz.rb +60 -0
- data/vendor/httpclient-2.1.5.2/httpclient/session.rb +5 -2
- metadata +81 -53
- data/examples/cookies/plan.rb +0 -49
- data/examples/csvdata/plan.rb +0 -32
- data/examples/csvdata/search_terms.csv +0 -14
- data/examples/dynamic/plan.rb +0 -60
- data/examples/essentials/logo.png +0 -0
- data/examples/essentials/plan.rb +0 -248
- data/examples/essentials/search_terms.txt +0 -19
- data/examples/exceptions/plan.rb +0 -20
- data/examples/httpauth/plan.rb +0 -33
- data/examples/timeout/plan.rb +0 -18
- data/examples/variables/plan.rb +0 -41
- data/lib/stella/client/container.rb +0 -378
- data/lib/stella/common.rb +0 -363
- data/lib/stella/data.rb +0 -59
- data/lib/stella/data/http.rb +0 -189
- data/lib/stella/engine/functional.rb +0 -156
- data/lib/stella/engine/load.rb +0 -516
- data/lib/stella/guidelines.rb +0 -18
- data/lib/stella/logger.rb +0 -150
- data/lib/stella/utils/httputil.rb +0 -266
- data/try/01_numeric_mixins_tryouts.rb +0 -40
- data/try/12_digest_tryouts.rb +0 -42
- data/try/70_module_usage.rb +0 -21
- data/try/api/10_functional.rb +0 -20
- data/try/configs/failed_requests.rb +0 -31
- data/try/configs/global_sequential.rb +0 -18
- data/try/proofs/thread_queue.rb +0 -21
@@ -1,156 +0,0 @@
|
|
1
|
-
|
2
|
-
module Stella::Engine
|
3
|
-
class Functional < Stella::Engine::Base
|
4
|
-
|
5
|
-
def run(testrun)
|
6
|
-
client = Stella::Client.new testrun.hosts.first, testrun.client_options
|
7
|
-
client.add_observer(self)
|
8
|
-
|
9
|
-
p testrun.client_options
|
10
|
-
|
11
|
-
Stella.stdout.info2 $/, "Starting test...", $/
|
12
|
-
testrun.start_time = Time.now.utc.to_i
|
13
|
-
|
14
|
-
start_time = Time.now.utc
|
15
|
-
|
16
|
-
thread = Thread.new do
|
17
|
-
# Identify this thread to Benelux
|
18
|
-
Benelux.current_track :functional
|
19
|
-
|
20
|
-
dig = Stella.stdout.lev > 1 ? testrun.plan.id : testrun.plan.id.shorter
|
21
|
-
Stella.stdout.info " %-65s ".att(:reverse) % ["#{testrun.plan.desc} (#{dig})"]
|
22
|
-
testrun.plan.usecases.each_with_index do |uc,i|
|
23
|
-
desc = (uc.desc || "Usecase ##{i+1}")
|
24
|
-
Benelux.add_thread_tags :usecase => uc.id
|
25
|
-
dig = Stella.stdout.lev > 1 ? uc.id : uc.id.shorter
|
26
|
-
Stella.stdout.info ' %-65s '.att(:reverse).bright % ["#{desc} (#{dig}) "]
|
27
|
-
Stella.rescue { client.execute uc }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
thread.join
|
32
|
-
|
33
|
-
test_time = Time.now.utc - start_time
|
34
|
-
|
35
|
-
# Need to use thread timeline b/c the clients are running in the
|
36
|
-
# main thread which Benelux.update_global_timeline does not touch.
|
37
|
-
tt = thread.timeline
|
38
|
-
|
39
|
-
testrun
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
def update_prepare_request(client_id, usecase, req, counter)
|
44
|
-
notice = "repeat: #{counter-1}" if counter > 1
|
45
|
-
dig = Stella.stdout.lev > 1 ? req.id : req.id.shorter
|
46
|
-
desc = "#{req.desc} (#{dig}) "
|
47
|
-
Stella.stdout.info2 " %-46s %16s ".bright % [desc, notice]
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
|
52
|
-
log = Stella::Engine::Log.new Time.now.to_f, container.unique_id, client_id,
|
53
|
-
'testplanid',
|
54
|
-
usecase.id, req.id,
|
55
|
-
req.http_method, container.status, uri.to_s,
|
56
|
-
params, container.response.request.header.dump,
|
57
|
-
container.response.header.dump,
|
58
|
-
container.response.body.content
|
59
|
-
|
60
|
-
Benelux.thread_timeline.add_message log, :status => container.status, :kind => :log
|
61
|
-
|
62
|
-
msg = ' %-6s %-53s ' % [req.http_method, uri]
|
63
|
-
msg << container.status.to_s if Stella.stdout.lev <= 2
|
64
|
-
Stella.stdout.info msg
|
65
|
-
|
66
|
-
Stella.stdout.info2 $/, " Params:"
|
67
|
-
params.each do |pair|
|
68
|
-
Stella.stdout.info2 " %s: %s" % pair
|
69
|
-
end
|
70
|
-
|
71
|
-
Stella.stdout.info3 $/, ' ' << container.response.request.header.send(:request_line)
|
72
|
-
|
73
|
-
container.response.request.header.all.each do |pair|
|
74
|
-
Stella.stdout.info3 " %s: %s" % pair
|
75
|
-
end
|
76
|
-
|
77
|
-
if req.http_method == 'POST'
|
78
|
-
cont = container.response.request.body.content
|
79
|
-
if String === cont
|
80
|
-
Stella.stdout.info4(' ' << cont.split($/).join("#{$/} "))
|
81
|
-
elsif HTTP::Message::Body::Parts === cont
|
82
|
-
cont.parts.each do |part|
|
83
|
-
if File === part
|
84
|
-
Stella.stdout.info4 "<#{part.path}>"
|
85
|
-
else
|
86
|
-
Stella.stdout.info4 part
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
resh = container.response.header
|
93
|
-
Stella.stdout.info3 $/, ' HTTP/%s %3d %s' % [resh.http_version, resh.status_code, resh.reason_phrase]
|
94
|
-
container.headers.all.each do |pair|
|
95
|
-
Stella.stdout.info3 " %s: %s" % pair
|
96
|
-
end
|
97
|
-
Stella.stdout.info4 container.body.empty? ? ' [empty]' : container.body
|
98
|
-
Stella.stdout.info2 $/
|
99
|
-
end
|
100
|
-
|
101
|
-
def update_execute_response_handler(client_id, req, container)
|
102
|
-
end
|
103
|
-
|
104
|
-
def update_error_execute_response_handler(client_id, ex, req, container)
|
105
|
-
Stella.le "#{ex.message} (#{ex.backtrace.first})"
|
106
|
-
Stella.ld ex.backtrace
|
107
|
-
end
|
108
|
-
|
109
|
-
def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
|
110
|
-
#desc = "#{usecase.desc} > #{req.desc}"
|
111
|
-
Stella.le ' ERROR %24s %s' % [ex.message, uri]
|
112
|
-
Stella.le ' %s' % params.inspect
|
113
|
-
unless req.headers.nil? || req.headers.empty?
|
114
|
-
Stella.le ' %s' % req.headers.inspect
|
115
|
-
end
|
116
|
-
Stella.ld ex.backtrace
|
117
|
-
end
|
118
|
-
|
119
|
-
def update_follow_redirect client_id, ret, req, container
|
120
|
-
Stella.stdout.info2 " FOLLOW %-53s" % [ret.uri]
|
121
|
-
end
|
122
|
-
|
123
|
-
def update_max_redirects client_id, counter, ret, req, container
|
124
|
-
Stella.stdout.info " MAX REDIRECTS %-53s" % [counter]
|
125
|
-
end
|
126
|
-
|
127
|
-
def update_usecase_quit client_id, msg, req, container
|
128
|
-
Benelux.thread_timeline.add_count :failed, 1
|
129
|
-
Stella.stdout.info " QUIT %s" % [msg]
|
130
|
-
end
|
131
|
-
|
132
|
-
def update_request_fail client_id, msg, req, container
|
133
|
-
Benelux.thread_timeline.add_count :failed, 1
|
134
|
-
Stella.stdout.info " FAILED %s" % [msg]
|
135
|
-
end
|
136
|
-
|
137
|
-
def update_request_error client_id, msg, req, container
|
138
|
-
Benelux.thread_timeline.add_count :failed, 1
|
139
|
-
Stella.stdout.info " ERROR %s" % [msg]
|
140
|
-
end
|
141
|
-
|
142
|
-
def update_request_repeat client_id, counter, total, req, container
|
143
|
-
Stella.stdout.info3 " REPEAT %d of %d" % [counter, total]
|
144
|
-
end
|
145
|
-
|
146
|
-
def update_authenticate client_id, usecase, req, domain, user, pass
|
147
|
-
Stella.stdout.info " AUTH #{domain} (#{user}/#{pass})"
|
148
|
-
end
|
149
|
-
|
150
|
-
def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container, timeout)
|
151
|
-
Benelux.thread_timeline.add_count :failed, 1
|
152
|
-
Stella.stdout.info " TIMEOUT(%f) %-53s" % [uri, timeout]
|
153
|
-
end
|
154
|
-
|
155
|
-
end
|
156
|
-
end
|
data/lib/stella/engine/load.rb
DELETED
@@ -1,516 +0,0 @@
|
|
1
|
-
|
2
|
-
module Stella::Engine
|
3
|
-
class Load < Stella::Engine::Base
|
4
|
-
|
5
|
-
@timers = [:response_time]
|
6
|
-
@counts = [:response_content_size]
|
7
|
-
|
8
|
-
def run(testrun)
|
9
|
-
@threads, @max_clients, @real_reps = [], 0, 0
|
10
|
-
counts = calculate_usecase_clients testrun
|
11
|
-
packages = build_thread_package testrun, counts
|
12
|
-
|
13
|
-
unless Stella::Logger.disabled?
|
14
|
-
Stella.stdout.info "Logging to #{testrun.log_dir}", $/
|
15
|
-
|
16
|
-
latest = File.join(File.dirname(testrun.log_dir), 'latest')
|
17
|
-
if Stella.sysinfo.os == :unix
|
18
|
-
File.unlink latest if File.exists? latest
|
19
|
-
FileUtils.ln_sf File.basename(testrun.log_dir), latest
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
@sumlog = Stella::Logger.new testrun.log_path('summary')
|
24
|
-
@failog = Stella::Logger.new testrun.log_path('exceptions')
|
25
|
-
|
26
|
-
Stella.stdout.add_template :head, ' %s: %s'
|
27
|
-
Stella.stdout.add_template :status, "#{$/}%s..."
|
28
|
-
|
29
|
-
if Stella.stdout.lev >= 2
|
30
|
-
Load.timers += [:socket_connect, :send_request, :first_byte, :receive_response]
|
31
|
-
Load.counts = [:request_header_size, :request_content_size]
|
32
|
-
Load.counts += [:response_headers_size, :response_content_size]
|
33
|
-
end
|
34
|
-
|
35
|
-
testrun.save
|
36
|
-
|
37
|
-
@dumper = prepare_dumper(testrun)
|
38
|
-
|
39
|
-
if testrun.duration > 0
|
40
|
-
timing = "#{testrun.duration.seconds.to_i} seconds"
|
41
|
-
else
|
42
|
-
timing = "#{testrun.repetitions} repetitions"
|
43
|
-
end
|
44
|
-
|
45
|
-
Stella.stdout.head "Runid", "#{testrun.id.shorter}"
|
46
|
-
Stella.stdout.head 'Plan', "#{testrun.plan.desc} (#{testrun.plan.id.shorter})"
|
47
|
-
Stella.stdout.head 'Hosts', testrun.hosts.join(', ')
|
48
|
-
Stella.stdout.head 'Clients', counts[:total]
|
49
|
-
Stella.stdout.head 'Limit', timing
|
50
|
-
Stella.stdout.head 'Wait', testrun.wait
|
51
|
-
Stella.stdout.head 'Arrival', testrun.arrival if testrun.arrival
|
52
|
-
|
53
|
-
@dumper.start
|
54
|
-
|
55
|
-
begin
|
56
|
-
Stella.stdout.status "Running"
|
57
|
-
testrun.status = "running"
|
58
|
-
testrun.start_time = Time.now.utc.to_i
|
59
|
-
execute_test_plan packages, testrun
|
60
|
-
rescue Interrupt
|
61
|
-
Stella.stdout.info $/, "Stopping test"
|
62
|
-
Stella.abort!
|
63
|
-
@threads.each { |t| t.join } unless @threads.nil? || @threads.empty? # wait
|
64
|
-
rescue => ex
|
65
|
-
STDERR.puts "Unhandled exception: #{ex.message}"
|
66
|
-
STDERR.puts ex.backtrace if Stella.debug? || Stella.stdout.lev >= 3
|
67
|
-
end
|
68
|
-
|
69
|
-
Stella.stdout.status "Processing"
|
70
|
-
|
71
|
-
@dumper.stop
|
72
|
-
|
73
|
-
bt = Benelux.timeline
|
74
|
-
tt = Benelux.thread_timeline
|
75
|
-
|
76
|
-
# TODO: don't get test time from benelux.
|
77
|
-
test_time = tt.stats.group(:execute_test_plan).mean
|
78
|
-
generate_report @sumlog, testrun, test_time
|
79
|
-
#report_time = tt.stats.group(:generate_report).mean
|
80
|
-
|
81
|
-
unless Stella::Logger.disabled?
|
82
|
-
Stella.stdout.info File.read(@sumlog.path)
|
83
|
-
Stella.stdout.info $/, "Log dir: #{testrun.log_dir}"
|
84
|
-
end
|
85
|
-
|
86
|
-
testrun
|
87
|
-
end
|
88
|
-
|
89
|
-
def execute_test_plan(packages, testrun)
|
90
|
-
time_started = Time.now
|
91
|
-
|
92
|
-
pqueue = Queue.new
|
93
|
-
packages.each { |p| pqueue << p }
|
94
|
-
|
95
|
-
@real_reps += 1 # Increments when duration is specified.
|
96
|
-
@threads = []
|
97
|
-
packages.size.times {
|
98
|
-
@max_clients += 1
|
99
|
-
@threads << Thread.new do
|
100
|
-
package = pqueue.pop
|
101
|
-
Thread.current[:real_reps] = 0
|
102
|
-
Thread.current[:real_uctime] = Benelux::Stats::Calculator.new
|
103
|
-
c, uc = package.client, package.usecase
|
104
|
-
Stella.stdout.info4 $/, "======== THREAD %s: START" % [c.id.short]
|
105
|
-
|
106
|
-
# This thread will stay on this one track.
|
107
|
-
Benelux.current_track c.id
|
108
|
-
|
109
|
-
Benelux.add_thread_tags :usecase => uc.id
|
110
|
-
Thread.current[:real_uctime].first_tick
|
111
|
-
prev_ptime ||= Time.now
|
112
|
-
testrun.repetitions.times { |rep|
|
113
|
-
break if Stella.abort?
|
114
|
-
Thread.current[:real_reps] += 1
|
115
|
-
# NOTE: It's important to not call digest or gibbler methods
|
116
|
-
# on client object b/c it is not frozen. Always use digest_cache.
|
117
|
-
args = [c.id.short, uc.desc, uc.id.short, Thread.current[:real_reps]]
|
118
|
-
Stella.stdout.info4 $/, "======== THREAD %s: %s:%s (rep: %d)" % args
|
119
|
-
|
120
|
-
Benelux.add_thread_tags :rep => rep
|
121
|
-
#Stella.stdout.info [package.client.gibbler.shorter, package.usecase.gibbler.shorter, rep].inspect
|
122
|
-
Stella::Engine::Load.rescue(c.id) {
|
123
|
-
break if Stella.abort?
|
124
|
-
print '.' if Stella.stdout.lev == 2
|
125
|
-
stats = c.execute uc
|
126
|
-
}
|
127
|
-
Benelux.remove_thread_tags :rep
|
128
|
-
|
129
|
-
Thread.current[:real_uctime].tick
|
130
|
-
time_elapsed = (Time.now - time_started).to_i
|
131
|
-
|
132
|
-
if (Time.now - prev_ptime).to_i >= testrun.granularity
|
133
|
-
prev_ptime, ruct = Time.now, Thread.current[:real_uctime]
|
134
|
-
if Stella.stdout.lev >= 2 && Thread.current == @threads.first
|
135
|
-
args = [time_elapsed.to_i, ruct.n, ruct.mean, ruct.sd]
|
136
|
-
Stella.stdout.info2 $/, "REAL UC TIME: %ds (reps: %d): %.4fs %.4f(SD)" % args
|
137
|
-
end
|
138
|
-
|
139
|
-
Thread.current.rotate_timeline
|
140
|
-
end
|
141
|
-
|
142
|
-
# If a duration was given, we make sure
|
143
|
-
# to run for only that amount of time.
|
144
|
-
if testrun.duration > 0
|
145
|
-
break if (time_elapsed+Thread.current[:real_uctime].mean) >= testrun.duration
|
146
|
-
redo if (time_elapsed+Thread.current[:real_uctime].mean) <= testrun.duration
|
147
|
-
end
|
148
|
-
}
|
149
|
-
|
150
|
-
Benelux.remove_thread_tags :usecase
|
151
|
-
|
152
|
-
pqueue << package # return the package to the queue
|
153
|
-
end
|
154
|
-
|
155
|
-
#p [testrun.arrival, 1/testrun.arrival]
|
156
|
-
|
157
|
-
unless testrun.arrival.nil? || testrun.arrival.to_f <= 0
|
158
|
-
# Create 1 second / users per second
|
159
|
-
args = [@threads.size, packages.size]
|
160
|
-
Stella.stdout.print 2, '+'
|
161
|
-
Stella.stdout.info3 $/, "-> NEW CLIENT: %s of %s" % args
|
162
|
-
sleep 1/testrun.arrival
|
163
|
-
end
|
164
|
-
|
165
|
-
}
|
166
|
-
|
167
|
-
repscalc = Benelux::Stats::Calculator.new
|
168
|
-
@threads.each { |t| t.join } # wait
|
169
|
-
@threads.each { |t| repscalc.sample(t[:real_reps]) }
|
170
|
-
@real_reps = repscalc.mean.to_i
|
171
|
-
|
172
|
-
|
173
|
-
#Stella.stdout.info "*** REPETITION #{@real_reps} of #{reps} ***"
|
174
|
-
|
175
|
-
Stella.stdout.info2 $/, $/
|
176
|
-
end
|
177
|
-
|
178
|
-
|
179
|
-
protected
|
180
|
-
class ThreadPackage
|
181
|
-
attr_accessor :index
|
182
|
-
attr_accessor :client
|
183
|
-
attr_accessor :usecase
|
184
|
-
def initialize(i, c, u)
|
185
|
-
@index, @client, @usecase = i, c, u
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def prepare_dumper(testrun)
|
190
|
-
hand = Stella::Hand.new(testrun.granularity, 2.seconds) do
|
191
|
-
Benelux.update_global_timeline
|
192
|
-
# @threads contains only stella clients
|
193
|
-
concurrency = @threads.select { |t| !t.status.nil? }.size
|
194
|
-
batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
|
195
|
-
testrun.add_sample batch, concurrency, timeline
|
196
|
-
testrun.log = [] unless testrun.has_log?
|
197
|
-
if testrun.log.size < testrun.logsize
|
198
|
-
tmp = Benelux.timeline.messages.filter(:kind => :log)
|
199
|
-
unless tmp.nil? || tmp.empty?
|
200
|
-
# grab only as many elements from the log as configured
|
201
|
-
testrun.log.push *tmp.first(testrun.logsize-testrun.log.size)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
testrun.save
|
205
|
-
@failog.info Benelux.timeline.messages.filter(:kind => :exception)
|
206
|
-
@failog.info Benelux.timeline.messages.filter(:kind => :timeout)
|
207
|
-
Benelux.timeline.clear if testrun.nostats
|
208
|
-
end
|
209
|
-
hand.finally do
|
210
|
-
testrun.end_time = Time.now.utc.to_i
|
211
|
-
testrun.save
|
212
|
-
end
|
213
|
-
hand
|
214
|
-
end
|
215
|
-
|
216
|
-
def generate_report(sumlog,testrun,test_time)
|
217
|
-
global_timeline = Benelux.timeline
|
218
|
-
global_stats = global_timeline.stats.group(:response_time).merge
|
219
|
-
if global_stats.n == 0
|
220
|
-
Stella.ld "No stats"
|
221
|
-
return
|
222
|
-
end
|
223
|
-
|
224
|
-
@sumlog.info " %-72s ".att(:reverse) % ["#{testrun.plan.desc} (#{testrun.plan.id.shorter})"]
|
225
|
-
testrun.plan.usecases.uniq.each_with_index do |uc,i|
|
226
|
-
|
227
|
-
# TODO: Create Ranges object, like Stats object
|
228
|
-
# global_timeline.ranges(:response_time)[:usecase => '1111']
|
229
|
-
# The following returns global response_time ranges.
|
230
|
-
requests = 0 #global_timeline.ranges(:response_time).size
|
231
|
-
|
232
|
-
desc = uc.desc || "Usecase ##{i+1} "
|
233
|
-
desc << " (#{uc.id.shorter}) "
|
234
|
-
str = ' ' << " %-66s %s %d%% ".bright.att(:reverse)
|
235
|
-
@sumlog.info str % [desc, '', uc.ratio_pretty]
|
236
|
-
uc.requests.each do |req|
|
237
|
-
filter = [uc.id, req.id]
|
238
|
-
desc = req.desc
|
239
|
-
@sumlog.info " %-72s ".bright % ["#{req.desc} (#{req.id.shorter})"]
|
240
|
-
@sumlog.info " %s" % [req.to_s]
|
241
|
-
|
242
|
-
Load.timers.each do |sname|
|
243
|
-
stats = global_timeline.stats.group(sname)[filter].merge
|
244
|
-
# Stella.stdout.info stats.inspect
|
245
|
-
str = ' %-30s %.3f <= ' << '%.3fs' << ' >= %.3f; %.3f(SD) %d(N)'
|
246
|
-
msg = str % [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n]
|
247
|
-
@sumlog.info msg
|
248
|
-
@sumlog.flush
|
249
|
-
end
|
250
|
-
@sumlog.info $/
|
251
|
-
end
|
252
|
-
|
253
|
-
@sumlog.info " Sub Total:".bright
|
254
|
-
|
255
|
-
stats = global_timeline.stats.group(:response_time)[uc.id].merge
|
256
|
-
failed = global_timeline.stats.group(:failed)[uc.id].merge
|
257
|
-
respgrp = global_timeline.stats.group(:execute_response_handler)[uc.id]
|
258
|
-
resst = respgrp.tag_values(:status)
|
259
|
-
|
260
|
-
Load.timers.each do |sname|
|
261
|
-
stats = global_timeline.stats.group(sname)[uc.id].merge
|
262
|
-
@sumlog.info ' %-30s %.3fs %.3f(SD)' % [sname, stats.mean, stats.sd]
|
263
|
-
@sumlog.flush
|
264
|
-
end
|
265
|
-
|
266
|
-
Load.counts.each do |sname|
|
267
|
-
stats = global_timeline.stats.group(sname)[uc.id].merge
|
268
|
-
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
269
|
-
@sumlog.flush
|
270
|
-
end
|
271
|
-
@sumlog.info $/
|
272
|
-
statusi = []
|
273
|
-
resst.each do |status|
|
274
|
-
size = respgrp[:status => status].size
|
275
|
-
statusi << "#{status}: #{size}"
|
276
|
-
end
|
277
|
-
@sumlog.info ' %-30s %d (%s)' % ['Total requests', stats.n, statusi.join(', ')]
|
278
|
-
@sumlog.info ' %-29s %d' % [:success, stats.n - failed.n]
|
279
|
-
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
280
|
-
|
281
|
-
@sumlog.info $/
|
282
|
-
end
|
283
|
-
|
284
|
-
@sumlog.info ' ' << " %-66s ".att(:reverse) % 'Total:'
|
285
|
-
@sumlog.flush
|
286
|
-
|
287
|
-
failed = global_timeline.stats.group(:failed)
|
288
|
-
respgrp = global_timeline.stats.group(:execute_response_handler)
|
289
|
-
resst = respgrp.tag_values(:status)
|
290
|
-
statusi = []
|
291
|
-
resst.each do |status|
|
292
|
-
size = respgrp[:status => status].size
|
293
|
-
statusi << [status, size]
|
294
|
-
end
|
295
|
-
|
296
|
-
Load.timers.each do |sname|
|
297
|
-
stats = global_timeline.stats.group(sname).merge
|
298
|
-
@sumlog.info ' %-30s %-.3fs %-.3f(SD)' % [sname, stats.mean, stats.sd]
|
299
|
-
@sumlog.flush
|
300
|
-
end
|
301
|
-
|
302
|
-
Load.counts.each do |sname|
|
303
|
-
stats = global_timeline.stats.group(sname).merge
|
304
|
-
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
305
|
-
@sumlog.flush
|
306
|
-
end
|
307
|
-
|
308
|
-
@sumlog.info $/
|
309
|
-
@sumlog.info ' %-30s %d' % ['Total requests', global_stats.n]
|
310
|
-
|
311
|
-
success = global_stats.n - failed.n
|
312
|
-
@sumlog.info ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
|
313
|
-
statusi.each do |pair|
|
314
|
-
@sumlog.info3 ' %-28s %s: %d' % ['', *pair]
|
315
|
-
end
|
316
|
-
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
317
|
-
|
318
|
-
@sumlog.flush
|
319
|
-
|
320
|
-
end
|
321
|
-
|
322
|
-
|
323
|
-
def calculate_usecase_clients(testrun)
|
324
|
-
counts = { :total => 0 }
|
325
|
-
testrun.plan.usecases.each_with_index do |usecase,i|
|
326
|
-
count = case testrun.clients
|
327
|
-
when 0..9
|
328
|
-
if (testrun.clients % testrun.plan.usecases.size > 0)
|
329
|
-
msg = "Client count (%d) does not evenly match usecase count (%d)"
|
330
|
-
raise Stella::WackyRatio, (msg % [testrun.clients, testrun.plan.usecases.size])
|
331
|
-
else
|
332
|
-
(testrun.clients / testrun.plan.usecases.size)
|
333
|
-
end
|
334
|
-
else
|
335
|
-
(testrun.clients * usecase.ratio).to_i
|
336
|
-
end
|
337
|
-
counts[usecase.id] = count
|
338
|
-
counts[:total] += count
|
339
|
-
end
|
340
|
-
counts
|
341
|
-
end
|
342
|
-
|
343
|
-
|
344
|
-
def build_thread_package(testrun, counts)
|
345
|
-
packages, pointer = Array.new(counts[:total]), 0
|
346
|
-
testrun.plan.usecases.each do |usecase|
|
347
|
-
count = counts[usecase.id]
|
348
|
-
Stella.ld "THREAD PACKAGE: #{usecase.desc} (#{pointer} + #{count})"
|
349
|
-
# Fill the thread_package with the contents of the block
|
350
|
-
packages.fill(pointer, count) do |index|
|
351
|
-
client = Stella::Client.new testrun.hosts.first, testrun.client_options
|
352
|
-
client.add_observer(self)
|
353
|
-
Stella.stdout.info4 "Created client #{client.id.short}"
|
354
|
-
ThreadPackage.new(index+1, client, usecase)
|
355
|
-
end
|
356
|
-
pointer += count
|
357
|
-
end
|
358
|
-
packages.compact # TODO: Why one nil element sometimes?
|
359
|
-
# Randomize so when ramping up load
|
360
|
-
# we get a mix of usecases.
|
361
|
-
packages.sort_by {rand}
|
362
|
-
end
|
363
|
-
|
364
|
-
|
365
|
-
def running_threads
|
366
|
-
@threads.select { |t| t.status } # non-false status are still running
|
367
|
-
end
|
368
|
-
|
369
|
-
def generate_runtime_report(testrun)
|
370
|
-
gt = Benelux.timeline
|
371
|
-
gstats = gt.stats.group(:response_time).merge
|
372
|
-
|
373
|
-
testrun.plan.usecases.uniq.each_with_index do |uc,i|
|
374
|
-
uc.requests.each do |req|
|
375
|
-
filter = [uc.id, req.id]
|
376
|
-
|
377
|
-
Load.timers.each do |sname|
|
378
|
-
stats = gt.stats.group(sname)[filter].merge
|
379
|
-
#Stella.stdout.info stats.inspect
|
380
|
-
puts [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n].join('; ')
|
381
|
-
end
|
382
|
-
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
|
-
end
|
387
|
-
|
388
|
-
def update_prepare_request(client_id, usecase, req, counter)
|
389
|
-
|
390
|
-
end
|
391
|
-
|
392
|
-
def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
|
393
|
-
if @opts[:with_content]
|
394
|
-
log = Stella::Engine::Log.new Time.now.to_f, container.unique_id, client_id,
|
395
|
-
'testplanid',
|
396
|
-
usecase.id, req.id,
|
397
|
-
req.http_method, container.status, uri.to_s,
|
398
|
-
params, container.response.request.header.dump,
|
399
|
-
container.response.header.dump,
|
400
|
-
container.response.body.dump
|
401
|
-
|
402
|
-
# Fix for no data, but why??
|
403
|
-
log.response_body = container.response.body.dump
|
404
|
-
Benelux.thread_timeline.add_message log, :status => container.status, :kind => :log
|
405
|
-
end
|
406
|
-
|
407
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
408
|
-
args.push usecase.id.shorter, req.id.shorter
|
409
|
-
args.push req.http_method, container.status, uri
|
410
|
-
args << params.to_a.collect { |el|
|
411
|
-
next if el[0].to_s == '__stella'
|
412
|
-
'%s=%s' % [el[0], el[1].to_s]
|
413
|
-
}.compact.join('&') # remove skipped params
|
414
|
-
args << headers.to_a.collect { |el|
|
415
|
-
next if el[0].to_s == 'X-Stella-ID'
|
416
|
-
'%s=%s' % el
|
417
|
-
}.compact.join('&') # remove skipped params
|
418
|
-
args << container.unique_id[0,10]
|
419
|
-
#Benelux.thread_timeline.add_message args.join('; '),
|
420
|
-
# :status => container.status,
|
421
|
-
# :kind => :request
|
422
|
-
args = [client_id.shorter, container.status, req.http_method, uri, params.inspect]
|
423
|
-
Stella.stdout.info3 ' Client-%s %3d %-6s %s %s' % args
|
424
|
-
|
425
|
-
end
|
426
|
-
|
427
|
-
def update_execute_response_handler(client_id, req, container)
|
428
|
-
end
|
429
|
-
|
430
|
-
def update_error_execute_response_handler(client_id, ex, req, container)
|
431
|
-
Benelux.thread_timeline.add_message ex.message, :kind => :exception
|
432
|
-
Benelux.thread_timeline.add_count :exception, 1
|
433
|
-
desc = "#{container.usecase.desc} > #{req.desc}"
|
434
|
-
if Stella.stdout.lev == 2
|
435
|
-
Stella.stdout.print 2, '.'.color(:red)
|
436
|
-
else
|
437
|
-
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
438
|
-
Stella.ld ex.backtrace
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
|
-
def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
|
443
|
-
Benelux.thread_timeline.add_message ex.message, :kind => :exception
|
444
|
-
Benelux.thread_timeline.add_count :exception, 1
|
445
|
-
desc = "#{usecase.desc} > #{req.desc}"
|
446
|
-
if Stella.stdout.lev == 2
|
447
|
-
Stella.stdout.print 2, '.'.color(:red)
|
448
|
-
else
|
449
|
-
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
450
|
-
Stella.ld ex.backtrace
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
|
-
def update_usecase_quit client_id, msg, req, container
|
455
|
-
Benelux.thread_timeline.add_count :quit, 1
|
456
|
-
Benelux.thread_timeline.add_message msg, :kind => :quit
|
457
|
-
Stella.stdout.info3 " Client-%s QUIT %s" % [client_id.shorter, msg]
|
458
|
-
end
|
459
|
-
|
460
|
-
def update_request_fail client_id, msg, req, container
|
461
|
-
Benelux.thread_timeline.add_count :failed, 1
|
462
|
-
Benelux.thread_timeline.add_message msg, :kind => :fail
|
463
|
-
Stella.stdout.info3 " Client-%s FAILED %s" % [client_id.shorter, msg]
|
464
|
-
end
|
465
|
-
|
466
|
-
def update_request_error client_id, msg, req, container
|
467
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
468
|
-
Benelux.thread_timeline.add_count :exception, 1
|
469
|
-
Benelux.thread_timeline.add_message msg, :kind => :exception
|
470
|
-
if Stella.stdout.lev >= 3
|
471
|
-
Stella.le ' Client-%s %s' % [client_id.shorter, ex.message]
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
def update_request_repeat client_id, counter, total, req, container
|
476
|
-
Stella.stdout.info3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
|
477
|
-
end
|
478
|
-
|
479
|
-
def update_follow_redirect client_id, ret, req, container
|
480
|
-
Stella.stdout.info3 " Client-%s FOLLOW %-53s" % [client_id.shorter, ret.uri]
|
481
|
-
end
|
482
|
-
|
483
|
-
def update_max_redirects client_id, counter, ret, req, container
|
484
|
-
Stella.stdout.info3 " Client-%s MAX REDIRECTS %s " % [client_id.shorter, counter]
|
485
|
-
end
|
486
|
-
|
487
|
-
def update_authenticate client_id, usecase, req, domain, user, pass
|
488
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
489
|
-
args.push usecase.id.shorter, req.id.shorter
|
490
|
-
args.push 'AUTH', domain, user, pass
|
491
|
-
Benelux.thread_timeline.add_message args.join('; '), :kind => :authentication
|
492
|
-
end
|
493
|
-
|
494
|
-
def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container, timeout)
|
495
|
-
msg = " Client-%s TIMEOUT(%.1f) %-53s" % [client_id.shorter, timeout, uri]
|
496
|
-
Stella.stdout.info3 msg
|
497
|
-
Benelux.thread_timeline.add_count :exception, 1
|
498
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
499
|
-
args.push [uri, 'TOUT', container.unique_id[0,10]]
|
500
|
-
Benelux.thread_timeline.add_message msg , :kind => :exception
|
501
|
-
end
|
502
|
-
|
503
|
-
def self.rescue(client_id, &blk)
|
504
|
-
blk.call
|
505
|
-
rescue => ex
|
506
|
-
Stella.le ' Error in Client-%s: %s' % [client_id.shorter, ex.message]
|
507
|
-
Stella.ld ex.backtrace
|
508
|
-
end
|
509
|
-
|
510
|
-
Benelux.add_timer Stella::Engine::Load, :build_thread_package
|
511
|
-
Benelux.add_timer Stella::Engine::Load, :generate_report
|
512
|
-
Benelux.add_timer Stella::Engine::Load, :execute_test_plan
|
513
|
-
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|