stella 0.8.8.001 → 2.0.1.001

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/CHANGES.txt +9 -1
  2. data/Gemfile +19 -0
  3. data/Gemfile.lock +50 -0
  4. data/README.md +5 -79
  5. data/Rakefile +10 -7
  6. data/Rudyfile +1 -1
  7. data/TODO +31 -0
  8. data/VERSION.yml +3 -4
  9. data/bin/stella +23 -81
  10. data/certs/README.txt +17 -0
  11. data/certs/cacerts.pem +1529 -0
  12. data/certs/gd-class2-root.crt +24 -0
  13. data/certs/gd_bundle.crt +76 -0
  14. data/certs/gd_intermediate.crt +29 -0
  15. data/certs/startssl-ca.pem +44 -0
  16. data/certs/startssl-sub.class1.server.ca.pem +36 -0
  17. data/certs/stella-master.crt +1738 -0
  18. data/lib/stella.rb +191 -123
  19. data/lib/stella/cli.rb +47 -67
  20. data/lib/stella/client.rb +424 -360
  21. data/lib/stella/core_ext.rb +527 -0
  22. data/lib/stella/engine.rb +126 -419
  23. data/lib/stella/report.rb +391 -0
  24. data/lib/stella/testplan.rb +432 -306
  25. data/lib/stella/utils.rb +227 -2
  26. data/stella.gemspec +56 -55
  27. data/try/00_basics_try.rb +29 -0
  28. data/try/01_selectable_try.rb +25 -0
  29. data/try/09_utils_try.rb +67 -0
  30. data/try/10_stella_object_try.rb +49 -0
  31. data/try/40_report_try.rb +133 -0
  32. data/try/90_class_syntax_try.rb +13 -0
  33. data/try/emhttp.rb +62 -0
  34. data/try/rubyroute.rb +70 -0
  35. data/try/support/file.bmp +0 -0
  36. data/try/support/file.gif +0 -0
  37. data/try/support/file.ico +0 -0
  38. data/try/support/file.jpeg +0 -0
  39. data/try/support/file.jpg +0 -0
  40. data/try/support/file.png +0 -0
  41. data/try/traceviz.rb +60 -0
  42. data/vendor/httpclient-2.1.5.2/httpclient/session.rb +5 -2
  43. metadata +81 -53
  44. data/examples/cookies/plan.rb +0 -49
  45. data/examples/csvdata/plan.rb +0 -32
  46. data/examples/csvdata/search_terms.csv +0 -14
  47. data/examples/dynamic/plan.rb +0 -60
  48. data/examples/essentials/logo.png +0 -0
  49. data/examples/essentials/plan.rb +0 -248
  50. data/examples/essentials/search_terms.txt +0 -19
  51. data/examples/exceptions/plan.rb +0 -20
  52. data/examples/httpauth/plan.rb +0 -33
  53. data/examples/timeout/plan.rb +0 -18
  54. data/examples/variables/plan.rb +0 -41
  55. data/lib/stella/client/container.rb +0 -378
  56. data/lib/stella/common.rb +0 -363
  57. data/lib/stella/data.rb +0 -59
  58. data/lib/stella/data/http.rb +0 -189
  59. data/lib/stella/engine/functional.rb +0 -156
  60. data/lib/stella/engine/load.rb +0 -516
  61. data/lib/stella/guidelines.rb +0 -18
  62. data/lib/stella/logger.rb +0 -150
  63. data/lib/stella/utils/httputil.rb +0 -266
  64. data/try/01_numeric_mixins_tryouts.rb +0 -40
  65. data/try/12_digest_tryouts.rb +0 -42
  66. data/try/70_module_usage.rb +0 -21
  67. data/try/api/10_functional.rb +0 -20
  68. data/try/configs/failed_requests.rb +0 -31
  69. data/try/configs/global_sequential.rb +0 -18
  70. data/try/proofs/thread_queue.rb +0 -21
@@ -1,156 +0,0 @@
1
-
2
- module Stella::Engine
3
- class Functional < Stella::Engine::Base
4
-
5
- def run(testrun)
6
- client = Stella::Client.new testrun.hosts.first, testrun.client_options
7
- client.add_observer(self)
8
-
9
- p testrun.client_options
10
-
11
- Stella.stdout.info2 $/, "Starting test...", $/
12
- testrun.start_time = Time.now.utc.to_i
13
-
14
- start_time = Time.now.utc
15
-
16
- thread = Thread.new do
17
- # Identify this thread to Benelux
18
- Benelux.current_track :functional
19
-
20
- dig = Stella.stdout.lev > 1 ? testrun.plan.id : testrun.plan.id.shorter
21
- Stella.stdout.info " %-65s ".att(:reverse) % ["#{testrun.plan.desc} (#{dig})"]
22
- testrun.plan.usecases.each_with_index do |uc,i|
23
- desc = (uc.desc || "Usecase ##{i+1}")
24
- Benelux.add_thread_tags :usecase => uc.id
25
- dig = Stella.stdout.lev > 1 ? uc.id : uc.id.shorter
26
- Stella.stdout.info ' %-65s '.att(:reverse).bright % ["#{desc} (#{dig}) "]
27
- Stella.rescue { client.execute uc }
28
- end
29
- end
30
-
31
- thread.join
32
-
33
- test_time = Time.now.utc - start_time
34
-
35
- # Need to use thread timeline b/c the clients are running in the
36
- # main thread which Benelux.update_global_timeline does not touch.
37
- tt = thread.timeline
38
-
39
- testrun
40
- end
41
-
42
-
43
- def update_prepare_request(client_id, usecase, req, counter)
44
- notice = "repeat: #{counter-1}" if counter > 1
45
- dig = Stella.stdout.lev > 1 ? req.id : req.id.shorter
46
- desc = "#{req.desc} (#{dig}) "
47
- Stella.stdout.info2 " %-46s %16s ".bright % [desc, notice]
48
- end
49
-
50
-
51
- def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
52
- log = Stella::Engine::Log.new Time.now.to_f, container.unique_id, client_id,
53
- 'testplanid',
54
- usecase.id, req.id,
55
- req.http_method, container.status, uri.to_s,
56
- params, container.response.request.header.dump,
57
- container.response.header.dump,
58
- container.response.body.content
59
-
60
- Benelux.thread_timeline.add_message log, :status => container.status, :kind => :log
61
-
62
- msg = ' %-6s %-53s ' % [req.http_method, uri]
63
- msg << container.status.to_s if Stella.stdout.lev <= 2
64
- Stella.stdout.info msg
65
-
66
- Stella.stdout.info2 $/, " Params:"
67
- params.each do |pair|
68
- Stella.stdout.info2 " %s: %s" % pair
69
- end
70
-
71
- Stella.stdout.info3 $/, ' ' << container.response.request.header.send(:request_line)
72
-
73
- container.response.request.header.all.each do |pair|
74
- Stella.stdout.info3 " %s: %s" % pair
75
- end
76
-
77
- if req.http_method == 'POST'
78
- cont = container.response.request.body.content
79
- if String === cont
80
- Stella.stdout.info4(' ' << cont.split($/).join("#{$/} "))
81
- elsif HTTP::Message::Body::Parts === cont
82
- cont.parts.each do |part|
83
- if File === part
84
- Stella.stdout.info4 "<#{part.path}>"
85
- else
86
- Stella.stdout.info4 part
87
- end
88
- end
89
- end
90
- end
91
-
92
- resh = container.response.header
93
- Stella.stdout.info3 $/, ' HTTP/%s %3d %s' % [resh.http_version, resh.status_code, resh.reason_phrase]
94
- container.headers.all.each do |pair|
95
- Stella.stdout.info3 " %s: %s" % pair
96
- end
97
- Stella.stdout.info4 container.body.empty? ? ' [empty]' : container.body
98
- Stella.stdout.info2 $/
99
- end
100
-
101
- def update_execute_response_handler(client_id, req, container)
102
- end
103
-
104
- def update_error_execute_response_handler(client_id, ex, req, container)
105
- Stella.le "#{ex.message} (#{ex.backtrace.first})"
106
- Stella.ld ex.backtrace
107
- end
108
-
109
- def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
110
- #desc = "#{usecase.desc} > #{req.desc}"
111
- Stella.le ' ERROR %24s %s' % [ex.message, uri]
112
- Stella.le ' %s' % params.inspect
113
- unless req.headers.nil? || req.headers.empty?
114
- Stella.le ' %s' % req.headers.inspect
115
- end
116
- Stella.ld ex.backtrace
117
- end
118
-
119
- def update_follow_redirect client_id, ret, req, container
120
- Stella.stdout.info2 " FOLLOW %-53s" % [ret.uri]
121
- end
122
-
123
- def update_max_redirects client_id, counter, ret, req, container
124
- Stella.stdout.info " MAX REDIRECTS %-53s" % [counter]
125
- end
126
-
127
- def update_usecase_quit client_id, msg, req, container
128
- Benelux.thread_timeline.add_count :failed, 1
129
- Stella.stdout.info " QUIT %s" % [msg]
130
- end
131
-
132
- def update_request_fail client_id, msg, req, container
133
- Benelux.thread_timeline.add_count :failed, 1
134
- Stella.stdout.info " FAILED %s" % [msg]
135
- end
136
-
137
- def update_request_error client_id, msg, req, container
138
- Benelux.thread_timeline.add_count :failed, 1
139
- Stella.stdout.info " ERROR %s" % [msg]
140
- end
141
-
142
- def update_request_repeat client_id, counter, total, req, container
143
- Stella.stdout.info3 " REPEAT %d of %d" % [counter, total]
144
- end
145
-
146
- def update_authenticate client_id, usecase, req, domain, user, pass
147
- Stella.stdout.info " AUTH #{domain} (#{user}/#{pass})"
148
- end
149
-
150
- def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container, timeout)
151
- Benelux.thread_timeline.add_count :failed, 1
152
- Stella.stdout.info " TIMEOUT(%f) %-53s" % [uri, timeout]
153
- end
154
-
155
- end
156
- end
@@ -1,516 +0,0 @@
1
-
2
- module Stella::Engine
3
- class Load < Stella::Engine::Base
4
-
5
- @timers = [:response_time]
6
- @counts = [:response_content_size]
7
-
8
- def run(testrun)
9
- @threads, @max_clients, @real_reps = [], 0, 0
10
- counts = calculate_usecase_clients testrun
11
- packages = build_thread_package testrun, counts
12
-
13
- unless Stella::Logger.disabled?
14
- Stella.stdout.info "Logging to #{testrun.log_dir}", $/
15
-
16
- latest = File.join(File.dirname(testrun.log_dir), 'latest')
17
- if Stella.sysinfo.os == :unix
18
- File.unlink latest if File.exists? latest
19
- FileUtils.ln_sf File.basename(testrun.log_dir), latest
20
- end
21
- end
22
-
23
- @sumlog = Stella::Logger.new testrun.log_path('summary')
24
- @failog = Stella::Logger.new testrun.log_path('exceptions')
25
-
26
- Stella.stdout.add_template :head, ' %s: %s'
27
- Stella.stdout.add_template :status, "#{$/}%s..."
28
-
29
- if Stella.stdout.lev >= 2
30
- Load.timers += [:socket_connect, :send_request, :first_byte, :receive_response]
31
- Load.counts = [:request_header_size, :request_content_size]
32
- Load.counts += [:response_headers_size, :response_content_size]
33
- end
34
-
35
- testrun.save
36
-
37
- @dumper = prepare_dumper(testrun)
38
-
39
- if testrun.duration > 0
40
- timing = "#{testrun.duration.seconds.to_i} seconds"
41
- else
42
- timing = "#{testrun.repetitions} repetitions"
43
- end
44
-
45
- Stella.stdout.head "Runid", "#{testrun.id.shorter}"
46
- Stella.stdout.head 'Plan', "#{testrun.plan.desc} (#{testrun.plan.id.shorter})"
47
- Stella.stdout.head 'Hosts', testrun.hosts.join(', ')
48
- Stella.stdout.head 'Clients', counts[:total]
49
- Stella.stdout.head 'Limit', timing
50
- Stella.stdout.head 'Wait', testrun.wait
51
- Stella.stdout.head 'Arrival', testrun.arrival if testrun.arrival
52
-
53
- @dumper.start
54
-
55
- begin
56
- Stella.stdout.status "Running"
57
- testrun.status = "running"
58
- testrun.start_time = Time.now.utc.to_i
59
- execute_test_plan packages, testrun
60
- rescue Interrupt
61
- Stella.stdout.info $/, "Stopping test"
62
- Stella.abort!
63
- @threads.each { |t| t.join } unless @threads.nil? || @threads.empty? # wait
64
- rescue => ex
65
- STDERR.puts "Unhandled exception: #{ex.message}"
66
- STDERR.puts ex.backtrace if Stella.debug? || Stella.stdout.lev >= 3
67
- end
68
-
69
- Stella.stdout.status "Processing"
70
-
71
- @dumper.stop
72
-
73
- bt = Benelux.timeline
74
- tt = Benelux.thread_timeline
75
-
76
- # TODO: don't get test time from benelux.
77
- test_time = tt.stats.group(:execute_test_plan).mean
78
- generate_report @sumlog, testrun, test_time
79
- #report_time = tt.stats.group(:generate_report).mean
80
-
81
- unless Stella::Logger.disabled?
82
- Stella.stdout.info File.read(@sumlog.path)
83
- Stella.stdout.info $/, "Log dir: #{testrun.log_dir}"
84
- end
85
-
86
- testrun
87
- end
88
-
89
- def execute_test_plan(packages, testrun)
90
- time_started = Time.now
91
-
92
- pqueue = Queue.new
93
- packages.each { |p| pqueue << p }
94
-
95
- @real_reps += 1 # Increments when duration is specified.
96
- @threads = []
97
- packages.size.times {
98
- @max_clients += 1
99
- @threads << Thread.new do
100
- package = pqueue.pop
101
- Thread.current[:real_reps] = 0
102
- Thread.current[:real_uctime] = Benelux::Stats::Calculator.new
103
- c, uc = package.client, package.usecase
104
- Stella.stdout.info4 $/, "======== THREAD %s: START" % [c.id.short]
105
-
106
- # This thread will stay on this one track.
107
- Benelux.current_track c.id
108
-
109
- Benelux.add_thread_tags :usecase => uc.id
110
- Thread.current[:real_uctime].first_tick
111
- prev_ptime ||= Time.now
112
- testrun.repetitions.times { |rep|
113
- break if Stella.abort?
114
- Thread.current[:real_reps] += 1
115
- # NOTE: It's important to not call digest or gibbler methods
116
- # on client object b/c it is not frozen. Always use digest_cache.
117
- args = [c.id.short, uc.desc, uc.id.short, Thread.current[:real_reps]]
118
- Stella.stdout.info4 $/, "======== THREAD %s: %s:%s (rep: %d)" % args
119
-
120
- Benelux.add_thread_tags :rep => rep
121
- #Stella.stdout.info [package.client.gibbler.shorter, package.usecase.gibbler.shorter, rep].inspect
122
- Stella::Engine::Load.rescue(c.id) {
123
- break if Stella.abort?
124
- print '.' if Stella.stdout.lev == 2
125
- stats = c.execute uc
126
- }
127
- Benelux.remove_thread_tags :rep
128
-
129
- Thread.current[:real_uctime].tick
130
- time_elapsed = (Time.now - time_started).to_i
131
-
132
- if (Time.now - prev_ptime).to_i >= testrun.granularity
133
- prev_ptime, ruct = Time.now, Thread.current[:real_uctime]
134
- if Stella.stdout.lev >= 2 && Thread.current == @threads.first
135
- args = [time_elapsed.to_i, ruct.n, ruct.mean, ruct.sd]
136
- Stella.stdout.info2 $/, "REAL UC TIME: %ds (reps: %d): %.4fs %.4f(SD)" % args
137
- end
138
-
139
- Thread.current.rotate_timeline
140
- end
141
-
142
- # If a duration was given, we make sure
143
- # to run for only that amount of time.
144
- if testrun.duration > 0
145
- break if (time_elapsed+Thread.current[:real_uctime].mean) >= testrun.duration
146
- redo if (time_elapsed+Thread.current[:real_uctime].mean) <= testrun.duration
147
- end
148
- }
149
-
150
- Benelux.remove_thread_tags :usecase
151
-
152
- pqueue << package # return the package to the queue
153
- end
154
-
155
- #p [testrun.arrival, 1/testrun.arrival]
156
-
157
- unless testrun.arrival.nil? || testrun.arrival.to_f <= 0
158
- # Create 1 second / users per second
159
- args = [@threads.size, packages.size]
160
- Stella.stdout.print 2, '+'
161
- Stella.stdout.info3 $/, "-> NEW CLIENT: %s of %s" % args
162
- sleep 1/testrun.arrival
163
- end
164
-
165
- }
166
-
167
- repscalc = Benelux::Stats::Calculator.new
168
- @threads.each { |t| t.join } # wait
169
- @threads.each { |t| repscalc.sample(t[:real_reps]) }
170
- @real_reps = repscalc.mean.to_i
171
-
172
-
173
- #Stella.stdout.info "*** REPETITION #{@real_reps} of #{reps} ***"
174
-
175
- Stella.stdout.info2 $/, $/
176
- end
177
-
178
-
179
- protected
180
- class ThreadPackage
181
- attr_accessor :index
182
- attr_accessor :client
183
- attr_accessor :usecase
184
- def initialize(i, c, u)
185
- @index, @client, @usecase = i, c, u
186
- end
187
- end
188
-
189
- def prepare_dumper(testrun)
190
- hand = Stella::Hand.new(testrun.granularity, 2.seconds) do
191
- Benelux.update_global_timeline
192
- # @threads contains only stella clients
193
- concurrency = @threads.select { |t| !t.status.nil? }.size
194
- batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
195
- testrun.add_sample batch, concurrency, timeline
196
- testrun.log = [] unless testrun.has_log?
197
- if testrun.log.size < testrun.logsize
198
- tmp = Benelux.timeline.messages.filter(:kind => :log)
199
- unless tmp.nil? || tmp.empty?
200
- # grab only as many elements from the log as configured
201
- testrun.log.push *tmp.first(testrun.logsize-testrun.log.size)
202
- end
203
- end
204
- testrun.save
205
- @failog.info Benelux.timeline.messages.filter(:kind => :exception)
206
- @failog.info Benelux.timeline.messages.filter(:kind => :timeout)
207
- Benelux.timeline.clear if testrun.nostats
208
- end
209
- hand.finally do
210
- testrun.end_time = Time.now.utc.to_i
211
- testrun.save
212
- end
213
- hand
214
- end
215
-
216
- def generate_report(sumlog,testrun,test_time)
217
- global_timeline = Benelux.timeline
218
- global_stats = global_timeline.stats.group(:response_time).merge
219
- if global_stats.n == 0
220
- Stella.ld "No stats"
221
- return
222
- end
223
-
224
- @sumlog.info " %-72s ".att(:reverse) % ["#{testrun.plan.desc} (#{testrun.plan.id.shorter})"]
225
- testrun.plan.usecases.uniq.each_with_index do |uc,i|
226
-
227
- # TODO: Create Ranges object, like Stats object
228
- # global_timeline.ranges(:response_time)[:usecase => '1111']
229
- # The following returns global response_time ranges.
230
- requests = 0 #global_timeline.ranges(:response_time).size
231
-
232
- desc = uc.desc || "Usecase ##{i+1} "
233
- desc << " (#{uc.id.shorter}) "
234
- str = ' ' << " %-66s %s %d%% ".bright.att(:reverse)
235
- @sumlog.info str % [desc, '', uc.ratio_pretty]
236
- uc.requests.each do |req|
237
- filter = [uc.id, req.id]
238
- desc = req.desc
239
- @sumlog.info " %-72s ".bright % ["#{req.desc} (#{req.id.shorter})"]
240
- @sumlog.info " %s" % [req.to_s]
241
-
242
- Load.timers.each do |sname|
243
- stats = global_timeline.stats.group(sname)[filter].merge
244
- # Stella.stdout.info stats.inspect
245
- str = ' %-30s %.3f <= ' << '%.3fs' << ' >= %.3f; %.3f(SD) %d(N)'
246
- msg = str % [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n]
247
- @sumlog.info msg
248
- @sumlog.flush
249
- end
250
- @sumlog.info $/
251
- end
252
-
253
- @sumlog.info " Sub Total:".bright
254
-
255
- stats = global_timeline.stats.group(:response_time)[uc.id].merge
256
- failed = global_timeline.stats.group(:failed)[uc.id].merge
257
- respgrp = global_timeline.stats.group(:execute_response_handler)[uc.id]
258
- resst = respgrp.tag_values(:status)
259
-
260
- Load.timers.each do |sname|
261
- stats = global_timeline.stats.group(sname)[uc.id].merge
262
- @sumlog.info ' %-30s %.3fs %.3f(SD)' % [sname, stats.mean, stats.sd]
263
- @sumlog.flush
264
- end
265
-
266
- Load.counts.each do |sname|
267
- stats = global_timeline.stats.group(sname)[uc.id].merge
268
- @sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
269
- @sumlog.flush
270
- end
271
- @sumlog.info $/
272
- statusi = []
273
- resst.each do |status|
274
- size = respgrp[:status => status].size
275
- statusi << "#{status}: #{size}"
276
- end
277
- @sumlog.info ' %-30s %d (%s)' % ['Total requests', stats.n, statusi.join(', ')]
278
- @sumlog.info ' %-29s %d' % [:success, stats.n - failed.n]
279
- @sumlog.info ' %-29s %d' % [:failed, failed.n]
280
-
281
- @sumlog.info $/
282
- end
283
-
284
- @sumlog.info ' ' << " %-66s ".att(:reverse) % 'Total:'
285
- @sumlog.flush
286
-
287
- failed = global_timeline.stats.group(:failed)
288
- respgrp = global_timeline.stats.group(:execute_response_handler)
289
- resst = respgrp.tag_values(:status)
290
- statusi = []
291
- resst.each do |status|
292
- size = respgrp[:status => status].size
293
- statusi << [status, size]
294
- end
295
-
296
- Load.timers.each do |sname|
297
- stats = global_timeline.stats.group(sname).merge
298
- @sumlog.info ' %-30s %-.3fs %-.3f(SD)' % [sname, stats.mean, stats.sd]
299
- @sumlog.flush
300
- end
301
-
302
- Load.counts.each do |sname|
303
- stats = global_timeline.stats.group(sname).merge
304
- @sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
305
- @sumlog.flush
306
- end
307
-
308
- @sumlog.info $/
309
- @sumlog.info ' %-30s %d' % ['Total requests', global_stats.n]
310
-
311
- success = global_stats.n - failed.n
312
- @sumlog.info ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
313
- statusi.each do |pair|
314
- @sumlog.info3 ' %-28s %s: %d' % ['', *pair]
315
- end
316
- @sumlog.info ' %-29s %d' % [:failed, failed.n]
317
-
318
- @sumlog.flush
319
-
320
- end
321
-
322
-
323
- def calculate_usecase_clients(testrun)
324
- counts = { :total => 0 }
325
- testrun.plan.usecases.each_with_index do |usecase,i|
326
- count = case testrun.clients
327
- when 0..9
328
- if (testrun.clients % testrun.plan.usecases.size > 0)
329
- msg = "Client count (%d) does not evenly match usecase count (%d)"
330
- raise Stella::WackyRatio, (msg % [testrun.clients, testrun.plan.usecases.size])
331
- else
332
- (testrun.clients / testrun.plan.usecases.size)
333
- end
334
- else
335
- (testrun.clients * usecase.ratio).to_i
336
- end
337
- counts[usecase.id] = count
338
- counts[:total] += count
339
- end
340
- counts
341
- end
342
-
343
-
344
- def build_thread_package(testrun, counts)
345
- packages, pointer = Array.new(counts[:total]), 0
346
- testrun.plan.usecases.each do |usecase|
347
- count = counts[usecase.id]
348
- Stella.ld "THREAD PACKAGE: #{usecase.desc} (#{pointer} + #{count})"
349
- # Fill the thread_package with the contents of the block
350
- packages.fill(pointer, count) do |index|
351
- client = Stella::Client.new testrun.hosts.first, testrun.client_options
352
- client.add_observer(self)
353
- Stella.stdout.info4 "Created client #{client.id.short}"
354
- ThreadPackage.new(index+1, client, usecase)
355
- end
356
- pointer += count
357
- end
358
- packages.compact # TODO: Why one nil element sometimes?
359
- # Randomize so when ramping up load
360
- # we get a mix of usecases.
361
- packages.sort_by {rand}
362
- end
363
-
364
-
365
- def running_threads
366
- @threads.select { |t| t.status } # non-false status are still running
367
- end
368
-
369
- def generate_runtime_report(testrun)
370
- gt = Benelux.timeline
371
- gstats = gt.stats.group(:response_time).merge
372
-
373
- testrun.plan.usecases.uniq.each_with_index do |uc,i|
374
- uc.requests.each do |req|
375
- filter = [uc.id, req.id]
376
-
377
- Load.timers.each do |sname|
378
- stats = gt.stats.group(sname)[filter].merge
379
- #Stella.stdout.info stats.inspect
380
- puts [sname, stats.min, stats.mean, stats.max, stats.sd, stats.n].join('; ')
381
- end
382
-
383
- end
384
- end
385
-
386
- end
387
-
388
- def update_prepare_request(client_id, usecase, req, counter)
389
-
390
- end
391
-
392
- def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
393
- if @opts[:with_content]
394
- log = Stella::Engine::Log.new Time.now.to_f, container.unique_id, client_id,
395
- 'testplanid',
396
- usecase.id, req.id,
397
- req.http_method, container.status, uri.to_s,
398
- params, container.response.request.header.dump,
399
- container.response.header.dump,
400
- container.response.body.dump
401
-
402
- # Fix for no data, but why??
403
- log.response_body = container.response.body.dump
404
- Benelux.thread_timeline.add_message log, :status => container.status, :kind => :log
405
- end
406
-
407
- args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
408
- args.push usecase.id.shorter, req.id.shorter
409
- args.push req.http_method, container.status, uri
410
- args << params.to_a.collect { |el|
411
- next if el[0].to_s == '__stella'
412
- '%s=%s' % [el[0], el[1].to_s]
413
- }.compact.join('&') # remove skipped params
414
- args << headers.to_a.collect { |el|
415
- next if el[0].to_s == 'X-Stella-ID'
416
- '%s=%s' % el
417
- }.compact.join('&') # remove skipped params
418
- args << container.unique_id[0,10]
419
- #Benelux.thread_timeline.add_message args.join('; '),
420
- # :status => container.status,
421
- # :kind => :request
422
- args = [client_id.shorter, container.status, req.http_method, uri, params.inspect]
423
- Stella.stdout.info3 ' Client-%s %3d %-6s %s %s' % args
424
-
425
- end
426
-
427
- def update_execute_response_handler(client_id, req, container)
428
- end
429
-
430
- def update_error_execute_response_handler(client_id, ex, req, container)
431
- Benelux.thread_timeline.add_message ex.message, :kind => :exception
432
- Benelux.thread_timeline.add_count :exception, 1
433
- desc = "#{container.usecase.desc} > #{req.desc}"
434
- if Stella.stdout.lev == 2
435
- Stella.stdout.print 2, '.'.color(:red)
436
- else
437
- Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
438
- Stella.ld ex.backtrace
439
- end
440
- end
441
-
442
- def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
443
- Benelux.thread_timeline.add_message ex.message, :kind => :exception
444
- Benelux.thread_timeline.add_count :exception, 1
445
- desc = "#{usecase.desc} > #{req.desc}"
446
- if Stella.stdout.lev == 2
447
- Stella.stdout.print 2, '.'.color(:red)
448
- else
449
- Stella.le ' Client-%s %-45s %s' % [client_id.shorter, desc, ex.message]
450
- Stella.ld ex.backtrace
451
- end
452
- end
453
-
454
- def update_usecase_quit client_id, msg, req, container
455
- Benelux.thread_timeline.add_count :quit, 1
456
- Benelux.thread_timeline.add_message msg, :kind => :quit
457
- Stella.stdout.info3 " Client-%s QUIT %s" % [client_id.shorter, msg]
458
- end
459
-
460
- def update_request_fail client_id, msg, req, container
461
- Benelux.thread_timeline.add_count :failed, 1
462
- Benelux.thread_timeline.add_message msg, :kind => :fail
463
- Stella.stdout.info3 " Client-%s FAILED %s" % [client_id.shorter, msg]
464
- end
465
-
466
- def update_request_error client_id, msg, req, container
467
- args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
468
- Benelux.thread_timeline.add_count :exception, 1
469
- Benelux.thread_timeline.add_message msg, :kind => :exception
470
- if Stella.stdout.lev >= 3
471
- Stella.le ' Client-%s %s' % [client_id.shorter, ex.message]
472
- end
473
- end
474
-
475
- def update_request_repeat client_id, counter, total, req, container
476
- Stella.stdout.info3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
477
- end
478
-
479
- def update_follow_redirect client_id, ret, req, container
480
- Stella.stdout.info3 " Client-%s FOLLOW %-53s" % [client_id.shorter, ret.uri]
481
- end
482
-
483
- def update_max_redirects client_id, counter, ret, req, container
484
- Stella.stdout.info3 " Client-%s MAX REDIRECTS %s " % [client_id.shorter, counter]
485
- end
486
-
487
- def update_authenticate client_id, usecase, req, domain, user, pass
488
- args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
489
- args.push usecase.id.shorter, req.id.shorter
490
- args.push 'AUTH', domain, user, pass
491
- Benelux.thread_timeline.add_message args.join('; '), :kind => :authentication
492
- end
493
-
494
- def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container, timeout)
495
- msg = " Client-%s TIMEOUT(%.1f) %-53s" % [client_id.shorter, timeout, uri]
496
- Stella.stdout.info3 msg
497
- Benelux.thread_timeline.add_count :exception, 1
498
- args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
499
- args.push [uri, 'TOUT', container.unique_id[0,10]]
500
- Benelux.thread_timeline.add_message msg , :kind => :exception
501
- end
502
-
503
- def self.rescue(client_id, &blk)
504
- blk.call
505
- rescue => ex
506
- Stella.le ' Error in Client-%s: %s' % [client_id.shorter, ex.message]
507
- Stella.ld ex.backtrace
508
- end
509
-
510
- Benelux.add_timer Stella::Engine::Load, :build_thread_package
511
- Benelux.add_timer Stella::Engine::Load, :generate_report
512
- Benelux.add_timer Stella::Engine::Load, :execute_test_plan
513
-
514
- end
515
- end
516
-