stella 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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