stella 0.7.1 → 0.7.2

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.
@@ -32,6 +32,7 @@ module Stella::Data::HTTP
32
32
  @uri = uri_str
33
33
  @http_method, @http_version = method, version
34
34
  @headers, @params, @response_handler = {}, {}, {}
35
+ @resources = {}
35
36
  @wait = 0
36
37
  @desc = "Request"
37
38
  @body = Stella::Data::HTTP::Body.new
@@ -55,13 +56,30 @@ module Stella::Data::HTTP
55
56
  alias_method :sleep, :wait
56
57
 
57
58
  def headers(*args)
58
- @headers.merge! args.first unless args.empty?
59
+ unless args.empty?
60
+ h = Hash === args[0] ? args[0] : {args[0]=> args[1]}
61
+ @headers.merge! h unless h.empty?
62
+ end
59
63
  @headers
60
64
  end
61
65
  alias_method :header, :headers
62
66
 
67
+ # Set a resource key value pair in the get, post block.
68
+ # These will be process later in Stella::Client
69
+ def set(*args)
70
+ unless args.empty?
71
+ h = Hash === args[0] ? args[0] : {args[0]=> args[1]}
72
+ @resources.merge! h unless h.empty?
73
+ end
74
+ @resources
75
+ end
76
+ alias_method :resources, :set
77
+
63
78
  def params(*args)
64
- @params.merge! args.first unless args.empty?
79
+ unless args.empty?
80
+ h = Hash === args[0] ? args[0] : {args[0]=> args[1]}
81
+ @params.merge! h unless h.empty?
82
+ end
65
83
  @params
66
84
  end
67
85
  alias_method :param, :params
data/lib/stella/engine.rb CHANGED
@@ -10,13 +10,17 @@ module Stella::Engine
10
10
  def update(*args)
11
11
  what, *args = args
12
12
  if respond_to?("update_#{what}")
13
- Stella.ld "OBSERVER UPDATE: #{what}"
13
+ #Stella.ld "OBSERVER UPDATE: #{what}"
14
14
  Stella.rescue { self.send("update_#{what}", *args) }
15
15
  else
16
16
  Stella.ld "NO UPDATE HANDLER FOR: #{what}"
17
17
  end
18
18
  end
19
-
19
+
20
+ def runid
21
+
22
+ end
23
+
20
24
  def process_options!(plan, opts={})
21
25
  opts = {
22
26
  :hosts => [],
@@ -19,6 +19,9 @@ module Stella::Engine
19
19
  Stella.lflush
20
20
  sleep 0.3
21
21
 
22
+ # Identify this thread to Benelux
23
+ Benelux.current_track :functional
24
+
22
25
  dig = Stella.loglev > 1 ? plan.digest_cache : plan.digest_cache.shorter
23
26
  Stella.li " %-65s ".att(:reverse) % ["#{plan.desc} (#{dig})"]
24
27
  plan.usecases.each_with_index do |uc,i|
@@ -28,11 +31,8 @@ module Stella::Engine
28
31
  Stella.rescue { client.execute uc }
29
32
  end
30
33
 
31
- #Benelux.update_all_track_timelines
32
- #tl = Benelux.timeline
33
-
34
- # errors?
35
-
34
+ tl = Benelux.thread_timeline
35
+ tl.stats.group(:failed).merge.n == 0
36
36
  end
37
37
 
38
38
 
@@ -44,30 +44,42 @@ module Stella::Engine
44
44
  end
45
45
 
46
46
  def update_receive_response(client_id, usecase, uri, req, params, counter, container)
47
- msg = ' %-59s ' % [uri]
47
+ msg = ' %-6s %-53s ' % [req.http_method, uri]
48
48
  msg << container.status.to_s if Stella.loglev == 1
49
49
  Stella.li msg
50
50
 
51
- Stella.li2 ' ' << container.response.request.header.send(:request_line)
52
-
53
- Stella.li2 $/, " Request-Params:"
51
+ Stella.li2 $/, " Params:"
54
52
  params.each do |pair|
55
53
  Stella.li2 " %s: %s" % pair
56
54
  end
57
55
 
58
- Stella.li2 $/, " Request-Headers:"
56
+ Stella.li2 $/, ' ' << container.response.request.header.send(:request_line)
57
+
59
58
  container.response.request.header.all.each do |pair|
60
- Stella.li2 " %s: %s" % pair
59
+ Stella.li2 " %s: %s" % pair
61
60
  end
62
61
 
63
- Stella.li2 $/, " Response-Status: %3d" % [container.status]
62
+ if req.http_method == 'POST'
63
+ cont = container.response.request.body.content
64
+ if String === cont
65
+ Stella.li2 (' ' << cont.split($/).join("#{$/} "))
66
+ elsif HTTP::Message::Body::Parts === cont
67
+ cont.parts.each do |part|
68
+ if File === part
69
+ Stella.li2 "<#{part.path}>"
70
+ else
71
+ Stella.li2 part
72
+ end
73
+ end
74
+ end
75
+ end
64
76
 
65
- Stella.li2 $/, " Response-Headers:"
77
+ resh = container.response.header
78
+ Stella.li2 $/, ' HTTP/%s %3d %s' % [resh.http_version, resh.status_code, resh.reason_phrase]
66
79
  container.headers.all.each do |pair|
67
- Stella.li2 " %s: %s" % pair
80
+ Stella.li2 " %s: %s" % pair
68
81
  end
69
- Stella.li3 $/, " Response-Content:"
70
- Stella.li3 container.body.empty? ? ' [empty]' : container.body
82
+ Stella.li4 container.body.empty? ? ' [empty]' : container.body
71
83
  Stella.li2 $/
72
84
  end
73
85
 
@@ -76,22 +88,25 @@ module Stella::Engine
76
88
 
77
89
  def update_error_execute_response_handler(client_id, ex, req, container)
78
90
  Stella.le ex.message
79
- Stella.li3 ex.backtrace
91
+ Stella.ld ex.backtrace
80
92
  end
81
93
 
82
94
  def update_request_error(client_id, usecase, uri, req, params, ex)
83
95
  desc = "#{usecase.desc} > #{req.desc}"
84
96
  Stella.le ' Client-%s %-45s %s' % [client_id.short, desc, ex.message]
85
- Stella.li3 ex.backtrace
97
+ Stella.ld ex.backtrace
86
98
  end
87
99
 
88
100
  def update_quit_usecase client_id, msg
89
- Stella.li4 " Client-%s QUIT %s" % [client_id.shorter, msg]
101
+ Stella.li " QUIT %s" % [msg]
90
102
  end
91
103
 
104
+ def update_fail_request client_id, msg
105
+ Stella.li " FAILED %s" % [msg]
106
+ end
92
107
 
93
108
  def update_repeat_request client_id, counter, total
94
- Stella.li4 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
109
+ Stella.li3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
95
110
  end
96
111
 
97
112
  end
@@ -7,6 +7,8 @@ module Stella::Engine
7
7
 
8
8
 
9
9
  def execute_test_plan(packages, reps=1, duration=0)
10
+ @mode = :rolling
11
+
10
12
  time_started = Time.now
11
13
 
12
14
  (1..reps).to_a.each { |rep|
@@ -4,7 +4,7 @@ module Stella::Engine
4
4
  extend Stella::Engine::Base
5
5
  extend Stella::Engine::Load
6
6
  extend self
7
-
7
+ ROTATE_TIMELINE = 15
8
8
  def execute_test_plan(packages, reps=1,duration=0)
9
9
  time_started = Time.now
10
10
 
@@ -46,13 +46,15 @@ module Stella::Engine
46
46
  Thread.current[:real_uctime].tick
47
47
  time_elapsed = (Time.now - time_started).to_i
48
48
 
49
- if Stella.loglev >= 2 &&
50
- Thread.current == @threads.first &&
51
- (Time.now - prev_ptime).to_i >= 5
49
+ if (Time.now - prev_ptime).to_i >= ROTATE_TIMELINE
52
50
  prev_ptime, ruct = Time.now, Thread.current[:real_uctime]
53
- args = [time_elapsed.to_i, ruct.n, ruct.mean, ruct.sd]
54
- Stella.li2 $/, "REAL UC TIME: %ds (reps: %d): %.4fs %.4f(SD)" % args
55
- Stella.lflush
51
+ if Stella.loglev >= 2 && Thread.current == @threads.first
52
+ args = [time_elapsed.to_i, ruct.n, ruct.mean, ruct.sd]
53
+ Stella.li2 $/, "REAL UC TIME: %ds (reps: %d): %.4fs %.4f(SD)" % args
54
+ Stella.lflush
55
+ end
56
+
57
+ Thread.current.rotate_timeline
56
58
  end
57
59
 
58
60
  # If a duration was given, we make sure
@@ -69,6 +71,24 @@ module Stella::Engine
69
71
  end
70
72
  }
71
73
 
74
+ data_dumper = Thread.new do
75
+ prev_ptime = Time.now
76
+ loop do
77
+ break if Stella.abort?
78
+ break if @threads.select { |t| (!t.nil? && t.status) }.empty?
79
+ if (Time.now - prev_ptime).to_i >= (ROTATE_TIMELINE * 4)
80
+ Benelux.update_global_timeline
81
+ Stella.li $/, [:logger, (Time.now - prev_ptime).to_i, Benelux.timeline.size].inspect
82
+ prev_ptime = Time.now
83
+ ##TODO: Dump to file
84
+ ##Benelux.timeline.clear
85
+ end
86
+ sleep 5
87
+ end
88
+
89
+ end
90
+ data_dumper.join
91
+
72
92
  repscalc = Benelux::Stats::Calculator.new
73
93
  @threads.each { |t| t.join } # wait
74
94
  @threads.each { |t| repscalc.sample(t[:real_reps]) }
@@ -36,7 +36,7 @@ module Stella::Engine
36
36
  Stella.li "Generating requests #{msg}...", $/
37
37
  Stella.lflush
38
38
 
39
- @mode = :rolling
39
+ bt = Benelux.timeline
40
40
 
41
41
  begin
42
42
  execute_test_plan packages, opts[:repetitions], opts[:duration]
@@ -49,8 +49,7 @@ module Stella::Engine
49
49
  Stella.lflush
50
50
 
51
51
  Benelux.update_global_timeline
52
-
53
- bt = Benelux.timeline
52
+
54
53
  tt = Benelux.thread_timeline
55
54
 
56
55
  test_time = tt.stats.group(:execute_test_plan).mean
@@ -71,7 +70,7 @@ module Stella::Engine
71
70
  Stella.li $/
72
71
  end
73
72
 
74
- # errors?
73
+ bt.stats.group(:failed).merge.n == 0
75
74
  end
76
75
 
77
76
  protected
@@ -111,7 +110,9 @@ module Stella::Engine
111
110
  Stella.ld "THREAD PACKAGE: #{usecase.desc} (#{pointer} + #{count})"
112
111
  # Fill the thread_package with the contents of the block
113
112
  packages.fill(pointer, count) do |index|
114
- client = Stella::Client.new opts[:hosts].first, index+1
113
+ copts = {}
114
+ copts[:parse_templates] = false if opts[:'disable-templates']
115
+ client = Stella::Client.new opts[:hosts].first, index+1, copts
115
116
  client.add_observer(self)
116
117
  client.enable_nowait_mode if opts[:nowait]
117
118
  Stella.li4 "Created client #{client.digest.short}"
@@ -132,6 +133,11 @@ module Stella::Engine
132
133
  def generate_report(plan,test_time)
133
134
  #Benelux.update_all_track_timelines
134
135
  global_timeline = Benelux.timeline
136
+ global_stats = global_timeline.stats.group(:do_request).merge
137
+ if global_stats.n == 0
138
+ Stella.ld "No stats"
139
+ return
140
+ end
135
141
 
136
142
  Stella.li $/, " %-72s ".att(:reverse) % ["#{plan.desc} (#{plan.digest_cache.shorter})"]
137
143
  plan.usecases.uniq.each_with_index do |uc,i|
@@ -191,7 +197,7 @@ module Stella::Engine
191
197
  end
192
198
 
193
199
  Stella.li ' ' << " %-66s ".att(:reverse) % 'Total:'
194
- stats = global_timeline.stats.group(:do_request).merge
200
+
195
201
  failed = global_timeline.stats.group(:failed)
196
202
  respgrp = global_timeline.stats.group(:execute_response_handler)
197
203
  resst = respgrp.tag_values(:status)
@@ -200,8 +206,8 @@ module Stella::Engine
200
206
  size = respgrp[:status => status].size
201
207
  statusi << [status, size]
202
208
  end
203
- Stella.li ' %-30s %d' % ['Total requests', stats.n]
204
- success = stats.n - failed.n
209
+ Stella.li ' %-30s %d' % ['Total requests', global_stats.n]
210
+ success = global_stats.n - failed.n
205
211
  Stella.li ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
206
212
  statusi.each do |pair|
207
213
  Stella.li2 ' %-28s %s: %d' % ['', *pair]
@@ -229,7 +235,9 @@ module Stella::Engine
229
235
 
230
236
  def update_receive_response(client_id, usecase, uri, req, params, counter, container)
231
237
  desc = "#{usecase.desc} > #{req.desc}"
232
- Stella.li3 ' Client-%s %3d %-6s %-45s' % [client_id.shorter, container.status, req.http_method, uri]
238
+ args = [client_id.shorter, container.status, req.http_method, uri, params.inspect]
239
+ Stella.li3 ' Client-%s %3d %-6s %s %s' % args
240
+ Stella.ld ' Client-%s %3d %s' % [client_id.shorter, container.status, container.body]
233
241
  end
234
242
 
235
243
  def update_execute_response_handler(client_id, req, container)
@@ -239,20 +247,23 @@ module Stella::Engine
239
247
  desc = "#{container.usecase.desc} > #{req.desc}"
240
248
  Stella.li $/ if Stella.loglev == 1
241
249
  Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
242
- Stella.li3 ex.backtrace
250
+ Stella.li ex.backtrace
243
251
  end
244
252
 
245
253
  def update_request_error(client_id, usecase, uri, req, params, ex)
246
254
  desc = "#{usecase.desc} > #{req.desc}"
247
255
  Stella.li $/ if Stella.loglev == 1
248
256
  Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
249
- Stella.li3 ex.backtrace
257
+ Stella.li ex.backtrace
250
258
  end
251
259
 
252
260
  def update_quit_usecase client_id, msg
253
261
  Stella.li3 " Client-%s QUIT %s" % [client_id.shorter, msg]
254
262
  end
255
263
 
264
+ def update_fail_request client_id, msg
265
+ Stella.li3 " Client-%s FAILED %s" % [client_id.shorter, msg]
266
+ end
256
267
 
257
268
  def update_repeat_request client_id, counter, total
258
269
  Stella.li3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
@@ -262,7 +273,6 @@ module Stella::Engine
262
273
  blk.call
263
274
  rescue => ex
264
275
  Stella.le ' Error in Client-%s: %s' % [client_id.shorter, ex.message]
265
- Stella.li3 ex.backtrace
266
276
  end
267
277
 
268
278
  Benelux.add_timer Stella::Engine::Load, :build_thread_package
@@ -7,6 +7,7 @@ class Testplan
7
7
  extend Attic
8
8
 
9
9
  attic :base_path
10
+ attic :plan_path
10
11
 
11
12
  attr_accessor :usecases
12
13
  attr_accessor :desc
@@ -36,8 +37,9 @@ class Testplan
36
37
  conf = File.read path
37
38
  plan = Stella::Testplan.new
38
39
  plan.base_path = File.dirname path
40
+ plan.plan_path = path
39
41
  # eval so the DSL code can be executed in this namespace.
40
- plan.instance_eval conf
42
+ plan.instance_eval conf, path
41
43
  plan
42
44
  end
43
45
 
@@ -58,6 +60,7 @@ class Testplan
58
60
 
59
61
  # make sure all clients share identical test plans
60
62
  def freeze
63
+ Stella.ld "FREEZE TESTPLAN: #{desc}"
61
64
  @usecases.each { |uc| uc.freeze }
62
65
  super
63
66
  self
@@ -70,6 +73,7 @@ class Testplan
70
73
  ratio, name = args[1], args[0] if args[0].is_a?(String)
71
74
  uc = Stella::Testplan::Usecase.new
72
75
  uc.base_path = self.base_path
76
+ uc.plan_path = self.plan_path
73
77
  uc.instance_eval &blk
74
78
  uc.ratio, uc.desc = (ratio || -1).to_f, name
75
79
  @testplan_current_ratio += uc.ratio if uc.ratio > 0
@@ -97,6 +101,9 @@ class Testplan
97
101
  desc = uc.desc || "Usecase ##{i+1}"
98
102
  desc += " (#{dig}) "
99
103
  str << (' ' << " %-61s %s%% ".att(:reverse).bright) % [desc, uc.ratio_pretty]
104
+ unless uc.http_auth.nil?
105
+ str << ' Auth: %s (%s/%s)' % uc.http_auth.values
106
+ end
100
107
  requests = uc.requests.each do |r|
101
108
  dig = long ? r.digest_cache : r.digest_cache.shorter
102
109
  str << " %-62s".bright % ["#{r.desc} (#{dig})"]
@@ -21,10 +21,16 @@ class Testplan
21
21
  include Gibbler::Complex
22
22
  extend Attic
23
23
 
24
+ class Auth < Struct.new(:kind, :user, :pass)
25
+ include Gibbler::Complex
26
+ end
27
+
24
28
  attic :base_path # we don't want gibbler to see this
29
+ attic :plan_path
25
30
 
26
31
  attr_accessor :desc
27
32
  attr_writer :ratio
33
+ attr_reader :http_auth
28
34
 
29
35
  attr_accessor :requests
30
36
  attr_accessor :resources
@@ -63,15 +69,17 @@ class Testplan
63
69
  # directory is assumed to be the same directory containing the test plan).
64
70
  def read(path)
65
71
  path = File.join(base_path, path) if base_path
72
+ Stella.ld "READING FILE: #{path}"
66
73
  File.read(path)
67
74
  end
68
-
75
+
69
76
  def list(path)
70
77
  read(path).split $/
71
78
  end
72
79
 
73
80
  def csv(path)
74
81
  path = File.join(base_path, path) if base_path
82
+ Stella.ld "READING CSV: #{path}"
75
83
  CSV.read(path)
76
84
  end
77
85
 
@@ -81,6 +89,11 @@ class Testplan
81
89
  self
82
90
  end
83
91
 
92
+ def auth(user, pass=nil, kind=:basic)
93
+ @http_auth ||= Auth.new
94
+ @http_auth.user, @http_auth.pass, @http_auth.kind = user, pass, kind
95
+ end
96
+
84
97
  def add_request(meth, *args, &blk)
85
98
  req = Stella::Data::HTTP::Request.new meth.to_s.upcase, args[0], &blk
86
99
  req.desc = args[1] if args.size > 1 # Description is optional
@@ -5,10 +5,10 @@ module Stella
5
5
  unless defined?(MAJOR)
6
6
  MAJOR = 0.freeze
7
7
  MINOR = 7.freeze
8
- TINY = 1.freeze
8
+ TINY = 2.freeze
9
9
  PATCH = '001'.freeze
10
10
  end
11
- def self.to_s; [MAJOR, MINOR, TINY, PATCH].join('.'); end
11
+ def self.to_s; [MAJOR, MINOR, TINY].join('.'); end
12
12
  def self.to_f; self.to_s.to_f; end
13
13
  def self.patch; PATCH; end
14
14
  end