stella 0.8.4.001 → 0.8.5.001

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.txt CHANGED
@@ -11,7 +11,20 @@ STELLA, CHANGES
11
11
  * TODO: process templates for calls to set in get blocks
12
12
 
13
13
 
14
- #### 0.8.4 (2010-03-??) ###############################
14
+ #### 0.8.5 (2010-03-27) ###############################
15
+
16
+ * FIXED: Add User-Agent header if Stella.agent is not null and one is not already provided
17
+ * FIXED: Client wait (undefined method '>' for Range error)
18
+ * CHANGE: Testrun#samples contains all data samples for each event in a given batch
19
+ * CHANGE: Renamed Testrun#events -> Testrun#event_probes
20
+ * ADDED: Testrun#logsize
21
+ * ADDED: Store HTTP status codes in Testrun#stats
22
+ * ADDED: Store error messages in Sample#errors
23
+ * ADDED: Stella.get now takes a block
24
+ * ADDED: Stella.agent
25
+
26
+
27
+ #### 0.8.4 (2010-03-19) ###############################
15
28
 
16
29
  * FIXED: Misc issues getting and setting headers, params, and resources
17
30
  * FIXED: There was no response body in Stella::Engine::Log objects
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :MAJOR: 0
3
3
  :MINOR: 8
4
- :PATCH: 4
4
+ :PATCH: 5
5
5
  :BUILD: '001'
data/bin/stella CHANGED
@@ -67,7 +67,7 @@ class Stella::CLI::Definition
67
67
  true
68
68
  end
69
69
  global :V, :version, "Display version number" do
70
- puts "Stella version: #{Stella::VERSION} (#{Stella::VERSION::PATCH})"
70
+ puts "Stella version: #{Stella::VERSION.inspect}"
71
71
  exit 0
72
72
  end
73
73
 
@@ -221,7 +221,7 @@ usecase 25, "YAML API" do
221
221
  # user should repeat this request 7 times.
222
222
  #
223
223
  response 200 do
224
- repeat 7
224
+ repeat 3
225
225
  end
226
226
  end
227
227
 
@@ -238,7 +238,7 @@ usecase 10, "Self-serve API" do
238
238
  param :city => random(['Toronto', 'Vancouver', 'Montreal'])
239
239
  param :logo => file('logo.png')
240
240
  response 302 do
241
- repeat 3
241
+ repeat 2
242
242
  end
243
243
  end
244
244
 
data/lib/stella.rb CHANGED
@@ -74,11 +74,12 @@ module Stella
74
74
  @debug = false
75
75
  @abort = false
76
76
  @quiet = false
77
+ @agent = "Stella/#{Stella::VERSION}"
77
78
  @log = Stella::SyncLogger.new
78
79
  @stdout = Stella::Logger.new STDOUT
79
80
 
80
81
  class << self
81
- attr_accessor :log, :stdout
82
+ attr_accessor :log, :stdout, :agent
82
83
  end
83
84
 
84
85
  def le(*msg); stdout.info " " << msg.join("#{$/} ").colour(:red); end
@@ -127,10 +128,15 @@ module Stella
127
128
  autoload :Client, 'stella/client'
128
129
  autoload :Service, 'stella/service'
129
130
 
130
- def get(uri, query={})
131
+ def get(uri, query={}, &blk)
131
132
  require 'stella/client'
132
133
  http_client = HTTPClient.new :agent_name => "Opera/9.51 (Windows NT 5.1; U; en)"
133
- http_client.get(uri, query).body.content
134
+ res = http_client.get(uri, query)
135
+ if blk.nil?
136
+ res.body.content
137
+ else
138
+ blk.call res
139
+ end
134
140
  rescue => ex
135
141
  STDERR.puts ex.message
136
142
  STDERR.puts ex.backtrace if Stella.debug?
data/lib/stella/cli.rb CHANGED
@@ -35,11 +35,11 @@ class Stella::CLI < Drydock::Command
35
35
 
36
36
  def generate
37
37
  testrun = run :generate
38
- @exit_code = (testrun.stats['summary']['failed'].n == 0 ? 0 : 1)
38
+ @exit_code = (testrun.has_errors? == 0 ? 0 : 1)
39
39
  end
40
40
  def verify
41
41
  testrun = run :verify
42
- @exit_code = (testrun.stats['summary']['failed'].n == 0 ? 0 : 1)
42
+ @exit_code = (testrun.has_errors? == 0 ? 0 : 1)
43
43
  end
44
44
 
45
45
  def example
data/lib/stella/client.rb CHANGED
@@ -154,8 +154,8 @@ module Stella
154
154
  next
155
155
  end
156
156
 
157
- wait = (req.wait > 0) ? req.wait : @opts[:wait]
158
- run_sleeper(wait, asset_duration) if (wait > 0) && !nowait?
157
+ wait = (req.wait != 0) ? req.wait : @opts[:wait]
158
+ run_sleeper(wait, asset_duration) unless nowait?
159
159
 
160
160
  # TODO: consider throw/catch
161
161
  case ret.class.to_s
@@ -212,6 +212,7 @@ module Stella
212
212
  end
213
213
 
214
214
  def run_sleeper(wait, already_waited=0)
215
+ return if wait == 0
215
216
  # The time it took to download the assets can
216
217
  # be removed from the specified wait time.
217
218
  if wait.is_a?(::Range)
@@ -228,7 +229,7 @@ module Stella
228
229
  def create_http_client
229
230
  opts = {
230
231
  :proxy => @proxy.uri || nil, # a tautology for clarity
231
- :agent_name => "Stella/#{Stella::VERSION}",
232
+ :agent_name => Stella.agent,
232
233
  :from => nil
233
234
  }
234
235
  http_client = HTTPClient.new opts
data/lib/stella/engine.rb CHANGED
@@ -97,6 +97,7 @@ class Stella::Testrun < Storable
97
97
  field :repetitions => Integer
98
98
  field :wait => Float
99
99
  field :nowait => TrueClass
100
+ field :logsize => Integer
100
101
  field :granularity => Integer
101
102
  field :withparam => TrueClass
102
103
  field :withheader => TrueClass
@@ -104,15 +105,18 @@ class Stella::Testrun < Storable
104
105
  field :nostats => TrueClass
105
106
  field :stats => Hash
106
107
  field :samples => Array
108
+ field :event_probes => Array
109
+ field :agent => String
107
110
  field :mode # verify or generate
108
111
  field :plan
109
112
  field :hosts
110
- field :events
111
113
  field :log
112
114
  gibbler :plan, :hosts, :mode, :clients, :duration, :repetitions, :wait, :start_time, :userid
113
115
  def initialize(plan=nil, opts={})
114
116
  @plan = plan
115
117
  @granularity = GRANULARITY
118
+ @logsize = 1
119
+ @log = []
116
120
  process_options! opts if !plan.nil? && !opts.empty?
117
121
  reset_stats
118
122
  end
@@ -137,33 +141,7 @@ class Stella::Testrun < Storable
137
141
  return Time.now.utc.to_i - @start_time if @end_time.nil? || @end_time <= 0
138
142
  @end_time - @start_time
139
143
  end
140
-
141
- def self.from_hash(hash={})
142
- me = super(hash)
143
- me.plan = Stella::Testplan.from_hash(me.plan)
144
- me.process_options! unless me.plan.nil?
145
-
146
- me.samples.collect! do |sample|
147
- Stella::Testrun::Sample.from_hash(sample)
148
- end
149
-
150
- me.plan.usecases.uniq.each_with_index do |uc,i|
151
- uc.requests.each do |req|
152
- me.events.each_with_index do |event,idx| # do_request, etc...
153
- event &&= event.to_s
154
- me.stats[uc.id][req.id][event] =
155
- Benelux::Stats::Calculator.from_hash(me.stats[uc.id][req.id][event])
156
- me.stats[uc.id]['summary'][event] =
157
- Benelux::Stats::Calculator.from_hash(me.stats[uc.id]['summary'][event])
158
- me.stats['summary'][event] =
159
- Benelux::Stats::Calculator.from_hash(me.stats['summary'][event])
160
- end
161
- end
162
- end
163
-
164
- me
165
- end
166
-
144
+
167
145
  def client_options
168
146
  opts = {
169
147
  :nowait => self.nowait || false,
@@ -201,11 +179,13 @@ class Stella::Testrun < Storable
201
179
  @stats ||= { :summary => {} }
202
180
 
203
181
  @status ||= "new"
204
- @events ||= [:response_time, :failed]
182
+ if @event_probes.nil? || @event_probes.empty?
183
+ @event_probes = ['response_time', 'response_content_size']
184
+ end
205
185
 
206
186
  @start_time ||= Time.now.to_i
207
187
 
208
- @events.collect! { |event| event.to_sym }
188
+ @event_probes.collect! { |event| event.to_s }
209
189
 
210
190
  @duration ||= 0
211
191
  @repetitions ||= 0
@@ -278,6 +258,7 @@ class Stella::Testrun < Storable
278
258
 
279
259
 
280
260
  def run(opts={})
261
+ Stella.agent = @agent unless @agent.nil? || @agent.empty?
281
262
  engine = case self.mode
282
263
  when :verify
283
264
  Stella::Engine::Functional.new(opts)
@@ -304,20 +285,60 @@ class Stella::Testrun < Storable
304
285
  @stats = { 'summary' => {} }
305
286
  unless @plan.nil?
306
287
  @plan.usecases.each do |uc|
307
- @events.each do |event|
288
+ @event_probes.each do |event|
308
289
  event &&= event.to_s
309
290
  @stats['summary'][event] = Benelux::Stats::Calculator.new
310
291
  @stats[uc.id] ||= { 'summary' => {} }
311
292
  @stats[uc.id]['summary'][event] = Benelux::Stats::Calculator.new
293
+ @stats[uc.id]['summary']['status'] ||= {}
294
+ @stats['summary']['status'] ||= {}
312
295
  uc.requests.each do |req|
313
296
  @stats[uc.id][req.id] ||= {}
314
297
  @stats[uc.id][req.id][event] = Benelux::Stats::Calculator.new
298
+ @stats[uc.id][req.id]['status'] ||= {}
315
299
  end
316
300
  end
317
301
  end
318
302
  end
319
303
  end
320
304
 
305
+
306
+ def self.from_hash(hash={})
307
+ me = super(hash)
308
+ me.plan = Stella::Testplan.from_hash(me.plan)
309
+ me.process_options! unless me.plan.nil?
310
+
311
+ me.samples.collect! do |sample|
312
+ Stella::Testrun::Sample.from_hash(sample)
313
+ end
314
+
315
+ me.plan.usecases.uniq.each_with_index do |uc,i|
316
+ uc.requests.each do |req|
317
+ me.event_probes.each_with_index do |event,idx| # do_request, etc...
318
+ event &&= event.to_s
319
+ next unless me.stats[uc.id][req.id].has_key?(event)
320
+ next if Benelux::Stats::Calculator === me.stats[uc.id][req.id][event]
321
+ me.stats[uc.id][req.id][event] =
322
+ Benelux::Stats::Calculator.from_hash(me.stats[uc.id][req.id][event])
323
+ me.stats[uc.id]['summary'][event] =
324
+ Benelux::Stats::Calculator.from_hash(me.stats[uc.id]['summary'][event])
325
+ me.stats['summary'][event] =
326
+ Benelux::Stats::Calculator.from_hash(me.stats['summary'][event])
327
+ end
328
+ end
329
+ end
330
+
331
+ me
332
+ end
333
+
334
+ def has_errors?
335
+ return false if @samples.nil? || @samples.empty?
336
+ @samples.each { |sam|
337
+ return true if sam.has_errors?
338
+ }
339
+ false
340
+ end
341
+
321
342
  def add_sample batch, concurrency, tl
322
343
 
323
344
  opts = {
@@ -334,14 +355,35 @@ class Stella::Testrun < Storable
334
355
  uc.requests.each do |req|
335
356
  sam.stats[uc.id][req.id] ||= {}
336
357
  filter = [uc.id, req.id]
337
- @events.each_with_index do |event,idx| # do_request, etc...
358
+ @event_probes.each_with_index do |event,idx| # do_request, etc...
338
359
  event &&= event.to_s
339
- stats = tl.stats.group(event.to_sym)[filter].merge
340
- sam.stats[uc.id][req.id][event] = stats
360
+ stats = tl.stats.group(event.to_sym)[filter]
361
+ unless sam.stats[uc.id][req.id].has_key?(event)
362
+ stats[uc.id][req.id][event] ||= {}
363
+ @stats[uc.id][req.id][event] ||= Benelux::Stats::Calculator.new
364
+ @stats[uc.id]['summary'][event] ||= Benelux::Stats::Calculator.new
365
+ @stats['summary'][event] ||= Benelux::Stats::Calculator.new
366
+ end
367
+ # When we don't merge the stats from benelux,
368
+ # the each calculator contains just one sample.
369
+ # So when we grab the sum, it's just one event sample.
370
+ sam.stats[uc.id][req.id][event] = stats.collect {|c| c.sum }
341
371
  # Tally request, usecase and total summaries at the same time.
342
- @stats[uc.id][req.id][event] += stats
343
- @stats[uc.id]['summary'][event] += stats
344
- @stats['summary'][event] += stats
372
+ @stats[uc.id][req.id][event] += stats.merge
373
+ @stats[uc.id]['summary'][event] += stats.merge
374
+ @stats['summary'][event] += stats.merge
375
+ end
376
+ resp = tl.stats.group(:execute_response_handler)[filter]
377
+ resp.tag_values(:status).each do |status|
378
+ sam.stats[uc.id][req.id]['status'] ||= {}
379
+ count = resp[:status => status].size
380
+ sam.stats[uc.id][req.id]['status'][status.to_i] = count
381
+ end
382
+ tmp = tl.messages.filter([filter, :exception].flatten)
383
+ unless tmp.empty?
384
+ sam.errors[uc.id] ||= {}
385
+ sam.errors[uc.id][req.id] ||= []
386
+ sam.errors[uc.id][req.id].push *tmp
345
387
  end
346
388
  end
347
389
  end
@@ -358,27 +400,31 @@ class Stella::Testrun < Storable
358
400
  field :stamp
359
401
  field :duration
360
402
  field :stats => Hash
403
+ field :errors => Hash
361
404
  #gibbler :batch, :concurrency, :stamp, :duration
362
405
  def initialize(opts={})
363
406
  opts.each_pair do |n,v|
364
407
  self.send("#{n}=", v) if has_field? n
365
408
  end
366
- @stats = { }
409
+ @stats, @errors = {}, {}
410
+ end
411
+ def has_errors?
412
+ !@errors.nil? && !@errors.empty?
367
413
  end
368
414
  def self.from_hash(hash={})
369
415
  me = super(hash)
370
- stats = {}
416
+ #stats = {}
371
417
  me.stats.each_pair { |ucid,uchash|
372
- stats[ucid] = {}
373
418
  uchash.each_pair { |reqid,reqhash|
374
- stats[ucid][reqid] = {}
375
- reqhash.each_pair { |event,stat|
376
- tmp = Benelux::Stats::Calculator.from_hash(stat)
377
- stats[ucid][reqid][event] = tmp
378
- }
379
- }
419
+ if me.stats[ucid][reqid].has_key? 'status'
420
+ me.stats[ucid][reqid]['status'].each_pair do |status,value|
421
+ me.stats[ucid][reqid]['status'].delete status
422
+ me.stats[ucid][reqid]['status'][status.to_i] = value.to_i
423
+ end
424
+ end
425
+ }
380
426
  }
381
- me.stats = stats
427
+ #me.stats = stats
382
428
  me
383
429
  end
384
430
  end
@@ -31,8 +31,6 @@ module Stella::Engine
31
31
  Load.counts = [:request_header_size, :request_content_size]
32
32
  Load.counts += [:response_headers_size, :response_content_size]
33
33
  end
34
-
35
- events = [Load.timers, Load.counts, :failed].flatten
36
34
 
37
35
  testrun.save
38
36
 
@@ -196,8 +194,13 @@ module Stella::Engine
196
194
  concurrency = @threads.select { |t| !t.status.nil? }.size
197
195
  batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
198
196
  testrun.add_sample batch, concurrency, timeline
199
- if batch == 1 # only save the first batch
200
- testrun.log = Benelux.timeline.messages.filter(:kind => :log)
197
+ testrun.log = [] unless testrun.has_log?
198
+ if testrun.log.size < testrun.logsize
199
+ tmp = Benelux.timeline.messages.filter(:kind => :log)
200
+ unless tmp.nil? || tmp.empty?
201
+ # grab only as many elements from the log as configured
202
+ testrun.log.push *tmp.first(testrun.logsize-testrun.log.size)
203
+ end
201
204
  end
202
205
  testrun.save
203
206
  @failog.info Benelux.timeline.messages.filter(:kind => :exception)
@@ -426,6 +429,8 @@ module Stella::Engine
426
429
  end
427
430
 
428
431
  def update_error_execute_response_handler(client_id, ex, req, container)
432
+ Benelux.thread_timeline.add_message ex.message, :kind => :exception
433
+ Benelux.thread_timeline.add_count :exception, 1
429
434
  desc = "#{container.usecase.desc} > #{req.desc}"
430
435
  if Stella.stdout.lev == 2
431
436
  Stella.stdout.print 2, '.'.color(:red)
@@ -436,6 +441,8 @@ module Stella::Engine
436
441
  end
437
442
 
438
443
  def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
444
+ Benelux.thread_timeline.add_message ex.message, :kind => :exception
445
+ Benelux.thread_timeline.add_count :error, 1
439
446
  desc = "#{usecase.desc} > #{req.desc}"
440
447
  if Stella.stdout.lev == 2
441
448
  Stella.stdout.print 2, '.'.color(:red)
@@ -446,28 +453,23 @@ module Stella::Engine
446
453
  end
447
454
 
448
455
  def update_usecase_quit client_id, msg, req, container
449
- args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
450
456
  Benelux.thread_timeline.add_count :quit, 1
451
- args.push [req, container.status, 'QUIT', msg, container.unique_id[0,10]]
452
- Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
457
+ Benelux.thread_timeline.add_message msg, :kind => :quit
453
458
  Stella.stdout.info3 " Client-%s QUIT %s" % [client_id.shorter, msg]
454
459
  end
455
460
 
456
461
  def update_request_fail client_id, msg, req, container
457
- args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
458
462
  Benelux.thread_timeline.add_count :failed, 1
459
- args.push [req, container.status, 'FAIL', msg, container.unique_id[0,10]]
460
- Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
463
+ Benelux.thread_timeline.add_message msg, :kind => :fail
461
464
  Stella.stdout.info3 " Client-%s FAILED %s" % [client_id.shorter, msg]
462
465
  end
463
466
 
464
467
  def update_request_error client_id, msg, req, container
465
468
  args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
466
- Benelux.thread_timeline.add_count :error, 1
467
- args.push [req, container.status, 'ERROR', msg, container.unique_id[0,10]]
468
- Benelux.thread_timeline.add_message args.join('; '), :kind => :exception
469
+ Benelux.thread_timeline.add_count :exception, 1
470
+ Benelux.thread_timeline.add_message msg, :kind => :exception
469
471
  if Stella.stdout.lev >= 3
470
- Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
472
+ Stella.le ' Client-%s %s' % [client_id.shorter, ex.message]
471
473
  end
472
474
  end
473
475
 
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.4.001"
8
+ s.version = "0.8.5.001"
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-19}
12
+ s.date = %q{2010-03-29}
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}
@@ -618,7 +618,7 @@ class HTTPClient
618
618
  req.version = $1.to_f
619
619
  end
620
620
  end
621
- if @agent_name && req.header.get('User-Agent').nil?
621
+ if @agent_name && req.header.get('User-Agent').empty?
622
622
  req.header.set('User-Agent', "#{@agent_name}")
623
623
  end
624
624
  if @from
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.4.001
4
+ version: 0.8.5.001
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-19 00:00:00 -04:00
12
+ date: 2010-03-29 00:00:00 -04:00
13
13
  default_executable: stella
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency