stella 0.8.1.002 → 0.8.2.001

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,10 @@
1
+ require 'stella/engine/loadbase'
1
2
 
2
3
  module Stella::Engine
3
- module LoadQueue
4
- extend Stella::Engine::Base
4
+ module Load
5
5
  extend Stella::Engine::Load
6
6
  extend self
7
- ROTATE_TIMELINE = 15
7
+ ROTATE_TIMELINE = 5
8
8
  def execute_test_plan(packages, reps=1,duration=0,arrival=nil)
9
9
  time_started = Time.now
10
10
 
@@ -90,7 +90,7 @@ module Stella::Engine
90
90
  Stella.stdout.info2 $/, $/
91
91
  end
92
92
 
93
- Benelux.add_timer Stella::Engine::LoadQueue, :execute_test_plan
93
+ Benelux.add_timer Stella::Engine::Load, :execute_test_plan
94
94
 
95
95
  end
96
96
  end
@@ -4,17 +4,16 @@ module Stella::Engine
4
4
  extend Stella::Engine::Base
5
5
  extend self
6
6
 
7
- @timers = [:do_request]
7
+ @timers = [:response_time]
8
8
  @counts = [:response_content_size]
9
9
  @reqlog = nil
10
10
  @logdir = nil
11
11
 
12
12
  class << self
13
- attr_accessor :timers, :counts, :logdir
13
+ attr_accessor :timers, :counts, :logdir, :testrun
14
14
  end
15
15
 
16
16
  def run(plan, opts={})
17
-
18
17
  opts = process_options! plan, opts
19
18
  @threads, @max_clients, @real_reps = [], 0, 0
20
19
 
@@ -26,30 +25,16 @@ module Stella::Engine
26
25
  File.unlink latest if File.exists? latest
27
26
  FileUtils.ln_sf File.basename(@logdir), latest
28
27
  end
29
-
30
- @reqlog = Stella::Logger.new log_path(plan, 'requests')
31
- @failog = Stella::Logger.new log_path(plan, 'requests-exceptions')
32
- @sumlog = Stella::Logger.new log_path(plan, 'summary')
33
- @optlog = Stella::Logger.new log_path(plan, 'options')
34
- @authlog = Stella::Logger.new log_path(plan, 'requests-auth')
35
-
36
- @syslog = Stella::Logger.new log_path(plan, 'sysinfo')
37
- @syslog.info(Stella.sysinfo.dump(:yaml)) and @syslog.close
38
-
39
- @plalog = Stella::Logger.new log_path(plan, 'plan')
40
- @plalog.info(plan.pretty.noansi) and @plalog.close
41
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')
42
32
 
43
33
  Stella.stdout.add_template :head, ' %s: %s'
44
34
  Stella.stdout.add_template :status, "#{$/}%s..."
45
35
 
46
- @sumlog.add_template :dsummary, '%20s: %8d'
47
- @sumlog.add_template :fsummary, '%20s: %8.2f'
48
- @optlog.add_template :head, '%10s: %s'
49
- @failog.add_template :request, '%s %s'
50
-
51
- if Stella.stdout.lev > 2
52
- Load.timers += [:query, :connect, :socket_gets_first_byte, :get_body]
36
+ if Stella.stdout.lev >= 2
37
+ Load.timers += [:socket_connect, :send_request, :first_byte, :receive_response]
53
38
  Load.counts = [:request_header_size, :request_content_size]
54
39
  Load.counts += [:response_headers_size, :response_content_size]
55
40
  end
@@ -64,13 +49,12 @@ module Stella::Engine
64
49
  Stella.stdout.head 'Testrun', @testrun.remote_digest
65
50
  end
66
51
 
52
+ @testrun.save(@statlog_path)
53
+
67
54
  @dumper = prepare_dumper(plan, opts)
68
55
 
69
56
  counts = calculate_usecase_clients plan, opts
70
57
 
71
- @optlog.head 'RUNID', runid(plan)
72
- @optlog.head 'OPTIONS', opts.inspect
73
-
74
58
  packages = build_thread_package plan, opts, counts
75
59
 
76
60
  if opts[:duration] > 0
@@ -80,13 +64,15 @@ module Stella::Engine
80
64
  end
81
65
 
82
66
  Stella.stdout.head 'Plan', "#{plan.desc} (#{plan.digest.shorter})"
67
+ Stella.stdout.head 'Hosts', opts[:hosts].join(', ')
83
68
  Stella.stdout.head 'Clients', counts[:total]
84
69
  Stella.stdout.head 'Limit', timing
85
70
 
71
+ Stella.stdout.head 'Arrival', opts[:arrival] if opts[:arrival]
72
+
86
73
  @dumper.start
87
74
 
88
75
  begin
89
- @optlog.head "START", Time.now.to_s
90
76
  Stella.stdout.status "Running"
91
77
  execute_test_plan packages, opts[:repetitions], opts[:duration], opts[:arrival]
92
78
  rescue Interrupt
@@ -100,15 +86,11 @@ module Stella::Engine
100
86
 
101
87
  Stella.stdout.status "Processing"
102
88
 
103
- @optlog.head "END", Time.now.to_s
104
- @optlog.flush
105
-
106
89
  @dumper.stop
107
90
 
108
91
  bt = Benelux.timeline
109
92
  tt = Benelux.thread_timeline
110
93
 
111
-
112
94
  # TODO: don't get test time from benelux.
113
95
  test_time = tt.stats.group(:execute_test_plan).mean
114
96
  generate_report @sumlog, plan, test_time
@@ -118,7 +100,7 @@ module Stella::Engine
118
100
 
119
101
  Stella.stdout.info $/, "Log dir: #{@logdir}"
120
102
 
121
- @testrun.summary[:summary][:failed].n == 0
103
+ @testrun.stats[:summary][:failed].n == 0
122
104
  end
123
105
 
124
106
  protected
@@ -132,41 +114,26 @@ module Stella::Engine
132
114
  end
133
115
 
134
116
  def prepare_dumper(plan, opts)
135
- hand = Stella::Hand.new(LoadQueue::ROTATE_TIMELINE, 2.seconds) do
117
+ hand = Stella::Hand.new(Load::ROTATE_TIMELINE, 2.seconds) do
136
118
  Benelux.update_global_timeline
137
119
  # @threads contains only stella clients
138
120
  concurrency = @threads.select { |t| !t.status.nil? }.size
139
121
  batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
140
122
  @testrun.add_sample batch, concurrency, timeline
141
-
142
- #reqlog.info [Time.now, Benelux.timeline.size].inspect
143
- @reqlog.info Benelux.timeline.messages.filter(:kind => :request)
123
+ @testrun.save(@statlog_path)
144
124
  @failog.info Benelux.timeline.messages.filter(:kind => :exception)
145
125
  @failog.info Benelux.timeline.messages.filter(:kind => :timeout)
146
- @authlog.info Benelux.timeline.messages.filter(:kind => :authentication)
147
- @reqlog.clear and @failog.clear and @authlog.clear
148
-
149
126
  Benelux.timeline.clear if opts[:"no-stats"]
150
-
151
127
  end
152
128
  hand.finally do
153
- #total = @testrun.stats[:summary][:do_request].n
154
- #failed = @testrun.stats[:summary][:failed].n
155
- #@sumlog.info $/, "Summary: "
156
- #@sumlog.dsummary 'successful req', total-failed
157
- #@sumlog.dsummary "failed req", failed
158
- #@sumlog.dsummary "max clients", @max_clients
159
- #@sumlog.dsummary "repetitions", @real_reps
160
- ##@sumlog.fsummary "test time", test_time
161
- ##@sumlog.fsummary "reporting time", report_time
162
- #@sumlog.flush
129
+ @testrun.save(@statlog_path)
163
130
  end
164
131
  hand
165
132
  end
166
133
 
167
134
  def generate_report(sumlog,plan,test_time)
168
135
  global_timeline = Benelux.timeline
169
- global_stats = global_timeline.stats.group(:do_request).merge
136
+ global_stats = global_timeline.stats.group(:response_time).merge
170
137
  if global_stats.n == 0
171
138
  Stella.ld "No stats"
172
139
  return
@@ -176,9 +143,9 @@ module Stella::Engine
176
143
  plan.usecases.uniq.each_with_index do |uc,i|
177
144
 
178
145
  # TODO: Create Ranges object, like Stats object
179
- # global_timeline.ranges(:do_request)[:usecase => '1111']
180
- # The following returns globl do_request ranges.
181
- requests = 0 #global_timeline.ranges(:do_request).size
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
182
149
 
183
150
  desc = uc.desc || "Usecase ##{i+1} "
184
151
  desc << " (#{uc.digest_cache.shorter}) "
@@ -203,18 +170,10 @@ module Stella::Engine
203
170
 
204
171
  @sumlog.info " Sub Total:".bright
205
172
 
206
- stats = global_timeline.stats.group(:do_request)[uc.digest_cache].merge
173
+ stats = global_timeline.stats.group(:response_time)[uc.digest_cache].merge
207
174
  failed = global_timeline.stats.group(:failed)[uc.digest_cache].merge
208
175
  respgrp = global_timeline.stats.group(:execute_response_handler)[uc.digest_cache]
209
176
  resst = respgrp.tag_values(:status)
210
- statusi = []
211
- resst.each do |status|
212
- size = respgrp[:status => status].size
213
- statusi << "#{status}: #{size}"
214
- end
215
- @sumlog.info ' %-30s %d (%s)' % ['Total requests', stats.n, statusi.join(', ')]
216
- @sumlog.info ' %-29s %d' % [:success, stats.n - failed.n]
217
- @sumlog.info ' %-29s %d' % [:failed, failed.n]
218
177
 
219
178
  Load.timers.each do |sname|
220
179
  stats = global_timeline.stats.group(sname)[uc.digest_cache].merge
@@ -228,9 +187,20 @@ module Stella::Engine
228
187
  @sumlog.flush
229
188
  end
230
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 $/
231
200
  end
232
201
 
233
202
  @sumlog.info ' ' << " %-66s ".att(:reverse) % 'Total:'
203
+ @sumlog.flush
234
204
 
235
205
  failed = global_timeline.stats.group(:failed)
236
206
  respgrp = global_timeline.stats.group(:execute_response_handler)
@@ -240,14 +210,7 @@ module Stella::Engine
240
210
  size = respgrp[:status => status].size
241
211
  statusi << [status, size]
242
212
  end
243
- @sumlog.info ' %-30s %d' % ['Total requests', global_stats.n]
244
- success = global_stats.n - failed.n
245
- @sumlog.info ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
246
- statusi.each do |pair|
247
- @sumlog.info3 ' %-28s %s: %d' % ['', *pair]
248
- end
249
- @sumlog.info ' %-29s %d' % [:failed, failed.n]
250
-
213
+
251
214
  Load.timers.each do |sname|
252
215
  stats = global_timeline.stats.group(sname).merge
253
216
  @sumlog.info ' %-30s %-.3fs %-.3f(SD)' % [sname, stats.mean, stats.sd]
@@ -259,6 +222,19 @@ module Stella::Engine
259
222
  @sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
260
223
  @sumlog.flush
261
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
+
262
238
  end
263
239
 
264
240
 
@@ -314,7 +290,7 @@ module Stella::Engine
314
290
 
315
291
  def generate_runtime_report(plan)
316
292
  gt = Benelux.timeline
317
- gstats = gt.stats.group(:do_request).merge
293
+ gstats = gt.stats.group(:response_time).merge
318
294
 
319
295
  plan.usecases.uniq.each_with_index do |uc,i|
320
296
  uc.requests.each do |req|
@@ -348,9 +324,9 @@ module Stella::Engine
348
324
  '%s=%s' % el
349
325
  }.compact.join('&') # remove skipped params
350
326
  args << container.unique_id[0,10]
351
- Benelux.thread_timeline.add_message args.join('; '),
352
- :status => container.status,
353
- :kind => :request
327
+ #Benelux.thread_timeline.add_message args.join('; '),
328
+ # :status => container.status,
329
+ # :kind => :request
354
330
  args = [client_id.shorter, container.status, req.http_method, uri, params.inspect]
355
331
  Stella.stdout.info3 ' Client-%s %3d %-6s %s %s' % args
356
332
 
@@ -426,8 +402,8 @@ module Stella::Engine
426
402
 
427
403
  def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container)
428
404
  Stella.stdout.info3 " Client-%s TIMEOUT %-53s" % [client_id.shorter, uri]
429
- args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
430
405
  Benelux.thread_timeline.add_count :failed, 1
406
+ args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
431
407
  args.push [uri, 'TOUT', container.unique_id[0,10]]
432
408
  Benelux.thread_timeline.add_message args.join('; '), :kind => :timeout
433
409
  end
data/lib/stella/logger.rb CHANGED
@@ -4,11 +4,7 @@ module Stella
4
4
 
5
5
 
6
6
  class Logger
7
-
8
- @@disable = false
9
- def self.disable!() @@disable = true end
10
- def self.disabled?() @@disable == true end
11
-
7
+
12
8
  attr_accessor :lev
13
9
  attr_reader :templates
14
10
 
@@ -17,10 +13,14 @@ module Stella
17
13
  @lev, @offset = 1, 0
18
14
  @templates = {}
19
15
  @autoflush = false
20
- return if Logger.disabled?
16
+ @disable = false
21
17
  self.output = output
22
18
  end
23
19
 
20
+ def disable!() @disable = true end
21
+ def enable!() @disable = true end
22
+ def disabled?() @disable == true end
23
+
24
24
  def autoflush!() @autoflush = true end
25
25
  def autoflush?() @autoflush == true end
26
26
 
@@ -37,14 +37,14 @@ module Stella
37
37
  end
38
38
 
39
39
  def print(level, *msg)
40
- return if level > @lev || Logger.disabled?
40
+ return if level > @lev || disabled?
41
41
  @buffer.print *msg
42
42
  flush if autoflush?
43
43
  true
44
44
  end
45
45
 
46
46
  def puts(level, *msg)
47
- return if level > @lev || Logger.disabled?
47
+ return if level > @lev || disabled?
48
48
  @buffer.puts *msg
49
49
  flush if autoflush?
50
50
  true
@@ -83,7 +83,7 @@ module Stella
83
83
 
84
84
  # TODO: There's a big when using print (no newline)
85
85
  def flush
86
- return if Logger.disabled?
86
+ return if disabled?
87
87
  @mutex.synchronize do
88
88
  #return if @offset == @output.tell
89
89
  @buffer.seek @offset
@@ -99,7 +99,7 @@ module Stella
99
99
  end
100
100
 
101
101
  def clear
102
- return if Logger.disabled?
102
+ return if disabled?
103
103
  flush
104
104
  @mutex.synchronize do
105
105
  @buffer.rewind
@@ -108,7 +108,7 @@ module Stella
108
108
  end
109
109
 
110
110
  def close
111
- return if Logger.disabled?
111
+ return if disabled?
112
112
  flush
113
113
  @buffer.close
114
114
  @output.close
@@ -120,7 +120,7 @@ module Stella
120
120
  # Must call flush to send to output.
121
121
  class SyncLogger < Logger
122
122
  def print(level, *msg)
123
- return if level > @lev || Logger.disabled?
123
+ return if level > @lev || disabled?
124
124
  @mutex.synchronize {
125
125
  @buffer.print *msg
126
126
  flush if autoflush?
@@ -130,7 +130,7 @@ module Stella
130
130
 
131
131
  def puts(level, *msg)
132
132
  #Stella.ld [level, @lev, msg]
133
- return if level > @lev || Logger.disabled?
133
+ return if level > @lev || disabled?
134
134
  @mutex.synchronize {
135
135
  @buffer.puts *msg
136
136
  flush if autoflush?
@@ -153,13 +153,13 @@ class Stella::Service
153
153
  trun.remote_digest = obj['digest']
154
154
  @runid = obj['digest']
155
155
  end
156
- def testrun_stats(summary, samples)
156
+ def testrun_stats(stats, samples)
157
157
  raise NoTestrunSelected, "no testrun: #{runid}" unless @runid
158
158
  req = uri('v1', 'testrun', "stats.json")
159
159
  params = {
160
160
  :runid => @runid,
161
161
  :status => 'running',
162
- :summary => summary.to_json,
162
+ :stats => stats.to_json,
163
163
  :samples => samples.to_json
164
164
  }
165
165
  res = send_request :post, req, params
@@ -41,7 +41,8 @@ class Testplan < Storable
41
41
  # TODO: Add Stellar::TOKEN to the calculation
42
42
  gibbler :id, :usecases, :description
43
43
 
44
- def initialize(uris=[], opts={})
44
+ def initialize(*uris)
45
+ uris.flatten!
45
46
  self.description = "Test plan"
46
47
  @usecases = []
47
48
  @testplan_current_ratio = 0
@@ -56,7 +57,6 @@ class Testplan < Storable
56
57
  uri = URI.parse uri
57
58
  uri.path = '/' if uri.path.nil? || uri.path.empty?
58
59
  req = usecase.add_request :get, uri.path
59
- req.wait = opts[:wait] if opts[:wait]
60
60
  end
61
61
  self.add_usecase usecase
62
62
  end
@@ -124,10 +124,12 @@ class Testplan < Storable
124
124
  end
125
125
 
126
126
  def pretty(long=false)
127
+ self.digest # make sure we have values in the cache
127
128
  str = []
128
129
  dig = long ? self.digest_cache : self.digest_cache.shorter
129
130
  str << " %-66s ".att(:reverse) % ["#{self.description} (#{dig})"]
130
131
  @usecases.each_with_index do |uc,i|
132
+ uc.digest
131
133
  dig = long ? uc.digest_cache : uc.digest_cache.shorter
132
134
  desc = uc.description || "Usecase ##{i+1}"
133
135
  desc += " (#{dig}) "
@@ -136,6 +138,7 @@ class Testplan < Storable
136
138
  str << ' Auth: %s (%s/%s)' % uc.http_auth.values
137
139
  end
138
140
  requests = uc.requests.each do |r|
141
+ r.digest
139
142
  dig = long ? r.digest_cache : r.digest_cache.shorter
140
143
  str << " %-62s".bright % ["#{r.description} (#{dig})"]
141
144
  str << " %s" % [r]
data/lib/stella/utils.rb CHANGED
@@ -109,7 +109,7 @@ module Stella
109
109
  end
110
110
 
111
111
  # A basic file writer
112
- def write_to_file(filename, content, mode, chmod=600)
112
+ def write_to_file(filename, content, mode, chmod=0600)
113
113
  mode = (mode == :append) ? 'a' : 'w'
114
114
  f = File.open(filename,mode)
115
115
  f.puts content