stella 0.8.1.002 → 0.8.2.001
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.gitmodules +4 -0
- data/CHANGES.txt +15 -1
- data/Rakefile +38 -51
- data/VERSION.yml +5 -0
- data/bin/stella +0 -4
- data/lib/stella.rb +15 -12
- data/lib/stella/cli.rb +3 -12
- data/lib/stella/client.rb +0 -1
- data/lib/stella/common.rb +16 -0
- data/lib/stella/engine.rb +39 -23
- data/lib/stella/engine/functional.rb +2 -3
- data/lib/stella/engine/{load_queue.rb → load.rb} +4 -4
- data/lib/stella/engine/loadbase.rb +51 -75
- data/lib/stella/logger.rb +13 -13
- data/lib/stella/service.rb +2 -2
- data/lib/stella/testplan.rb +5 -2
- data/lib/stella/utils.rb +1 -1
- data/stella.gemspec +124 -88
- data/tryouts/70_module_usage.rb +15 -0
- metadata +23 -22
- data/lib/stella/engine/load_create.rb +0 -91
- data/lib/stella/engine/load_em.rb +0 -139
- data/lib/stella/engine/load_package.rb +0 -38
- data/lib/threadify.rb +0 -165
@@ -1,10 +1,10 @@
|
|
1
|
+
require 'stella/engine/loadbase'
|
1
2
|
|
2
3
|
module Stella::Engine
|
3
|
-
module
|
4
|
-
extend Stella::Engine::Base
|
4
|
+
module Load
|
5
5
|
extend Stella::Engine::Load
|
6
6
|
extend self
|
7
|
-
ROTATE_TIMELINE =
|
7
|
+
ROTATE_TIMELINE = 5
|
8
8
|
def execute_test_plan(packages, reps=1,duration=0,arrival=nil)
|
9
9
|
time_started = Time.now
|
10
10
|
|
@@ -90,7 +90,7 @@ module Stella::Engine
|
|
90
90
|
Stella.stdout.info2 $/, $/
|
91
91
|
end
|
92
92
|
|
93
|
-
Benelux.add_timer Stella::Engine::
|
93
|
+
Benelux.add_timer Stella::Engine::Load, :execute_test_plan
|
94
94
|
|
95
95
|
end
|
96
96
|
end
|
@@ -4,17 +4,16 @@ module Stella::Engine
|
|
4
4
|
extend Stella::Engine::Base
|
5
5
|
extend self
|
6
6
|
|
7
|
-
@timers = [:
|
7
|
+
@timers = [:response_time]
|
8
8
|
@counts = [:response_content_size]
|
9
9
|
@reqlog = nil
|
10
10
|
@logdir = nil
|
11
11
|
|
12
12
|
class << self
|
13
|
-
attr_accessor :timers, :counts, :logdir
|
13
|
+
attr_accessor :timers, :counts, :logdir, :testrun
|
14
14
|
end
|
15
15
|
|
16
16
|
def run(plan, opts={})
|
17
|
-
|
18
17
|
opts = process_options! plan, opts
|
19
18
|
@threads, @max_clients, @real_reps = [], 0, 0
|
20
19
|
|
@@ -26,30 +25,16 @@ module Stella::Engine
|
|
26
25
|
File.unlink latest if File.exists? latest
|
27
26
|
FileUtils.ln_sf File.basename(@logdir), latest
|
28
27
|
end
|
29
|
-
|
30
|
-
@reqlog = Stella::Logger.new log_path(plan, 'requests')
|
31
|
-
@failog = Stella::Logger.new log_path(plan, 'requests-exceptions')
|
32
|
-
@sumlog = Stella::Logger.new log_path(plan, 'summary')
|
33
|
-
@optlog = Stella::Logger.new log_path(plan, 'options')
|
34
|
-
@authlog = Stella::Logger.new log_path(plan, 'requests-auth')
|
35
|
-
|
36
|
-
@syslog = Stella::Logger.new log_path(plan, 'sysinfo')
|
37
|
-
@syslog.info(Stella.sysinfo.dump(:yaml)) and @syslog.close
|
38
|
-
|
39
|
-
@plalog = Stella::Logger.new log_path(plan, 'plan')
|
40
|
-
@plalog.info(plan.pretty.noansi) and @plalog.close
|
41
28
|
|
29
|
+
@statlog_path = log_path(plan, 'stats')
|
30
|
+
@sumlog = Stella::Logger.new log_path(plan, 'summary')
|
31
|
+
@failog = Stella::Logger.new log_path(plan, 'exceptions')
|
42
32
|
|
43
33
|
Stella.stdout.add_template :head, ' %s: %s'
|
44
34
|
Stella.stdout.add_template :status, "#{$/}%s..."
|
45
35
|
|
46
|
-
|
47
|
-
|
48
|
-
@optlog.add_template :head, '%10s: %s'
|
49
|
-
@failog.add_template :request, '%s %s'
|
50
|
-
|
51
|
-
if Stella.stdout.lev > 2
|
52
|
-
Load.timers += [:query, :connect, :socket_gets_first_byte, :get_body]
|
36
|
+
if Stella.stdout.lev >= 2
|
37
|
+
Load.timers += [:socket_connect, :send_request, :first_byte, :receive_response]
|
53
38
|
Load.counts = [:request_header_size, :request_content_size]
|
54
39
|
Load.counts += [:response_headers_size, :response_content_size]
|
55
40
|
end
|
@@ -64,13 +49,12 @@ module Stella::Engine
|
|
64
49
|
Stella.stdout.head 'Testrun', @testrun.remote_digest
|
65
50
|
end
|
66
51
|
|
52
|
+
@testrun.save(@statlog_path)
|
53
|
+
|
67
54
|
@dumper = prepare_dumper(plan, opts)
|
68
55
|
|
69
56
|
counts = calculate_usecase_clients plan, opts
|
70
57
|
|
71
|
-
@optlog.head 'RUNID', runid(plan)
|
72
|
-
@optlog.head 'OPTIONS', opts.inspect
|
73
|
-
|
74
58
|
packages = build_thread_package plan, opts, counts
|
75
59
|
|
76
60
|
if opts[:duration] > 0
|
@@ -80,13 +64,15 @@ module Stella::Engine
|
|
80
64
|
end
|
81
65
|
|
82
66
|
Stella.stdout.head 'Plan', "#{plan.desc} (#{plan.digest.shorter})"
|
67
|
+
Stella.stdout.head 'Hosts', opts[:hosts].join(', ')
|
83
68
|
Stella.stdout.head 'Clients', counts[:total]
|
84
69
|
Stella.stdout.head 'Limit', timing
|
85
70
|
|
71
|
+
Stella.stdout.head 'Arrival', opts[:arrival] if opts[:arrival]
|
72
|
+
|
86
73
|
@dumper.start
|
87
74
|
|
88
75
|
begin
|
89
|
-
@optlog.head "START", Time.now.to_s
|
90
76
|
Stella.stdout.status "Running"
|
91
77
|
execute_test_plan packages, opts[:repetitions], opts[:duration], opts[:arrival]
|
92
78
|
rescue Interrupt
|
@@ -100,15 +86,11 @@ module Stella::Engine
|
|
100
86
|
|
101
87
|
Stella.stdout.status "Processing"
|
102
88
|
|
103
|
-
@optlog.head "END", Time.now.to_s
|
104
|
-
@optlog.flush
|
105
|
-
|
106
89
|
@dumper.stop
|
107
90
|
|
108
91
|
bt = Benelux.timeline
|
109
92
|
tt = Benelux.thread_timeline
|
110
93
|
|
111
|
-
|
112
94
|
# TODO: don't get test time from benelux.
|
113
95
|
test_time = tt.stats.group(:execute_test_plan).mean
|
114
96
|
generate_report @sumlog, plan, test_time
|
@@ -118,7 +100,7 @@ module Stella::Engine
|
|
118
100
|
|
119
101
|
Stella.stdout.info $/, "Log dir: #{@logdir}"
|
120
102
|
|
121
|
-
@testrun.
|
103
|
+
@testrun.stats[:summary][:failed].n == 0
|
122
104
|
end
|
123
105
|
|
124
106
|
protected
|
@@ -132,41 +114,26 @@ module Stella::Engine
|
|
132
114
|
end
|
133
115
|
|
134
116
|
def prepare_dumper(plan, opts)
|
135
|
-
hand = Stella::Hand.new(
|
117
|
+
hand = Stella::Hand.new(Load::ROTATE_TIMELINE, 2.seconds) do
|
136
118
|
Benelux.update_global_timeline
|
137
119
|
# @threads contains only stella clients
|
138
120
|
concurrency = @threads.select { |t| !t.status.nil? }.size
|
139
121
|
batch, timeline = Benelux.timeline_updates, Benelux.timeline_chunk
|
140
122
|
@testrun.add_sample batch, concurrency, timeline
|
141
|
-
|
142
|
-
#reqlog.info [Time.now, Benelux.timeline.size].inspect
|
143
|
-
@reqlog.info Benelux.timeline.messages.filter(:kind => :request)
|
123
|
+
@testrun.save(@statlog_path)
|
144
124
|
@failog.info Benelux.timeline.messages.filter(:kind => :exception)
|
145
125
|
@failog.info Benelux.timeline.messages.filter(:kind => :timeout)
|
146
|
-
@authlog.info Benelux.timeline.messages.filter(:kind => :authentication)
|
147
|
-
@reqlog.clear and @failog.clear and @authlog.clear
|
148
|
-
|
149
126
|
Benelux.timeline.clear if opts[:"no-stats"]
|
150
|
-
|
151
127
|
end
|
152
128
|
hand.finally do
|
153
|
-
|
154
|
-
#failed = @testrun.stats[:summary][:failed].n
|
155
|
-
#@sumlog.info $/, "Summary: "
|
156
|
-
#@sumlog.dsummary 'successful req', total-failed
|
157
|
-
#@sumlog.dsummary "failed req", failed
|
158
|
-
#@sumlog.dsummary "max clients", @max_clients
|
159
|
-
#@sumlog.dsummary "repetitions", @real_reps
|
160
|
-
##@sumlog.fsummary "test time", test_time
|
161
|
-
##@sumlog.fsummary "reporting time", report_time
|
162
|
-
#@sumlog.flush
|
129
|
+
@testrun.save(@statlog_path)
|
163
130
|
end
|
164
131
|
hand
|
165
132
|
end
|
166
133
|
|
167
134
|
def generate_report(sumlog,plan,test_time)
|
168
135
|
global_timeline = Benelux.timeline
|
169
|
-
global_stats = global_timeline.stats.group(:
|
136
|
+
global_stats = global_timeline.stats.group(:response_time).merge
|
170
137
|
if global_stats.n == 0
|
171
138
|
Stella.ld "No stats"
|
172
139
|
return
|
@@ -176,9 +143,9 @@ module Stella::Engine
|
|
176
143
|
plan.usecases.uniq.each_with_index do |uc,i|
|
177
144
|
|
178
145
|
# TODO: Create Ranges object, like Stats object
|
179
|
-
# global_timeline.ranges(:
|
180
|
-
# The following returns
|
181
|
-
requests = 0 #global_timeline.ranges(:
|
146
|
+
# global_timeline.ranges(:response_time)[:usecase => '1111']
|
147
|
+
# The following returns global response_time ranges.
|
148
|
+
requests = 0 #global_timeline.ranges(:response_time).size
|
182
149
|
|
183
150
|
desc = uc.desc || "Usecase ##{i+1} "
|
184
151
|
desc << " (#{uc.digest_cache.shorter}) "
|
@@ -203,18 +170,10 @@ module Stella::Engine
|
|
203
170
|
|
204
171
|
@sumlog.info " Sub Total:".bright
|
205
172
|
|
206
|
-
stats = global_timeline.stats.group(:
|
173
|
+
stats = global_timeline.stats.group(:response_time)[uc.digest_cache].merge
|
207
174
|
failed = global_timeline.stats.group(:failed)[uc.digest_cache].merge
|
208
175
|
respgrp = global_timeline.stats.group(:execute_response_handler)[uc.digest_cache]
|
209
176
|
resst = respgrp.tag_values(:status)
|
210
|
-
statusi = []
|
211
|
-
resst.each do |status|
|
212
|
-
size = respgrp[:status => status].size
|
213
|
-
statusi << "#{status}: #{size}"
|
214
|
-
end
|
215
|
-
@sumlog.info ' %-30s %d (%s)' % ['Total requests', stats.n, statusi.join(', ')]
|
216
|
-
@sumlog.info ' %-29s %d' % [:success, stats.n - failed.n]
|
217
|
-
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
218
177
|
|
219
178
|
Load.timers.each do |sname|
|
220
179
|
stats = global_timeline.stats.group(sname)[uc.digest_cache].merge
|
@@ -228,9 +187,20 @@ module Stella::Engine
|
|
228
187
|
@sumlog.flush
|
229
188
|
end
|
230
189
|
@sumlog.info $/
|
190
|
+
statusi = []
|
191
|
+
resst.each do |status|
|
192
|
+
size = respgrp[:status => status].size
|
193
|
+
statusi << "#{status}: #{size}"
|
194
|
+
end
|
195
|
+
@sumlog.info ' %-30s %d (%s)' % ['Total requests', stats.n, statusi.join(', ')]
|
196
|
+
@sumlog.info ' %-29s %d' % [:success, stats.n - failed.n]
|
197
|
+
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
198
|
+
|
199
|
+
@sumlog.info $/
|
231
200
|
end
|
232
201
|
|
233
202
|
@sumlog.info ' ' << " %-66s ".att(:reverse) % 'Total:'
|
203
|
+
@sumlog.flush
|
234
204
|
|
235
205
|
failed = global_timeline.stats.group(:failed)
|
236
206
|
respgrp = global_timeline.stats.group(:execute_response_handler)
|
@@ -240,14 +210,7 @@ module Stella::Engine
|
|
240
210
|
size = respgrp[:status => status].size
|
241
211
|
statusi << [status, size]
|
242
212
|
end
|
243
|
-
|
244
|
-
success = global_stats.n - failed.n
|
245
|
-
@sumlog.info ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
|
246
|
-
statusi.each do |pair|
|
247
|
-
@sumlog.info3 ' %-28s %s: %d' % ['', *pair]
|
248
|
-
end
|
249
|
-
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
250
|
-
|
213
|
+
|
251
214
|
Load.timers.each do |sname|
|
252
215
|
stats = global_timeline.stats.group(sname).merge
|
253
216
|
@sumlog.info ' %-30s %-.3fs %-.3f(SD)' % [sname, stats.mean, stats.sd]
|
@@ -259,6 +222,19 @@ module Stella::Engine
|
|
259
222
|
@sumlog.info ' %-30s %-12s (avg:%s)' % [sname, stats.sum.to_bytes, stats.mean.to_bytes]
|
260
223
|
@sumlog.flush
|
261
224
|
end
|
225
|
+
|
226
|
+
@sumlog.info $/
|
227
|
+
@sumlog.info ' %-30s %d' % ['Total requests', global_stats.n]
|
228
|
+
|
229
|
+
success = global_stats.n - failed.n
|
230
|
+
@sumlog.info ' %-29s %d (req/s: %.2f)' % [:success, success, success/test_time]
|
231
|
+
statusi.each do |pair|
|
232
|
+
@sumlog.info3 ' %-28s %s: %d' % ['', *pair]
|
233
|
+
end
|
234
|
+
@sumlog.info ' %-29s %d' % [:failed, failed.n]
|
235
|
+
|
236
|
+
@sumlog.flush
|
237
|
+
|
262
238
|
end
|
263
239
|
|
264
240
|
|
@@ -314,7 +290,7 @@ module Stella::Engine
|
|
314
290
|
|
315
291
|
def generate_runtime_report(plan)
|
316
292
|
gt = Benelux.timeline
|
317
|
-
gstats = gt.stats.group(:
|
293
|
+
gstats = gt.stats.group(:response_time).merge
|
318
294
|
|
319
295
|
plan.usecases.uniq.each_with_index do |uc,i|
|
320
296
|
uc.requests.each do |req|
|
@@ -348,9 +324,9 @@ module Stella::Engine
|
|
348
324
|
'%s=%s' % el
|
349
325
|
}.compact.join('&') # remove skipped params
|
350
326
|
args << container.unique_id[0,10]
|
351
|
-
Benelux.thread_timeline.add_message args.join('; '),
|
352
|
-
|
353
|
-
|
327
|
+
#Benelux.thread_timeline.add_message args.join('; '),
|
328
|
+
# :status => container.status,
|
329
|
+
# :kind => :request
|
354
330
|
args = [client_id.shorter, container.status, req.http_method, uri, params.inspect]
|
355
331
|
Stella.stdout.info3 ' Client-%s %3d %-6s %s %s' % args
|
356
332
|
|
@@ -426,8 +402,8 @@ module Stella::Engine
|
|
426
402
|
|
427
403
|
def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container)
|
428
404
|
Stella.stdout.info3 " Client-%s TIMEOUT %-53s" % [client_id.shorter, uri]
|
429
|
-
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
430
405
|
Benelux.thread_timeline.add_count :failed, 1
|
406
|
+
args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
|
431
407
|
args.push [uri, 'TOUT', container.unique_id[0,10]]
|
432
408
|
Benelux.thread_timeline.add_message args.join('; '), :kind => :timeout
|
433
409
|
end
|
data/lib/stella/logger.rb
CHANGED
@@ -4,11 +4,7 @@ module Stella
|
|
4
4
|
|
5
5
|
|
6
6
|
class Logger
|
7
|
-
|
8
|
-
@@disable = false
|
9
|
-
def self.disable!() @@disable = true end
|
10
|
-
def self.disabled?() @@disable == true end
|
11
|
-
|
7
|
+
|
12
8
|
attr_accessor :lev
|
13
9
|
attr_reader :templates
|
14
10
|
|
@@ -17,10 +13,14 @@ module Stella
|
|
17
13
|
@lev, @offset = 1, 0
|
18
14
|
@templates = {}
|
19
15
|
@autoflush = false
|
20
|
-
|
16
|
+
@disable = false
|
21
17
|
self.output = output
|
22
18
|
end
|
23
19
|
|
20
|
+
def disable!() @disable = true end
|
21
|
+
def enable!() @disable = true end
|
22
|
+
def disabled?() @disable == true end
|
23
|
+
|
24
24
|
def autoflush!() @autoflush = true end
|
25
25
|
def autoflush?() @autoflush == true end
|
26
26
|
|
@@ -37,14 +37,14 @@ module Stella
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def print(level, *msg)
|
40
|
-
return if level > @lev ||
|
40
|
+
return if level > @lev || disabled?
|
41
41
|
@buffer.print *msg
|
42
42
|
flush if autoflush?
|
43
43
|
true
|
44
44
|
end
|
45
45
|
|
46
46
|
def puts(level, *msg)
|
47
|
-
return if level > @lev ||
|
47
|
+
return if level > @lev || disabled?
|
48
48
|
@buffer.puts *msg
|
49
49
|
flush if autoflush?
|
50
50
|
true
|
@@ -83,7 +83,7 @@ module Stella
|
|
83
83
|
|
84
84
|
# TODO: There's a big when using print (no newline)
|
85
85
|
def flush
|
86
|
-
return if
|
86
|
+
return if disabled?
|
87
87
|
@mutex.synchronize do
|
88
88
|
#return if @offset == @output.tell
|
89
89
|
@buffer.seek @offset
|
@@ -99,7 +99,7 @@ module Stella
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def clear
|
102
|
-
return if
|
102
|
+
return if disabled?
|
103
103
|
flush
|
104
104
|
@mutex.synchronize do
|
105
105
|
@buffer.rewind
|
@@ -108,7 +108,7 @@ module Stella
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def close
|
111
|
-
return if
|
111
|
+
return if disabled?
|
112
112
|
flush
|
113
113
|
@buffer.close
|
114
114
|
@output.close
|
@@ -120,7 +120,7 @@ module Stella
|
|
120
120
|
# Must call flush to send to output.
|
121
121
|
class SyncLogger < Logger
|
122
122
|
def print(level, *msg)
|
123
|
-
return if level > @lev ||
|
123
|
+
return if level > @lev || disabled?
|
124
124
|
@mutex.synchronize {
|
125
125
|
@buffer.print *msg
|
126
126
|
flush if autoflush?
|
@@ -130,7 +130,7 @@ module Stella
|
|
130
130
|
|
131
131
|
def puts(level, *msg)
|
132
132
|
#Stella.ld [level, @lev, msg]
|
133
|
-
return if level > @lev ||
|
133
|
+
return if level > @lev || disabled?
|
134
134
|
@mutex.synchronize {
|
135
135
|
@buffer.puts *msg
|
136
136
|
flush if autoflush?
|
data/lib/stella/service.rb
CHANGED
@@ -153,13 +153,13 @@ class Stella::Service
|
|
153
153
|
trun.remote_digest = obj['digest']
|
154
154
|
@runid = obj['digest']
|
155
155
|
end
|
156
|
-
def testrun_stats(
|
156
|
+
def testrun_stats(stats, samples)
|
157
157
|
raise NoTestrunSelected, "no testrun: #{runid}" unless @runid
|
158
158
|
req = uri('v1', 'testrun', "stats.json")
|
159
159
|
params = {
|
160
160
|
:runid => @runid,
|
161
161
|
:status => 'running',
|
162
|
-
:
|
162
|
+
:stats => stats.to_json,
|
163
163
|
:samples => samples.to_json
|
164
164
|
}
|
165
165
|
res = send_request :post, req, params
|
data/lib/stella/testplan.rb
CHANGED
@@ -41,7 +41,8 @@ class Testplan < Storable
|
|
41
41
|
# TODO: Add Stellar::TOKEN to the calculation
|
42
42
|
gibbler :id, :usecases, :description
|
43
43
|
|
44
|
-
def initialize(uris
|
44
|
+
def initialize(*uris)
|
45
|
+
uris.flatten!
|
45
46
|
self.description = "Test plan"
|
46
47
|
@usecases = []
|
47
48
|
@testplan_current_ratio = 0
|
@@ -56,7 +57,6 @@ class Testplan < Storable
|
|
56
57
|
uri = URI.parse uri
|
57
58
|
uri.path = '/' if uri.path.nil? || uri.path.empty?
|
58
59
|
req = usecase.add_request :get, uri.path
|
59
|
-
req.wait = opts[:wait] if opts[:wait]
|
60
60
|
end
|
61
61
|
self.add_usecase usecase
|
62
62
|
end
|
@@ -124,10 +124,12 @@ class Testplan < Storable
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def pretty(long=false)
|
127
|
+
self.digest # make sure we have values in the cache
|
127
128
|
str = []
|
128
129
|
dig = long ? self.digest_cache : self.digest_cache.shorter
|
129
130
|
str << " %-66s ".att(:reverse) % ["#{self.description} (#{dig})"]
|
130
131
|
@usecases.each_with_index do |uc,i|
|
132
|
+
uc.digest
|
131
133
|
dig = long ? uc.digest_cache : uc.digest_cache.shorter
|
132
134
|
desc = uc.description || "Usecase ##{i+1}"
|
133
135
|
desc += " (#{dig}) "
|
@@ -136,6 +138,7 @@ class Testplan < Storable
|
|
136
138
|
str << ' Auth: %s (%s/%s)' % uc.http_auth.values
|
137
139
|
end
|
138
140
|
requests = uc.requests.each do |r|
|
141
|
+
r.digest
|
139
142
|
dig = long ? r.digest_cache : r.digest_cache.shorter
|
140
143
|
str << " %-62s".bright % ["#{r.description} (#{dig})"]
|
141
144
|
str << " %s" % [r]
|
data/lib/stella/utils.rb
CHANGED
@@ -109,7 +109,7 @@ module Stella
|
|
109
109
|
end
|
110
110
|
|
111
111
|
# A basic file writer
|
112
|
-
def write_to_file(filename, content, mode, chmod=
|
112
|
+
def write_to_file(filename, content, mode, chmod=0600)
|
113
113
|
mode = (mode == :append) ? 'a' : 'w'
|
114
114
|
f = File.open(filename,mode)
|
115
115
|
f.puts content
|