stella 0.8.4.001 → 0.8.5.001

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 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