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.
@@ -5,22 +5,23 @@ module Stella::Engine
5
5
  @timers = [:response_time]
6
6
  @counts = [:response_content_size]
7
7
 
8
- def run(plan)
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
- @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
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
- @statlog_path = log_path(plan, 'stats')
22
- @sumlog = Stella::Logger.new log_path(plan, 'summary')
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
- @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)
36
+
37
+ testrun.save
45
38
 
46
- @dumper = prepare_dumper(plan, opts)
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 opts[:duration] > 0
53
- timing = "#{opts[:duration].seconds.to_i} seconds"
43
+ if testrun.duration > 0
44
+ timing = "#{testrun.duration.seconds.to_i} seconds"
54
45
  else
55
- timing = "#{opts[:repetitions]} repetitions"
46
+ timing = "#{testrun.repetitions} repetitions"
56
47
  end
57
48
 
58
- Stella.stdout.head 'Plan', "#{plan.desc} (#{plan.digest.shorter})"
59
- Stella.stdout.head 'Hosts', opts[:hosts].join(', ')
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
- execute_test_plan packages, opts[:repetitions], opts[:duration], opts[:arrival]
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, plan, test_time
81
+ generate_report @sumlog, testrun, test_time
89
82
  #report_time = tt.stats.group(:generate_report).mean
90
83
 
91
- Stella.stdout.info File.read(@sumlog.path)
92
-
93
- Stella.stdout.info $/, "Log dir: #{@logdir}"
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
- @testrun
89
+ testrun
96
90
  end
97
91
 
98
92
  ROTATE_TIMELINE = 5
99
- def execute_test_plan(packages, reps=1,duration=0,arrival=nil)
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.digest.short]
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.digest
111
+ Benelux.current_track c.id
118
112
 
119
- Benelux.add_thread_tags :usecase => uc.digest_cache
113
+ Benelux.add_thread_tags :usecase => uc.id
120
114
  Thread.current[:real_uctime].first_tick
121
115
  prev_ptime ||= Time.now
122
- reps.times { |rep|
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.digest_cache.short, uc.desc, uc.digest.short, Thread.current[:real_reps]]
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.digest_cache) {
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(plan, opts)
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
- @testrun.add_sample batch, concurrency, timeline
202
- @testrun.save(@statlog_path)
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 opts[:"no-stats"]
202
+ Benelux.timeline.clear if testrun.nostats
206
203
  end
207
204
  hand.finally do
208
- @testrun.save(@statlog_path)
205
+ testrun.save
209
206
  end
210
207
  hand
211
208
  end
212
209
 
213
- def generate_report(sumlog,plan,test_time)
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.digest_cache.shorter})"]
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.digest_cache.shorter}) "
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.digest_cache, req.digest_cache]
231
+ filter = [uc.id, req.id]
235
232
  desc = req.desc
236
- @sumlog.info " %-72s ".bright % ["#{req.desc} (#{req.digest_cache.shorter})"]
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.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]
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.digest_cache].merge
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.digest_cache].merge
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(plan, opts)
317
+ def calculate_usecase_clients(testrun)
321
318
  counts = { :total => 0 }
322
- plan.usecases.each_with_index do |usecase,i|
323
- count = case opts[:clients]
319
+ testrun.plan.usecases.each_with_index do |usecase,i|
320
+ count = case testrun.clients
324
321
  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
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
- (opts[:clients] / plan.usecases.size)
326
+ (testrun.clients / testrun.plan.usecases.size)
330
327
  end
331
328
  else
332
- (opts[:clients] * usecase.ratio).to_i
329
+ (testrun.clients * usecase.ratio).to_i
333
330
  end
334
- counts[usecase.digest_cache] = count
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(plan, opts, counts)
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.digest_cache]
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 opts[:hosts].first, index+1, opts
345
+ client = Stella::Client.new testrun.hosts.first, testrun.client_options
349
346
  client.add_observer(self)
350
- client.enable_nowait_mode if opts[:nowait]
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(plan)
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.digest_cache, req.digest_cache]
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.digest.shorter, req.digest.shorter
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.digest.shorter, req.digest.shorter
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