stella 0.8.2.002 → 0.8.2.003
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.
- 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
|
-
|