stella 0.8.2.003 → 0.8.3.001
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +19 -0
- data/Rakefile +2 -2
- data/VERSION.yml +2 -2
- data/bin/stella +4 -5
- data/lib/proc_source.rb +1 -0
- data/lib/stella/cli.rb +20 -37
- data/lib/stella/client.rb +35 -17
- data/lib/stella/common.rb +74 -5
- data/lib/stella/data/http.rb +27 -11
- data/lib/stella/engine/functional.rb +11 -43
- data/lib/stella/engine/load.rb +94 -86
- data/lib/stella/engine.rb +224 -109
- data/lib/stella/logger.rb +15 -12
- data/lib/stella/testplan.rb +35 -11
- data/lib/stella.rb +2 -2
- data/stella.gemspec +8 -9
- data/tryouts/70_module_usage.rb +7 -6
- metadata +4 -5
- data/lib/stella/service.rb +0 -334
data/lib/stella/engine/load.rb
CHANGED
@@ -5,22 +5,23 @@ module Stella::Engine
|
|
5
5
|
@timers = [:response_time]
|
6
6
|
@counts = [:response_content_size]
|
7
7
|
|
8
|
-
def run(
|
9
|
-
opts = process_options! plan, @opts
|
8
|
+
def run(testrun)
|
10
9
|
@threads, @max_clients, @real_reps = [], 0, 0
|
10
|
+
counts = calculate_usecase_clients testrun
|
11
|
+
packages = build_thread_package testrun, counts
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
19
21
|
end
|
20
22
|
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@failog = Stella::Logger.new log_path(plan, 'exceptions')
|
23
|
+
@sumlog = Stella::Logger.new testrun.log_path('summary')
|
24
|
+
@failog = Stella::Logger.new testrun.log_path('exceptions')
|
24
25
|
|
25
26
|
Stella.stdout.add_template :head, ' %s: %s'
|
26
27
|
Stella.stdout.add_template :status, "#{$/}%s..."
|
@@ -32,41 +33,33 @@ module Stella::Engine
|
|
32
33
|
end
|
33
34
|
|
34
35
|
events = [Load.timers, Load.counts, :failed].flatten
|
35
|
-
|
36
|
-
|
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)
|
36
|
+
|
37
|
+
testrun.save
|
45
38
|
|
46
|
-
@dumper = prepare_dumper(
|
39
|
+
@dumper = prepare_dumper(testrun)
|
47
40
|
|
48
|
-
counts = calculate_usecase_clients plan, opts
|
49
41
|
|
50
|
-
packages = build_thread_package plan, opts, counts
|
51
42
|
|
52
|
-
if
|
53
|
-
timing = "#{
|
43
|
+
if testrun.duration > 0
|
44
|
+
timing = "#{testrun.duration.seconds.to_i} seconds"
|
54
45
|
else
|
55
|
-
timing = "#{
|
46
|
+
timing = "#{testrun.repetitions} repetitions"
|
56
47
|
end
|
57
48
|
|
58
|
-
Stella.stdout.head
|
59
|
-
Stella.stdout.head '
|
49
|
+
Stella.stdout.head "Runid", "#{testrun.id.shorter}"
|
50
|
+
Stella.stdout.head 'Plan', "#{testrun.plan.desc} (#{testrun.plan.id.shorter})"
|
51
|
+
Stella.stdout.head 'Hosts', testrun.hosts.join(', ')
|
60
52
|
Stella.stdout.head 'Clients', counts[:total]
|
61
53
|
Stella.stdout.head 'Limit', timing
|
62
|
-
|
63
|
-
Stella.stdout.head 'Arrival', opts[:arrival] if opts[:arrival]
|
54
|
+
Stella.stdout.head 'Arrival', testrun.arrival if testrun.arrival
|
64
55
|
|
65
56
|
@dumper.start
|
66
57
|
|
67
58
|
begin
|
68
59
|
Stella.stdout.status "Running"
|
69
|
-
|
60
|
+
testrun.status = "running"
|
61
|
+
testrun.start_time = Time.now.utc.to_i
|
62
|
+
execute_test_plan packages, testrun
|
70
63
|
rescue Interrupt
|
71
64
|
Stella.stdout.info $/, "Stopping test"
|
72
65
|
Stella.abort!
|
@@ -85,18 +78,19 @@ module Stella::Engine
|
|
85
78
|
|
86
79
|
# TODO: don't get test time from benelux.
|
87
80
|
test_time = tt.stats.group(:execute_test_plan).mean
|
88
|
-
generate_report @sumlog,
|
81
|
+
generate_report @sumlog, testrun, test_time
|
89
82
|
#report_time = tt.stats.group(:generate_report).mean
|
90
83
|
|
91
|
-
Stella.
|
92
|
-
|
93
|
-
|
84
|
+
unless Stella::Logger.disabled?
|
85
|
+
Stella.stdout.info File.read(@sumlog.path)
|
86
|
+
Stella.stdout.info $/, "Log dir: #{testrun.log_dir}"
|
87
|
+
end
|
94
88
|
|
95
|
-
|
89
|
+
testrun
|
96
90
|
end
|
97
91
|
|
98
92
|
ROTATE_TIMELINE = 5
|
99
|
-
def execute_test_plan(packages,
|
93
|
+
def execute_test_plan(packages, testrun)
|
100
94
|
time_started = Time.now
|
101
95
|
|
102
96
|
pqueue = Queue.new
|
@@ -111,25 +105,25 @@ module Stella::Engine
|
|
111
105
|
Thread.current[:real_reps] = 0
|
112
106
|
Thread.current[:real_uctime] = Benelux::Stats::Calculator.new
|
113
107
|
c, uc = package.client, package.usecase
|
114
|
-
Stella.stdout.info4 $/, "======== THREAD %s: START" % [c.
|
108
|
+
Stella.stdout.info4 $/, "======== THREAD %s: START" % [c.id.short]
|
115
109
|
|
116
110
|
# This thread will stay on this one track.
|
117
|
-
Benelux.current_track c.
|
111
|
+
Benelux.current_track c.id
|
118
112
|
|
119
|
-
Benelux.add_thread_tags :usecase => uc.
|
113
|
+
Benelux.add_thread_tags :usecase => uc.id
|
120
114
|
Thread.current[:real_uctime].first_tick
|
121
115
|
prev_ptime ||= Time.now
|
122
|
-
|
116
|
+
testrun.repetitions.times { |rep|
|
123
117
|
break if Stella.abort?
|
124
118
|
Thread.current[:real_reps] += 1
|
125
119
|
# NOTE: It's important to not call digest or gibbler methods
|
126
120
|
# on client object b/c it is not frozen. Always use digest_cache.
|
127
|
-
args = [c.
|
121
|
+
args = [c.id.short, uc.desc, uc.id.short, Thread.current[:real_reps]]
|
128
122
|
Stella.stdout.info4 $/, "======== THREAD %s: %s:%s (rep: %d)" % args
|
129
123
|
|
130
124
|
Benelux.add_thread_tags :rep => rep
|
131
125
|
#Stella.stdout.info [package.client.gibbler.shorter, package.usecase.gibbler.shorter, rep].inspect
|
132
|
-
Stella::Engine::Load.rescue(c.
|
126
|
+
Stella::Engine::Load.rescue(c.id) {
|
133
127
|
break if Stella.abort?
|
134
128
|
print '.' if Stella.stdout.lev == 2
|
135
129
|
stats = c.execute uc
|
@@ -151,9 +145,9 @@ module Stella::Engine
|
|
151
145
|
|
152
146
|
# If a duration was given, we make sure
|
153
147
|
# to run for only that amount of time.
|
154
|
-
if duration > 0
|
155
|
-
break if (time_elapsed+Thread.current[:real_uctime].mean) >= duration
|
156
|
-
redo if (time_elapsed+Thread.current[:real_uctime].mean) <= duration
|
148
|
+
if testrun.duration > 0
|
149
|
+
break if (time_elapsed+Thread.current[:real_uctime].mean) >= testrun.duration
|
150
|
+
redo if (time_elapsed+Thread.current[:real_uctime].mean) <= testrun.duration
|
157
151
|
end
|
158
152
|
}
|
159
153
|
|
@@ -162,12 +156,12 @@ module Stella::Engine
|
|
162
156
|
pqueue << package # return the package to the queue
|
163
157
|
end
|
164
158
|
|
165
|
-
unless arrival.nil?
|
159
|
+
unless testrun.arrival.nil? || testrun.arrival.to_f <= 0
|
166
160
|
# Create 1 second / users per second
|
167
161
|
args = [@threads.size, packages.size]
|
168
162
|
Stella.stdout.print 2, '+'
|
169
163
|
Stella.stdout.info3 $/, "-> NEW CLIENT: %s of %s" % args
|
170
|
-
sleep 1/arrival
|
164
|
+
sleep 1/testrun.arrival
|
171
165
|
end
|
172
166
|
}
|
173
167
|
|
@@ -192,25 +186,28 @@ module Stella::Engine
|
|
192
186
|
end
|
193
187
|
end
|
194
188
|
|
195
|
-
def prepare_dumper(
|
189
|
+
def prepare_dumper(testrun)
|
196
190
|
hand = Stella::Hand.new(Load::ROTATE_TIMELINE, 2.seconds) do
|
197
191
|
Benelux.update_global_timeline
|
198
192
|
# @threads contains only stella clients
|
199
193
|
concurrency = @threads.select { |t| !t.status.nil? }.size
|
200
194
|
batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
|
201
|
-
|
202
|
-
|
195
|
+
testrun.add_sample batch, concurrency, timeline
|
196
|
+
if batch == 1 # only save the first batch
|
197
|
+
testrun.log = Benelux.timeline.messages.filter(:kind => :log)
|
198
|
+
end
|
199
|
+
testrun.save
|
203
200
|
@failog.info Benelux.timeline.messages.filter(:kind => :exception)
|
204
201
|
@failog.info Benelux.timeline.messages.filter(:kind => :timeout)
|
205
|
-
Benelux.timeline.clear if
|
202
|
+
Benelux.timeline.clear if testrun.nostats
|
206
203
|
end
|
207
204
|
hand.finally do
|
208
|
-
|
205
|
+
testrun.save
|
209
206
|
end
|
210
207
|
hand
|
211
208
|
end
|
212
209
|
|
213
|
-
def generate_report(sumlog,
|
210
|
+
def generate_report(sumlog,testrun,test_time)
|
214
211
|
global_timeline = Benelux.timeline
|
215
212
|
global_stats = global_timeline.stats.group(:response_time).merge
|
216
213
|
if global_stats.n == 0
|
@@ -218,8 +215,8 @@ module Stella::Engine
|
|
218
215
|
return
|
219
216
|
end
|
220
217
|
|
221
|
-
@sumlog.info " %-72s ".att(:reverse) % ["#{plan.desc} (#{plan.
|
222
|
-
plan.usecases.uniq.each_with_index do |uc,i|
|
218
|
+
@sumlog.info " %-72s ".att(:reverse) % ["#{testrun.plan.desc} (#{testrun.plan.id.shorter})"]
|
219
|
+
testrun.plan.usecases.uniq.each_with_index do |uc,i|
|
223
220
|
|
224
221
|
# TODO: Create Ranges object, like Stats object
|
225
222
|
# global_timeline.ranges(:response_time)[:usecase => '1111']
|
@@ -227,13 +224,13 @@ module Stella::Engine
|
|
227
224
|
requests = 0 #global_timeline.ranges(:response_time).size
|
228
225
|
|
229
226
|
desc = uc.desc || "Usecase ##{i+1} "
|
230
|
-
desc << " (#{uc.
|
227
|
+
desc << " (#{uc.id.shorter}) "
|
231
228
|
str = ' ' << " %-66s %s %d%% ".bright.att(:reverse)
|
232
229
|
@sumlog.info str % [desc, '', uc.ratio_pretty]
|
233
230
|
uc.requests.each do |req|
|
234
|
-
filter = [uc.
|
231
|
+
filter = [uc.id, req.id]
|
235
232
|
desc = req.desc
|
236
|
-
@sumlog.info " %-72s ".bright % ["#{req.desc} (#{req.
|
233
|
+
@sumlog.info " %-72s ".bright % ["#{req.desc} (#{req.id.shorter})"]
|
237
234
|
@sumlog.info " %s" % [req.to_s]
|
238
235
|
|
239
236
|
Load.timers.each do |sname|
|
@@ -249,19 +246,19 @@ module Stella::Engine
|
|
249
246
|
|
250
247
|
@sumlog.info " Sub Total:".bright
|
251
248
|
|
252
|
-
stats = global_timeline.stats.group(:response_time)[uc.
|
253
|
-
failed = global_timeline.stats.group(:failed)[uc.
|
254
|
-
respgrp = global_timeline.stats.group(:execute_response_handler)[uc.
|
249
|
+
stats = global_timeline.stats.group(:response_time)[uc.id].merge
|
250
|
+
failed = global_timeline.stats.group(:failed)[uc.id].merge
|
251
|
+
respgrp = global_timeline.stats.group(:execute_response_handler)[uc.id]
|
255
252
|
resst = respgrp.tag_values(:status)
|
256
253
|
|
257
254
|
Load.timers.each do |sname|
|
258
|
-
stats = global_timeline.stats.group(sname)[uc.
|
255
|
+
stats = global_timeline.stats.group(sname)[uc.id].merge
|
259
256
|
@sumlog.info ' %-30s %.3fs %.3f(SD)' % [sname, stats.mean, stats.sd]
|
260
257
|
@sumlog.flush
|
261
258
|
end
|
262
259
|
|
263
260
|
Load.counts.each do |sname|
|
264
|
-
stats = global_timeline.stats.group(sname)[uc.
|
261
|
+
stats = global_timeline.stats.group(sname)[uc.id].merge
|
265
262
|
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
266
263
|
@sumlog.flush
|
267
264
|
end
|
@@ -317,38 +314,37 @@ module Stella::Engine
|
|
317
314
|
end
|
318
315
|
|
319
316
|
|
320
|
-
def calculate_usecase_clients(
|
317
|
+
def calculate_usecase_clients(testrun)
|
321
318
|
counts = { :total => 0 }
|
322
|
-
plan.usecases.each_with_index do |usecase,i|
|
323
|
-
count = case
|
319
|
+
testrun.plan.usecases.each_with_index do |usecase,i|
|
320
|
+
count = case testrun.clients
|
324
321
|
when 0..9
|
325
|
-
if (
|
326
|
-
msg = "Client count does not evenly match usecase count"
|
327
|
-
raise Stella::WackyRatio, msg
|
322
|
+
if (testrun.clients % testrun.plan.usecases.size > 0)
|
323
|
+
msg = "Client count (%d) does not evenly match usecase count (%d)"
|
324
|
+
raise Stella::WackyRatio, (msg % [testrun.clients, testrun.plan.usecases.size])
|
328
325
|
else
|
329
|
-
(
|
326
|
+
(testrun.clients / testrun.plan.usecases.size)
|
330
327
|
end
|
331
328
|
else
|
332
|
-
(
|
329
|
+
(testrun.clients * usecase.ratio).to_i
|
333
330
|
end
|
334
|
-
counts[usecase.
|
331
|
+
counts[usecase.id] = count
|
335
332
|
counts[:total] += count
|
336
333
|
end
|
337
334
|
counts
|
338
335
|
end
|
339
336
|
|
340
337
|
|
341
|
-
def build_thread_package(
|
338
|
+
def build_thread_package(testrun, counts)
|
342
339
|
packages, pointer = Array.new(counts[:total]), 0
|
343
|
-
plan.usecases.each do |usecase|
|
344
|
-
count = counts[usecase.
|
340
|
+
testrun.plan.usecases.each do |usecase|
|
341
|
+
count = counts[usecase.id]
|
345
342
|
Stella.ld "THREAD PACKAGE: #{usecase.desc} (#{pointer} + #{count})"
|
346
343
|
# Fill the thread_package with the contents of the block
|
347
344
|
packages.fill(pointer, count) do |index|
|
348
|
-
client = Stella::Client.new
|
345
|
+
client = Stella::Client.new testrun.hosts.first, testrun.client_options
|
349
346
|
client.add_observer(self)
|
350
|
-
|
351
|
-
Stella.stdout.info4 "Created client #{client.digest.short}"
|
347
|
+
Stella.stdout.info4 "Created client #{client.id.short}"
|
352
348
|
ThreadPackage.new(index+1, client, usecase)
|
353
349
|
end
|
354
350
|
pointer += count
|
@@ -364,13 +360,13 @@ module Stella::Engine
|
|
364
360
|
@threads.select { |t| t.status } # non-false status are still running
|
365
361
|
end
|
366
362
|
|
367
|
-
def generate_runtime_report(
|
363
|
+
def generate_runtime_report(testrun)
|
368
364
|
gt = Benelux.timeline
|
369
365
|
gstats = gt.stats.group(:response_time).merge
|
370
366
|
|
371
|
-
plan.usecases.uniq.each_with_index do |uc,i|
|
367
|
+
testrun.plan.usecases.uniq.each_with_index do |uc,i|
|
372
368
|
uc.requests.each do |req|
|
373
|
-
filter = [uc.
|
369
|
+
filter = [uc.id, req.id]
|
374
370
|
|
375
371
|
Load.timers.each do |sname|
|
376
372
|
stats = gt.stats.group(sname)[filter].merge
|
@@ -388,8 +384,20 @@ module Stella::Engine
|
|
388
384
|
end
|
389
385
|
|
390
386
|
def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
|
387
|
+
if @opts[:with_content]
|
388
|
+
log = Stella::Engine::Log.new Time.now.to_f, container.unique_id, client_id,
|
389
|
+
'testplanid',
|
390
|
+
usecase.id, req.id,
|
391
|
+
req.http_method, container.status, uri,
|
392
|
+
params, container.response.request.header.dump,
|
393
|
+
container.response.header.dump,
|
394
|
+
container.response.body.dump
|
395
|
+
|
396
|
+
Benelux.thread_timeline.add_message log, :status => container.status, :kind => :log
|
397
|
+
end
|
398
|
+
|
391
399
|
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
392
|
-
args.push usecase.
|
400
|
+
args.push usecase.id.shorter, req.id.shorter
|
393
401
|
args.push req.http_method, container.status, uri
|
394
402
|
args << params.to_a.collect { |el|
|
395
403
|
next if el[0].to_s == '__stella'
|
@@ -471,7 +479,7 @@ module Stella::Engine
|
|
471
479
|
|
472
480
|
def update_authenticate client_id, usecase, req, domain, user, pass
|
473
481
|
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
474
|
-
args.push usecase.
|
482
|
+
args.push usecase.id.shorter, req.id.shorter
|
475
483
|
args.push 'AUTH', domain, user, pass
|
476
484
|
Benelux.thread_timeline.add_message args.join('; '), :kind => :authentication
|
477
485
|
end
|