stella 0.8.2.002 → 0.8.2.003
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +2 -0
- data/VERSION.yml +1 -1
- data/lib/stella/cli.rb +6 -7
- data/lib/stella/data/http.rb +1 -1
- data/lib/stella/engine.rb +15 -3
- data/lib/stella/engine/functional.rb +4 -6
- data/lib/stella/engine/load.rb +410 -6
- data/stella.gemspec +2 -3
- data/tryouts/70_module_usage.rb +9 -4
- metadata +2 -3
- data/lib/stella/engine/loadbase.rb +0 -423
data/CHANGES.txt
CHANGED
@@ -24,6 +24,8 @@ STELLA, CHANGES
|
|
24
24
|
* CHANGE: Removed no-logging option
|
25
25
|
* CHANGE: Renamed Testrun#summary to Testrun#stats
|
26
26
|
* CHANGE: Pass entire URI when calling Testplan#new
|
27
|
+
* CHANGE: Engine objects are now classes
|
28
|
+
* CHANGE: Engine#run methods now return instance of Stella::Testrun
|
27
29
|
* ADDED: JSON statistics log (.stella/logs/latest/stats)
|
28
30
|
|
29
31
|
|
data/VERSION.yml
CHANGED
data/lib/stella/cli.rb
CHANGED
@@ -26,8 +26,9 @@ class Stella::CLI < Drydock::Command
|
|
26
26
|
opts[opt] = @global.send(opt) unless @global.send(opt).nil?
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
engine = Stella::Engine::Functional.new opts
|
30
|
+
testrun = engine.run @testplan
|
31
|
+
@exit_code = (testrun.stats[:summary][:failed].n == 0 ? 0 : 1)
|
31
32
|
end
|
32
33
|
|
33
34
|
def generate_valid?
|
@@ -47,11 +48,9 @@ class Stella::CLI < Drydock::Command
|
|
47
48
|
|
48
49
|
connect_service if @global.remote
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
@exit_code = (ret ? 0 : 1)
|
51
|
+
engine = Stella::Engine::Load.new opts
|
52
|
+
testrun = engine.run @testplan
|
53
|
+
@exit_code = (testrun.stats[:summary][:failed].n == 0 ? 0 : 1)
|
55
54
|
end
|
56
55
|
|
57
56
|
def example
|
data/lib/stella/data/http.rb
CHANGED
@@ -39,7 +39,7 @@ module Stella::Data::HTTP
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def initialize (method, uri_str, version="1.1", &definition)
|
42
|
-
@uri = uri_str
|
42
|
+
@uri = uri_str.to_s
|
43
43
|
@http_method, @http_version = method, version
|
44
44
|
@headers, @params, @response_handler = {}, {}, {}
|
45
45
|
@resources = {}
|
data/lib/stella/engine.rb
CHANGED
@@ -21,10 +21,18 @@ module Stella::Engine
|
|
21
21
|
field :response_headers
|
22
22
|
field :response_body
|
23
23
|
end
|
24
|
-
|
25
|
-
extend self
|
24
|
+
class Base
|
26
25
|
|
27
|
-
|
26
|
+
class << self
|
27
|
+
attr_accessor :timers, :counts
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :testrun, :logdir, :opts
|
31
|
+
|
32
|
+
def initialize(opts={})
|
33
|
+
@opts = opts
|
34
|
+
@logdir = nil
|
35
|
+
end
|
28
36
|
|
29
37
|
@@client_limit = 1000
|
30
38
|
|
@@ -84,6 +92,10 @@ module Stella::Engine
|
|
84
92
|
end
|
85
93
|
end
|
86
94
|
|
95
|
+
opts[:clients] &&= opts[:clients].to_i
|
96
|
+
opts[:duration] &&= opts[:duration].to_i
|
97
|
+
opts[:arrival] &&= opts[:arrival].to_f
|
98
|
+
opts[:repetitions] &&= opts[:repetitions].to_i
|
87
99
|
opts[:clients] = plan.usecases.size if opts[:clients] < plan.usecases.size
|
88
100
|
|
89
101
|
if opts[:clients] > @@client_limit
|
@@ -1,11 +1,9 @@
|
|
1
1
|
|
2
2
|
module Stella::Engine
|
3
|
-
|
4
|
-
extend Stella::Engine::Base
|
5
|
-
extend self
|
3
|
+
class Functional < Stella::Engine::Base
|
6
4
|
|
7
|
-
def run(plan
|
8
|
-
opts = process_options! plan, opts
|
5
|
+
def run(plan)
|
6
|
+
opts = process_options! plan, @opts
|
9
7
|
|
10
8
|
Stella.stdout.info2 "Hosts: " << opts[:hosts].join(', ') if !opts[:hosts].empty?
|
11
9
|
|
@@ -59,7 +57,7 @@ module Stella::Engine
|
|
59
57
|
@testrun.add_sample 1, 1, tt
|
60
58
|
end
|
61
59
|
|
62
|
-
@testrun
|
60
|
+
@testrun
|
63
61
|
end
|
64
62
|
|
65
63
|
|
data/lib/stella/engine/load.rb
CHANGED
@@ -1,9 +1,100 @@
|
|
1
|
-
require 'stella/engine/loadbase'
|
2
1
|
|
3
2
|
module Stella::Engine
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
class Load < Stella::Engine::Base
|
4
|
+
|
5
|
+
@timers = [:response_time]
|
6
|
+
@counts = [:response_content_size]
|
7
|
+
|
8
|
+
def run(plan)
|
9
|
+
opts = process_options! plan, @opts
|
10
|
+
@threads, @max_clients, @real_reps = [], 0, 0
|
11
|
+
|
12
|
+
@logdir = log_dir(plan)
|
13
|
+
latest = File.join(File.dirname(@logdir), 'latest')
|
14
|
+
Stella.stdout.info "Logging to #{@logdir}", $/
|
15
|
+
|
16
|
+
if Stella.sysinfo.os == :unix
|
17
|
+
File.unlink latest if File.exists? latest
|
18
|
+
FileUtils.ln_sf File.basename(@logdir), latest
|
19
|
+
end
|
20
|
+
|
21
|
+
@statlog_path = log_path(plan, 'stats')
|
22
|
+
@sumlog = Stella::Logger.new log_path(plan, 'summary')
|
23
|
+
@failog = Stella::Logger.new log_path(plan, 'exceptions')
|
24
|
+
|
25
|
+
Stella.stdout.add_template :head, ' %s: %s'
|
26
|
+
Stella.stdout.add_template :status, "#{$/}%s..."
|
27
|
+
|
28
|
+
if Stella.stdout.lev >= 2
|
29
|
+
Load.timers += [:socket_connect, :send_request, :first_byte, :receive_response]
|
30
|
+
Load.counts = [:request_header_size, :request_content_size]
|
31
|
+
Load.counts += [:response_headers_size, :response_content_size]
|
32
|
+
end
|
33
|
+
|
34
|
+
events = [Load.timers, Load.counts, :failed].flatten
|
35
|
+
@testrun = Stella::Testrun.new plan, events, opts
|
36
|
+
@testrun.mode = 'l'
|
37
|
+
|
38
|
+
if Stella::Engine.service
|
39
|
+
Stella::Engine.service.testplan_sync plan
|
40
|
+
Stella::Engine.service.testrun_create @testrun
|
41
|
+
Stella.stdout.head 'Testrun', @testrun.remote_digest
|
42
|
+
end
|
43
|
+
|
44
|
+
@testrun.save(@statlog_path)
|
45
|
+
|
46
|
+
@dumper = prepare_dumper(plan, opts)
|
47
|
+
|
48
|
+
counts = calculate_usecase_clients plan, opts
|
49
|
+
|
50
|
+
packages = build_thread_package plan, opts, counts
|
51
|
+
|
52
|
+
if opts[:duration] > 0
|
53
|
+
timing = "#{opts[:duration].seconds.to_i} seconds"
|
54
|
+
else
|
55
|
+
timing = "#{opts[:repetitions]} repetitions"
|
56
|
+
end
|
57
|
+
|
58
|
+
Stella.stdout.head 'Plan', "#{plan.desc} (#{plan.digest.shorter})"
|
59
|
+
Stella.stdout.head 'Hosts', opts[:hosts].join(', ')
|
60
|
+
Stella.stdout.head 'Clients', counts[:total]
|
61
|
+
Stella.stdout.head 'Limit', timing
|
62
|
+
|
63
|
+
Stella.stdout.head 'Arrival', opts[:arrival] if opts[:arrival]
|
64
|
+
|
65
|
+
@dumper.start
|
66
|
+
|
67
|
+
begin
|
68
|
+
Stella.stdout.status "Running"
|
69
|
+
execute_test_plan packages, opts[:repetitions], opts[:duration], opts[:arrival]
|
70
|
+
rescue Interrupt
|
71
|
+
Stella.stdout.info $/, "Stopping test"
|
72
|
+
Stella.abort!
|
73
|
+
@threads.each { |t| t.join } unless @threads.nil? || @threads.empty? # wait
|
74
|
+
rescue => ex
|
75
|
+
STDERR.puts "Unhandled exception: #{ex.message}"
|
76
|
+
STDERR.puts ex.backtrace if Stella.debug? || Stella.stdout.lev >= 3
|
77
|
+
end
|
78
|
+
|
79
|
+
Stella.stdout.status "Processing"
|
80
|
+
|
81
|
+
@dumper.stop
|
82
|
+
|
83
|
+
bt = Benelux.timeline
|
84
|
+
tt = Benelux.thread_timeline
|
85
|
+
|
86
|
+
# TODO: don't get test time from benelux.
|
87
|
+
test_time = tt.stats.group(:execute_test_plan).mean
|
88
|
+
generate_report @sumlog, plan, test_time
|
89
|
+
#report_time = tt.stats.group(:generate_report).mean
|
90
|
+
|
91
|
+
Stella.stdout.info File.read(@sumlog.path)
|
92
|
+
|
93
|
+
Stella.stdout.info $/, "Log dir: #{@logdir}"
|
94
|
+
|
95
|
+
@testrun
|
96
|
+
end
|
97
|
+
|
7
98
|
ROTATE_TIMELINE = 5
|
8
99
|
def execute_test_plan(packages, reps=1,duration=0,arrival=nil)
|
9
100
|
time_started = Time.now
|
@@ -90,7 +181,320 @@ module Stella::Engine
|
|
90
181
|
Stella.stdout.info2 $/, $/
|
91
182
|
end
|
92
183
|
|
93
|
-
Benelux.add_timer Stella::Engine::Load, :execute_test_plan
|
94
184
|
|
185
|
+
protected
|
186
|
+
class ThreadPackage
|
187
|
+
attr_accessor :index
|
188
|
+
attr_accessor :client
|
189
|
+
attr_accessor :usecase
|
190
|
+
def initialize(i, c, u)
|
191
|
+
@index, @client, @usecase = i, c, u
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def prepare_dumper(plan, opts)
|
196
|
+
hand = Stella::Hand.new(Load::ROTATE_TIMELINE, 2.seconds) do
|
197
|
+
Benelux.update_global_timeline
|
198
|
+
# @threads contains only stella clients
|
199
|
+
concurrency = @threads.select { |t| !t.status.nil? }.size
|
200
|
+
batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
|
201
|
+
@testrun.add_sample batch, concurrency, timeline
|
202
|
+
@testrun.save(@statlog_path)
|
203
|
+
@failog.info Benelux.timeline.messages.filter(:kind => :exception)
|
204
|
+
@failog.info Benelux.timeline.messages.filter(:kind => :timeout)
|
205
|
+
Benelux.timeline.clear if opts[:"no-stats"]
|
206
|
+
end
|
207
|
+
hand.finally do
|
208
|
+
@testrun.save(@statlog_path)
|
209
|
+
end
|
210
|
+
hand
|
211
|
+
end
|
212
|
+
|
213
|
+
def generate_report(sumlog,plan,test_time)
|
214
|
+
global_timeline = Benelux.timeline
|
215
|
+
global_stats = global_timeline.stats.group(:response_time).merge
|
216
|
+
if global_stats.n == 0
|
217
|
+
Stella.ld "No stats"
|
218
|
+
return
|
219
|
+
end
|
220
|
+
|
221
|
+
@sumlog.info " %-72s ".att(:reverse) % ["#{plan.desc} (#{plan.digest_cache.shorter})"]
|
222
|
+
plan.usecases.uniq.each_with_index do |uc,i|
|
223
|
+
|
224
|
+
# TODO: Create Ranges object, like Stats object
|
225
|
+
# global_timeline.ranges(:response_time)[:usecase => '1111']
|
226
|
+
# The following returns global response_time ranges.
|
227
|
+
requests = 0 #global_timeline.ranges(:response_time).size
|
228
|
+
|
229
|
+
desc = uc.desc || "Usecase ##{i+1} "
|
230
|
+
desc << " (#{uc.digest_cache.shorter}) "
|
231
|
+
str = ' ' << " %-66s %s %d%% ".bright.att(:reverse)
|
232
|
+
@sumlog.info str % [desc, '', uc.ratio_pretty]
|
233
|
+
uc.requests.each do |req|
|
234
|
+
filter = [uc.digest_cache, req.digest_cache]
|
235
|
+
desc = req.desc
|
236
|
+
@sumlog.info " %-72s ".bright % ["#{req.desc} (#{req.digest_cache.shorter})"]
|
237
|
+
@sumlog.info " %s" % [req.to_s]
|
238
|
+
|
239
|
+
Load.timers.each do |sname|
|
240
|
+
stats = global_timeline.stats.group(sname)[filter].merge
|
241
|
+
# Stella.stdout.info stats.inspect
|
242
|
+
str = ' %-30s %.3f <= ' << '%.3fs' << ' >= %.3f; %.3f(SD) %d(N)'
|
243
|
+
msg = str % [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n]
|
244
|
+
@sumlog.info msg
|
245
|
+
@sumlog.flush
|
246
|
+
end
|
247
|
+
@sumlog.info $/
|
248
|
+
end
|
249
|
+
|
250
|
+
@sumlog.info " Sub Total:".bright
|
251
|
+
|
252
|
+
stats = global_timeline.stats.group(:response_time)[uc.digest_cache].merge
|
253
|
+
failed = global_timeline.stats.group(:failed)[uc.digest_cache].merge
|
254
|
+
respgrp = global_timeline.stats.group(:execute_response_handler)[uc.digest_cache]
|
255
|
+
resst = respgrp.tag_values(:status)
|
256
|
+
|
257
|
+
Load.timers.each do |sname|
|
258
|
+
stats = global_timeline.stats.group(sname)[uc.digest_cache].merge
|
259
|
+
@sumlog.info ' %-30s %.3fs %.3f(SD)' % [sname, stats.mean, stats.sd]
|
260
|
+
@sumlog.flush
|
261
|
+
end
|
262
|
+
|
263
|
+
Load.counts.each do |sname|
|
264
|
+
stats = global_timeline.stats.group(sname)[uc.digest_cache].merge
|
265
|
+
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
266
|
+
@sumlog.flush
|
267
|
+
end
|
268
|
+
@sumlog.info $/
|
269
|
+
statusi = []
|
270
|
+
resst.each do |status|
|
271
|
+
size = respgrp[:status => status].size
|
272
|
+
statusi << "#{status}: #{size}"
|
273
|
+
end
|
274
|
+
@sumlog.info ' %-30s %d (%s)' % ['Total requests', stats.n, statusi.join(', ')]
|
275
|
+
@sumlog.info ' %-29s %d' % [:success, stats.n - failed.n]
|
276
|
+
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
277
|
+
|
278
|
+
@sumlog.info $/
|
279
|
+
end
|
280
|
+
|
281
|
+
@sumlog.info ' ' << " %-66s ".att(:reverse) % 'Total:'
|
282
|
+
@sumlog.flush
|
283
|
+
|
284
|
+
failed = global_timeline.stats.group(:failed)
|
285
|
+
respgrp = global_timeline.stats.group(:execute_response_handler)
|
286
|
+
resst = respgrp.tag_values(:status)
|
287
|
+
statusi = []
|
288
|
+
resst.each do |status|
|
289
|
+
size = respgrp[:status => status].size
|
290
|
+
statusi << [status, size]
|
291
|
+
end
|
292
|
+
|
293
|
+
Load.timers.each do |sname|
|
294
|
+
stats = global_timeline.stats.group(sname).merge
|
295
|
+
@sumlog.info ' %-30s %-.3fs %-.3f(SD)' % [sname, stats.mean, stats.sd]
|
296
|
+
@sumlog.flush
|
297
|
+
end
|
298
|
+
|
299
|
+
Load.counts.each do |sname|
|
300
|
+
stats = global_timeline.stats.group(sname).merge
|
301
|
+
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
302
|
+
@sumlog.flush
|
303
|
+
end
|
304
|
+
|
305
|
+
@sumlog.info $/
|
306
|
+
@sumlog.info ' %-30s %d' % ['Total requests', global_stats.n]
|
307
|
+
|
308
|
+
success = global_stats.n - failed.n
|
309
|
+
@sumlog.info ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
|
310
|
+
statusi.each do |pair|
|
311
|
+
@sumlog.info3 ' %-28s %s: %d' % ['', *pair]
|
312
|
+
end
|
313
|
+
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
314
|
+
|
315
|
+
@sumlog.flush
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
|
320
|
+
def calculate_usecase_clients(plan, opts)
|
321
|
+
counts = { :total => 0 }
|
322
|
+
plan.usecases.each_with_index do |usecase,i|
|
323
|
+
count = case opts[:clients]
|
324
|
+
when 0..9
|
325
|
+
if (opts[:clients] % plan.usecases.size > 0)
|
326
|
+
msg = "Client count does not evenly match usecase count"
|
327
|
+
raise Stella::WackyRatio, msg
|
328
|
+
else
|
329
|
+
(opts[:clients] / plan.usecases.size)
|
330
|
+
end
|
331
|
+
else
|
332
|
+
(opts[:clients] * usecase.ratio).to_i
|
333
|
+
end
|
334
|
+
counts[usecase.digest_cache] = count
|
335
|
+
counts[:total] += count
|
336
|
+
end
|
337
|
+
counts
|
338
|
+
end
|
339
|
+
|
340
|
+
|
341
|
+
def build_thread_package(plan, opts, counts)
|
342
|
+
packages, pointer = Array.new(counts[:total]), 0
|
343
|
+
plan.usecases.each do |usecase|
|
344
|
+
count = counts[usecase.digest_cache]
|
345
|
+
Stella.ld "THREAD PACKAGE: #{usecase.desc} (#{pointer} + #{count})"
|
346
|
+
# Fill the thread_package with the contents of the block
|
347
|
+
packages.fill(pointer, count) do |index|
|
348
|
+
client = Stella::Client.new opts[:hosts].first, index+1, opts
|
349
|
+
client.add_observer(self)
|
350
|
+
client.enable_nowait_mode if opts[:nowait]
|
351
|
+
Stella.stdout.info4 "Created client #{client.digest.short}"
|
352
|
+
ThreadPackage.new(index+1, client, usecase)
|
353
|
+
end
|
354
|
+
pointer += count
|
355
|
+
end
|
356
|
+
packages.compact # TODO: Why one nil element sometimes?
|
357
|
+
# Randomize so when ramping up load
|
358
|
+
# we get a mix of usecases.
|
359
|
+
packages.sort_by {rand}
|
360
|
+
end
|
361
|
+
|
362
|
+
|
363
|
+
def running_threads
|
364
|
+
@threads.select { |t| t.status } # non-false status are still running
|
365
|
+
end
|
366
|
+
|
367
|
+
def generate_runtime_report(plan)
|
368
|
+
gt = Benelux.timeline
|
369
|
+
gstats = gt.stats.group(:response_time).merge
|
370
|
+
|
371
|
+
plan.usecases.uniq.each_with_index do |uc,i|
|
372
|
+
uc.requests.each do |req|
|
373
|
+
filter = [uc.digest_cache, req.digest_cache]
|
374
|
+
|
375
|
+
Load.timers.each do |sname|
|
376
|
+
stats = gt.stats.group(sname)[filter].merge
|
377
|
+
#Stella.stdout.info stats.inspect
|
378
|
+
puts [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n].join('; ')
|
379
|
+
end
|
380
|
+
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
end
|
385
|
+
|
386
|
+
def update_prepare_request(client_id, usecase, req, counter)
|
387
|
+
|
388
|
+
end
|
389
|
+
|
390
|
+
def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
|
391
|
+
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
392
|
+
args.push usecase.digest.shorter, req.digest.shorter
|
393
|
+
args.push req.http_method, container.status, uri
|
394
|
+
args << params.to_a.collect { |el|
|
395
|
+
next if el[0].to_s == '__stella'
|
396
|
+
'%s=%s' % [el[0], el[1].to_s]
|
397
|
+
}.compact.join('&') # remove skipped params
|
398
|
+
args << headers.to_a.collect { |el|
|
399
|
+
next if el[0].to_s == 'X-Stella-ID'
|
400
|
+
'%s=%s' % el
|
401
|
+
}.compact.join('&') # remove skipped params
|
402
|
+
args << container.unique_id[0,10]
|
403
|
+
#Benelux.thread_timeline.add_message args.join('; '),
|
404
|
+
# :status => container.status,
|
405
|
+
# :kind => :request
|
406
|
+
args = [client_id.shorter, container.status, req.http_method, uri, params.inspect]
|
407
|
+
Stella.stdout.info3 ' Client-%s %3d %-6s %s %s' % args
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
def update_execute_response_handler(client_id, req, container)
|
412
|
+
end
|
413
|
+
|
414
|
+
def update_error_execute_response_handler(client_id, ex, req, container)
|
415
|
+
desc = "#{container.usecase.desc} > #{req.desc}"
|
416
|
+
if Stella.stdout.lev == 2
|
417
|
+
Stella.stdout.print 2, '.'.color(:red)
|
418
|
+
else
|
419
|
+
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
420
|
+
Stella.ld ex.backtrace
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
|
425
|
+
desc = "#{usecase.desc} > #{req.desc}"
|
426
|
+
if Stella.stdout.lev == 2
|
427
|
+
Stella.stdout.print 2, '.'.color(:red)
|
428
|
+
else
|
429
|
+
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
430
|
+
Stella.ld ex.backtrace
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def update_usecase_quit client_id, msg, req, container
|
435
|
+
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
436
|
+
Benelux.thread_timeline.add_count :quit, 1
|
437
|
+
args.push [req, container.status, 'QUIT', msg, container.unique_id[0,10]]
|
438
|
+
Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
|
439
|
+
Stella.stdout.info3 " Client-%s QUIT %s" % [client_id.shorter, msg]
|
440
|
+
end
|
441
|
+
|
442
|
+
def update_request_fail client_id, msg, req, container
|
443
|
+
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
444
|
+
Benelux.thread_timeline.add_count :failed, 1
|
445
|
+
args.push [req, container.status, 'FAIL', msg, container.unique_id[0,10]]
|
446
|
+
Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
|
447
|
+
Stella.stdout.info3 " Client-%s FAILED %s" % [client_id.shorter, msg]
|
448
|
+
end
|
449
|
+
|
450
|
+
def update_request_error client_id, msg, req, container
|
451
|
+
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
452
|
+
Benelux.thread_timeline.add_count :error, 1
|
453
|
+
args.push [req, container.status, 'ERROR', msg, container.unique_id[0,10]]
|
454
|
+
Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
|
455
|
+
if Stella.stdout.lev >= 3
|
456
|
+
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def update_request_repeat client_id, counter, total, req, container
|
461
|
+
Stella.stdout.info3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
|
462
|
+
end
|
463
|
+
|
464
|
+
def update_follow_redirect client_id, ret, req, container
|
465
|
+
Stella.stdout.info3 " Client-%s FOLLOW %-53s" % [client_id.shorter, ret.uri]
|
466
|
+
end
|
467
|
+
|
468
|
+
def update_max_redirects client_id, counter, ret, req, container
|
469
|
+
Stella.stdout.info3 " Client-%s MAX REDIRECTS %s " % [client_id.shorter, counter]
|
470
|
+
end
|
471
|
+
|
472
|
+
def update_authenticate client_id, usecase, req, domain, user, pass
|
473
|
+
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
474
|
+
args.push usecase.digest.shorter, req.digest.shorter
|
475
|
+
args.push 'AUTH', domain, user, pass
|
476
|
+
Benelux.thread_timeline.add_message args.join('; '), :kind => :authentication
|
477
|
+
end
|
478
|
+
|
479
|
+
def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container)
|
480
|
+
Stella.stdout.info3 " Client-%s TIMEOUT %-53s" % [client_id.shorter, uri]
|
481
|
+
Benelux.thread_timeline.add_count :failed, 1
|
482
|
+
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
483
|
+
args.push [uri, 'TOUT', container.unique_id[0,10]]
|
484
|
+
Benelux.thread_timeline.add_message args.join('; '), :kind => :timeout
|
485
|
+
end
|
486
|
+
|
487
|
+
def self.rescue(client_id, &blk)
|
488
|
+
blk.call
|
489
|
+
rescue => ex
|
490
|
+
Stella.le ' Error in Client-%s: %s' % [client_id.shorter, ex.message]
|
491
|
+
Stella.ld ex.backtrace
|
492
|
+
end
|
493
|
+
|
494
|
+
Benelux.add_timer Stella::Engine::Load, :build_thread_package
|
495
|
+
Benelux.add_timer Stella::Engine::Load, :generate_report
|
496
|
+
Benelux.add_timer Stella::Engine::Load, :execute_test_plan
|
497
|
+
|
95
498
|
end
|
96
|
-
end
|
499
|
+
end
|
500
|
+
|
data/stella.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{stella}
|
8
|
-
s.version = "0.8.2.
|
8
|
+
s.version = "0.8.2.003"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Delano Mandelbaum"]
|
12
|
-
s.date = %q{2010-03-
|
12
|
+
s.date = %q{2010-03-06}
|
13
13
|
s.default_executable = %q{stella}
|
14
14
|
s.description = %q{Blame Stella for breaking your web application!}
|
15
15
|
s.email = %q{delano@solutious.com}
|
@@ -49,7 +49,6 @@ Gem::Specification.new do |s|
|
|
49
49
|
"lib/stella/engine.rb",
|
50
50
|
"lib/stella/engine/functional.rb",
|
51
51
|
"lib/stella/engine/load.rb",
|
52
|
-
"lib/stella/engine/loadbase.rb",
|
53
52
|
"lib/stella/guidelines.rb",
|
54
53
|
"lib/stella/logger.rb",
|
55
54
|
"lib/stella/service.rb",
|
data/tryouts/70_module_usage.rb
CHANGED
@@ -2,14 +2,19 @@
|
|
2
2
|
|
3
3
|
require 'stella'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
Benelux.enable_debug
|
6
|
+
|
7
|
+
Stella.enable_quiet
|
8
|
+
#Stella.stdout.lev = 3
|
7
9
|
plan = Stella::Testplan.new('http://localhost:3114/search')
|
8
10
|
opts = {
|
9
11
|
:hosts => '',
|
10
12
|
:clients => 100,
|
11
13
|
#:duration => 10
|
12
14
|
}
|
13
|
-
Stella::Engine::Load.run plan, opts
|
14
15
|
|
15
|
-
|
16
|
+
#engine = Stella::Engine::Functional.new opts
|
17
|
+
engine = Stella::Engine::Load.new opts
|
18
|
+
engine.run plan
|
19
|
+
|
20
|
+
puts engine.testrun.stats[:summary].to_json
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stella
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.2.
|
4
|
+
version: 0.8.2.003
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-03-
|
12
|
+
date: 2010-03-06 00:00:00 -05:00
|
13
13
|
default_executable: stella
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -112,7 +112,6 @@ files:
|
|
112
112
|
- lib/stella/engine.rb
|
113
113
|
- lib/stella/engine/functional.rb
|
114
114
|
- lib/stella/engine/load.rb
|
115
|
-
- lib/stella/engine/loadbase.rb
|
116
115
|
- lib/stella/guidelines.rb
|
117
116
|
- lib/stella/logger.rb
|
118
117
|
- lib/stella/service.rb
|
@@ -1,423 +0,0 @@
|
|
1
|
-
|
2
|
-
module Stella::Engine
|
3
|
-
module Load
|
4
|
-
extend Stella::Engine::Base
|
5
|
-
extend self
|
6
|
-
|
7
|
-
@timers = [:response_time]
|
8
|
-
@counts = [:response_content_size]
|
9
|
-
@reqlog = nil
|
10
|
-
@logdir = nil
|
11
|
-
|
12
|
-
class << self
|
13
|
-
attr_accessor :timers, :counts, :logdir, :testrun
|
14
|
-
end
|
15
|
-
|
16
|
-
def run(plan, opts={})
|
17
|
-
opts = process_options! plan, opts
|
18
|
-
@threads, @max_clients, @real_reps = [], 0, 0
|
19
|
-
|
20
|
-
@logdir = log_dir(plan)
|
21
|
-
latest = File.join(File.dirname(@logdir), 'latest')
|
22
|
-
Stella.stdout.info "Logging to #{@logdir}", $/
|
23
|
-
|
24
|
-
if Stella.sysinfo.os == :unix
|
25
|
-
File.unlink latest if File.exists? latest
|
26
|
-
FileUtils.ln_sf File.basename(@logdir), latest
|
27
|
-
end
|
28
|
-
|
29
|
-
@statlog_path = log_path(plan, 'stats')
|
30
|
-
@sumlog = Stella::Logger.new log_path(plan, 'summary')
|
31
|
-
@failog = Stella::Logger.new log_path(plan, 'exceptions')
|
32
|
-
|
33
|
-
Stella.stdout.add_template :head, ' %s: %s'
|
34
|
-
Stella.stdout.add_template :status, "#{$/}%s..."
|
35
|
-
|
36
|
-
if Stella.stdout.lev >= 2
|
37
|
-
Load.timers += [:socket_connect, :send_request, :first_byte, :receive_response]
|
38
|
-
Load.counts = [:request_header_size, :request_content_size]
|
39
|
-
Load.counts += [:response_headers_size, :response_content_size]
|
40
|
-
end
|
41
|
-
|
42
|
-
events = [Load.timers, Load.counts, :failed].flatten
|
43
|
-
@testrun = Stella::Testrun.new plan, events, opts
|
44
|
-
@testrun.mode = 'l'
|
45
|
-
|
46
|
-
if Stella::Engine.service
|
47
|
-
Stella::Engine.service.testplan_sync plan
|
48
|
-
Stella::Engine.service.testrun_create @testrun
|
49
|
-
Stella.stdout.head 'Testrun', @testrun.remote_digest
|
50
|
-
end
|
51
|
-
|
52
|
-
@testrun.save(@statlog_path)
|
53
|
-
|
54
|
-
@dumper = prepare_dumper(plan, opts)
|
55
|
-
|
56
|
-
counts = calculate_usecase_clients plan, opts
|
57
|
-
|
58
|
-
packages = build_thread_package plan, opts, counts
|
59
|
-
|
60
|
-
if opts[:duration] > 0
|
61
|
-
timing = "#{opts[:duration].seconds.to_i} seconds"
|
62
|
-
else
|
63
|
-
timing = "#{opts[:repetitions]} repetitions"
|
64
|
-
end
|
65
|
-
|
66
|
-
Stella.stdout.head 'Plan', "#{plan.desc} (#{plan.digest.shorter})"
|
67
|
-
Stella.stdout.head 'Hosts', opts[:hosts].join(', ')
|
68
|
-
Stella.stdout.head 'Clients', counts[:total]
|
69
|
-
Stella.stdout.head 'Limit', timing
|
70
|
-
|
71
|
-
Stella.stdout.head 'Arrival', opts[:arrival] if opts[:arrival]
|
72
|
-
|
73
|
-
@dumper.start
|
74
|
-
|
75
|
-
begin
|
76
|
-
Stella.stdout.status "Running"
|
77
|
-
execute_test_plan packages, opts[:repetitions], opts[:duration], opts[:arrival]
|
78
|
-
rescue Interrupt
|
79
|
-
Stella.stdout.info $/, "Stopping test"
|
80
|
-
Stella.abort!
|
81
|
-
@threads.each { |t| t.join } unless @threads.nil? || @threads.empty? # wait
|
82
|
-
rescue => ex
|
83
|
-
STDERR.puts "Unhandled exception: #{ex.message}"
|
84
|
-
STDERR.puts ex.backtrace if Stella.debug? || Stella.stdout.lev >= 3
|
85
|
-
end
|
86
|
-
|
87
|
-
Stella.stdout.status "Processing"
|
88
|
-
|
89
|
-
@dumper.stop
|
90
|
-
|
91
|
-
bt = Benelux.timeline
|
92
|
-
tt = Benelux.thread_timeline
|
93
|
-
|
94
|
-
# TODO: don't get test time from benelux.
|
95
|
-
test_time = tt.stats.group(:execute_test_plan).mean
|
96
|
-
generate_report @sumlog, plan, test_time
|
97
|
-
#report_time = tt.stats.group(:generate_report).mean
|
98
|
-
|
99
|
-
Stella.stdout.info File.read(@sumlog.path)
|
100
|
-
|
101
|
-
Stella.stdout.info $/, "Log dir: #{@logdir}"
|
102
|
-
|
103
|
-
@testrun.stats[:summary][:failed].n == 0
|
104
|
-
end
|
105
|
-
|
106
|
-
protected
|
107
|
-
class ThreadPackage
|
108
|
-
attr_accessor :index
|
109
|
-
attr_accessor :client
|
110
|
-
attr_accessor :usecase
|
111
|
-
def initialize(i, c, u)
|
112
|
-
@index, @client, @usecase = i, c, u
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def prepare_dumper(plan, opts)
|
117
|
-
hand = Stella::Hand.new(Load::ROTATE_TIMELINE, 2.seconds) do
|
118
|
-
Benelux.update_global_timeline
|
119
|
-
# @threads contains only stella clients
|
120
|
-
concurrency = @threads.select { |t| !t.status.nil? }.size
|
121
|
-
batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
|
122
|
-
@testrun.add_sample batch, concurrency, timeline
|
123
|
-
@testrun.save(@statlog_path)
|
124
|
-
@failog.info Benelux.timeline.messages.filter(:kind => :exception)
|
125
|
-
@failog.info Benelux.timeline.messages.filter(:kind => :timeout)
|
126
|
-
Benelux.timeline.clear if opts[:"no-stats"]
|
127
|
-
end
|
128
|
-
hand.finally do
|
129
|
-
@testrun.save(@statlog_path)
|
130
|
-
end
|
131
|
-
hand
|
132
|
-
end
|
133
|
-
|
134
|
-
def generate_report(sumlog,plan,test_time)
|
135
|
-
global_timeline = Benelux.timeline
|
136
|
-
global_stats = global_timeline.stats.group(:response_time).merge
|
137
|
-
if global_stats.n == 0
|
138
|
-
Stella.ld "No stats"
|
139
|
-
return
|
140
|
-
end
|
141
|
-
|
142
|
-
@sumlog.info " %-72s ".att(:reverse) % ["#{plan.desc} (#{plan.digest_cache.shorter})"]
|
143
|
-
plan.usecases.uniq.each_with_index do |uc,i|
|
144
|
-
|
145
|
-
# TODO: Create Ranges object, like Stats object
|
146
|
-
# global_timeline.ranges(:response_time)[:usecase => '1111']
|
147
|
-
# The following returns global response_time ranges.
|
148
|
-
requests = 0 #global_timeline.ranges(:response_time).size
|
149
|
-
|
150
|
-
desc = uc.desc || "Usecase ##{i+1} "
|
151
|
-
desc << " (#{uc.digest_cache.shorter}) "
|
152
|
-
str = ' ' << " %-66s %s %d%% ".bright.att(:reverse)
|
153
|
-
@sumlog.info str % [desc, '', uc.ratio_pretty]
|
154
|
-
uc.requests.each do |req|
|
155
|
-
filter = [uc.digest_cache, req.digest_cache]
|
156
|
-
desc = req.desc
|
157
|
-
@sumlog.info " %-72s ".bright % ["#{req.desc} (#{req.digest_cache.shorter})"]
|
158
|
-
@sumlog.info " %s" % [req.to_s]
|
159
|
-
|
160
|
-
Load.timers.each do |sname|
|
161
|
-
stats = global_timeline.stats.group(sname)[filter].merge
|
162
|
-
# Stella.stdout.info stats.inspect
|
163
|
-
str = ' %-30s %.3f <= ' << '%.3fs' << ' >= %.3f; %.3f(SD) %d(N)'
|
164
|
-
msg = str % [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n]
|
165
|
-
@sumlog.info msg
|
166
|
-
@sumlog.flush
|
167
|
-
end
|
168
|
-
@sumlog.info $/
|
169
|
-
end
|
170
|
-
|
171
|
-
@sumlog.info " Sub Total:".bright
|
172
|
-
|
173
|
-
stats = global_timeline.stats.group(:response_time)[uc.digest_cache].merge
|
174
|
-
failed = global_timeline.stats.group(:failed)[uc.digest_cache].merge
|
175
|
-
respgrp = global_timeline.stats.group(:execute_response_handler)[uc.digest_cache]
|
176
|
-
resst = respgrp.tag_values(:status)
|
177
|
-
|
178
|
-
Load.timers.each do |sname|
|
179
|
-
stats = global_timeline.stats.group(sname)[uc.digest_cache].merge
|
180
|
-
@sumlog.info ' %-30s %.3fs %.3f(SD)' % [sname, stats.mean, stats.sd]
|
181
|
-
@sumlog.flush
|
182
|
-
end
|
183
|
-
|
184
|
-
Load.counts.each do |sname|
|
185
|
-
stats = global_timeline.stats.group(sname)[uc.digest_cache].merge
|
186
|
-
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
187
|
-
@sumlog.flush
|
188
|
-
end
|
189
|
-
@sumlog.info $/
|
190
|
-
statusi = []
|
191
|
-
resst.each do |status|
|
192
|
-
size = respgrp[:status => status].size
|
193
|
-
statusi << "#{status}: #{size}"
|
194
|
-
end
|
195
|
-
@sumlog.info ' %-30s %d (%s)' % ['Total requests', stats.n, statusi.join(', ')]
|
196
|
-
@sumlog.info ' %-29s %d' % [:success, stats.n - failed.n]
|
197
|
-
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
198
|
-
|
199
|
-
@sumlog.info $/
|
200
|
-
end
|
201
|
-
|
202
|
-
@sumlog.info ' ' << " %-66s ".att(:reverse) % 'Total:'
|
203
|
-
@sumlog.flush
|
204
|
-
|
205
|
-
failed = global_timeline.stats.group(:failed)
|
206
|
-
respgrp = global_timeline.stats.group(:execute_response_handler)
|
207
|
-
resst = respgrp.tag_values(:status)
|
208
|
-
statusi = []
|
209
|
-
resst.each do |status|
|
210
|
-
size = respgrp[:status => status].size
|
211
|
-
statusi << [status, size]
|
212
|
-
end
|
213
|
-
|
214
|
-
Load.timers.each do |sname|
|
215
|
-
stats = global_timeline.stats.group(sname).merge
|
216
|
-
@sumlog.info ' %-30s %-.3fs %-.3f(SD)' % [sname, stats.mean, stats.sd]
|
217
|
-
@sumlog.flush
|
218
|
-
end
|
219
|
-
|
220
|
-
Load.counts.each do |sname|
|
221
|
-
stats = global_timeline.stats.group(sname).merge
|
222
|
-
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
223
|
-
@sumlog.flush
|
224
|
-
end
|
225
|
-
|
226
|
-
@sumlog.info $/
|
227
|
-
@sumlog.info ' %-30s %d' % ['Total requests', global_stats.n]
|
228
|
-
|
229
|
-
success = global_stats.n - failed.n
|
230
|
-
@sumlog.info ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
|
231
|
-
statusi.each do |pair|
|
232
|
-
@sumlog.info3 ' %-28s %s: %d' % ['', *pair]
|
233
|
-
end
|
234
|
-
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
235
|
-
|
236
|
-
@sumlog.flush
|
237
|
-
|
238
|
-
end
|
239
|
-
|
240
|
-
|
241
|
-
def calculate_usecase_clients(plan, opts)
|
242
|
-
counts = { :total => 0 }
|
243
|
-
plan.usecases.each_with_index do |usecase,i|
|
244
|
-
count = case opts[:clients]
|
245
|
-
when 0..9
|
246
|
-
if (opts[:clients] % plan.usecases.size > 0)
|
247
|
-
msg = "Client count does not evenly match usecase count"
|
248
|
-
raise Stella::WackyRatio, msg
|
249
|
-
else
|
250
|
-
(opts[:clients] / plan.usecases.size)
|
251
|
-
end
|
252
|
-
else
|
253
|
-
(opts[:clients] * usecase.ratio).to_i
|
254
|
-
end
|
255
|
-
counts[usecase.digest_cache] = count
|
256
|
-
counts[:total] += count
|
257
|
-
end
|
258
|
-
counts
|
259
|
-
end
|
260
|
-
|
261
|
-
|
262
|
-
def build_thread_package(plan, opts, counts)
|
263
|
-
packages, pointer = Array.new(counts[:total]), 0
|
264
|
-
plan.usecases.each do |usecase|
|
265
|
-
count = counts[usecase.digest_cache]
|
266
|
-
Stella.ld "THREAD PACKAGE: #{usecase.desc} (#{pointer} + #{count})"
|
267
|
-
# Fill the thread_package with the contents of the block
|
268
|
-
packages.fill(pointer, count) do |index|
|
269
|
-
client = Stella::Client.new opts[:hosts].first, index+1, opts
|
270
|
-
client.add_observer(self)
|
271
|
-
client.enable_nowait_mode if opts[:nowait]
|
272
|
-
Stella.stdout.info4 "Created client #{client.digest.short}"
|
273
|
-
ThreadPackage.new(index+1, client, usecase)
|
274
|
-
end
|
275
|
-
pointer += count
|
276
|
-
end
|
277
|
-
packages.compact # TODO: Why one nil element sometimes?
|
278
|
-
# Randomize so when ramping up load
|
279
|
-
# we get a mix of usecases.
|
280
|
-
packages.sort_by {rand}
|
281
|
-
end
|
282
|
-
|
283
|
-
def execute_test_plan(*args)
|
284
|
-
raise "Override execute_test_plan method in #{self}"
|
285
|
-
end
|
286
|
-
|
287
|
-
def running_threads
|
288
|
-
@threads.select { |t| t.status } # non-false status are still running
|
289
|
-
end
|
290
|
-
|
291
|
-
def generate_runtime_report(plan)
|
292
|
-
gt = Benelux.timeline
|
293
|
-
gstats = gt.stats.group(:response_time).merge
|
294
|
-
|
295
|
-
plan.usecases.uniq.each_with_index do |uc,i|
|
296
|
-
uc.requests.each do |req|
|
297
|
-
filter = [uc.digest_cache, req.digest_cache]
|
298
|
-
|
299
|
-
Load.timers.each do |sname|
|
300
|
-
stats = gt.stats.group(sname)[filter].merge
|
301
|
-
#Stella.stdout.info stats.inspect
|
302
|
-
puts [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n].join('; ')
|
303
|
-
end
|
304
|
-
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
end
|
309
|
-
|
310
|
-
def update_prepare_request(client_id, usecase, req, counter)
|
311
|
-
|
312
|
-
end
|
313
|
-
|
314
|
-
def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
|
315
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
316
|
-
args.push usecase.digest.shorter, req.digest.shorter
|
317
|
-
args.push req.http_method, container.status, uri
|
318
|
-
args << params.to_a.collect { |el|
|
319
|
-
next if el[0].to_s == '__stella'
|
320
|
-
'%s=%s' % [el[0], el[1].to_s]
|
321
|
-
}.compact.join('&') # remove skipped params
|
322
|
-
args << headers.to_a.collect { |el|
|
323
|
-
next if el[0].to_s == 'X-Stella-ID'
|
324
|
-
'%s=%s' % el
|
325
|
-
}.compact.join('&') # remove skipped params
|
326
|
-
args << container.unique_id[0,10]
|
327
|
-
#Benelux.thread_timeline.add_message args.join('; '),
|
328
|
-
# :status => container.status,
|
329
|
-
# :kind => :request
|
330
|
-
args = [client_id.shorter, container.status, req.http_method, uri, params.inspect]
|
331
|
-
Stella.stdout.info3 ' Client-%s %3d %-6s %s %s' % args
|
332
|
-
|
333
|
-
end
|
334
|
-
|
335
|
-
def update_execute_response_handler(client_id, req, container)
|
336
|
-
end
|
337
|
-
|
338
|
-
def update_error_execute_response_handler(client_id, ex, req, container)
|
339
|
-
desc = "#{container.usecase.desc} > #{req.desc}"
|
340
|
-
if Stella.stdout.lev == 2
|
341
|
-
Stella.stdout.print 2, '.'.color(:red)
|
342
|
-
else
|
343
|
-
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
344
|
-
Stella.ld ex.backtrace
|
345
|
-
end
|
346
|
-
end
|
347
|
-
|
348
|
-
def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
|
349
|
-
desc = "#{usecase.desc} > #{req.desc}"
|
350
|
-
if Stella.stdout.lev == 2
|
351
|
-
Stella.stdout.print 2, '.'.color(:red)
|
352
|
-
else
|
353
|
-
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
354
|
-
Stella.ld ex.backtrace
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
def update_usecase_quit client_id, msg, req, container
|
359
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
360
|
-
Benelux.thread_timeline.add_count :quit, 1
|
361
|
-
args.push [req, container.status, 'QUIT', msg, container.unique_id[0,10]]
|
362
|
-
Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
|
363
|
-
Stella.stdout.info3 " Client-%s QUIT %s" % [client_id.shorter, msg]
|
364
|
-
end
|
365
|
-
|
366
|
-
def update_request_fail client_id, msg, req, container
|
367
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
368
|
-
Benelux.thread_timeline.add_count :failed, 1
|
369
|
-
args.push [req, container.status, 'FAIL', msg, container.unique_id[0,10]]
|
370
|
-
Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
|
371
|
-
Stella.stdout.info3 " Client-%s FAILED %s" % [client_id.shorter, msg]
|
372
|
-
end
|
373
|
-
|
374
|
-
def update_request_error client_id, msg, req, container
|
375
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
376
|
-
Benelux.thread_timeline.add_count :error, 1
|
377
|
-
args.push [req, container.status, 'ERROR', msg, container.unique_id[0,10]]
|
378
|
-
Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
|
379
|
-
if Stella.stdout.lev >= 3
|
380
|
-
Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
def update_request_repeat client_id, counter, total, req, container
|
385
|
-
Stella.stdout.info3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
|
386
|
-
end
|
387
|
-
|
388
|
-
def update_follow_redirect client_id, ret, req, container
|
389
|
-
Stella.stdout.info3 " Client-%s FOLLOW %-53s" % [client_id.shorter, ret.uri]
|
390
|
-
end
|
391
|
-
|
392
|
-
def update_max_redirects client_id, counter, ret, req, container
|
393
|
-
Stella.stdout.info3 " Client-%s MAX REDIRECTS %s " % [client_id.shorter, counter]
|
394
|
-
end
|
395
|
-
|
396
|
-
def update_authenticate client_id, usecase, req, domain, user, pass
|
397
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
398
|
-
args.push usecase.digest.shorter, req.digest.shorter
|
399
|
-
args.push 'AUTH', domain, user, pass
|
400
|
-
Benelux.thread_timeline.add_message args.join('; '), :kind => :authentication
|
401
|
-
end
|
402
|
-
|
403
|
-
def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container)
|
404
|
-
Stella.stdout.info3 " Client-%s TIMEOUT %-53s" % [client_id.shorter, uri]
|
405
|
-
Benelux.thread_timeline.add_count :failed, 1
|
406
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
407
|
-
args.push [uri, 'TOUT', container.unique_id[0,10]]
|
408
|
-
Benelux.thread_timeline.add_message args.join('; '), :kind => :timeout
|
409
|
-
end
|
410
|
-
|
411
|
-
def self.rescue(client_id, &blk)
|
412
|
-
blk.call
|
413
|
-
rescue => ex
|
414
|
-
Stella.le ' Error in Client-%s: %s' % [client_id.shorter, ex.message]
|
415
|
-
Stella.ld ex.backtrace
|
416
|
-
end
|
417
|
-
|
418
|
-
Benelux.add_timer Stella::Engine::Load, :build_thread_package
|
419
|
-
Benelux.add_timer Stella::Engine::Load, :generate_report
|
420
|
-
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|