stella 0.7.6.007 → 0.8.0.000

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.
@@ -142,6 +142,28 @@ module Stella::Data::HTTP
142
142
  header[:Cookie]
143
143
  end
144
144
 
145
+ def freeze
146
+ @params = convert_values_to_templates @params
147
+ @headers = convert_values_to_templates @headers
148
+ super
149
+ self
150
+ end
151
+
152
+ private
153
+ def convert_values_to_templates(hash)
154
+ updated = {}
155
+ hash.each_pair { |k,v|
156
+ next if Stella::Template === v
157
+ if Proc === v
158
+ msg = "As of Stella 0.8, Procs are no longer supported as values#{$/}"
159
+ msg << "for parameters and headers (\"#{k}\" in \"#{description}\").#{$/}"
160
+ msg << "Use string templates instead. See the examples/ directory."
161
+ raise Stella::Error, msg
162
+ end
163
+ updated[k] = Stella::Template.new( v || '')
164
+ }
165
+ updated
166
+ end
145
167
  end
146
168
 
147
169
  end
data/lib/stella/data.rb CHANGED
@@ -4,353 +4,54 @@ module Stella::Data
4
4
 
5
5
  module Helpers
6
6
 
7
- def resource(name)
8
- Proc.new do
9
- resource name
10
- end
11
- end
7
+ def resource(args) to_templ(:resource, *args) end
12
8
 
13
9
  # Can include glob
14
10
  #
15
11
  # e.g.
16
12
  # random_file('avatar*')
17
- def random_file(*args)
18
- input = args.size > 1 ? args : args.first
19
- Proc.new do
20
- value = case input.class.to_s
21
- when "String"
22
- Stella.ld "FILE: #{input}"
23
- path = File.exists?(input) ? input : File.join(@base_path, input)
24
- files = Dir.glob(path)
25
- path = files[ rand(files.size) ]
26
- Stella.ld "Creating file object: #{path}"
27
- File.new(path)
28
- when "Proc"
29
- input.call
30
- else
31
- input
32
- end
33
- raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
34
- Stella.ld "FILE: #{value}"
35
- value
36
- end
37
- end
13
+ def random_file(*args) to_templ(:random_file, *args) end
38
14
 
39
- def read_file(*args)
40
- input = args.size > 1 ? args : args.first
41
- Proc.new do
42
- case input.class.to_s
43
- when "String"
44
- file(input).read # This is the file method defined in Container.
45
- when "Proc"
46
- input.call
47
- else
48
- input
49
- end
50
- end
51
- end
15
+ def read_file(*args) to_templ(:read_file, *args) end
52
16
 
53
- def path(*args)
54
- input = File.join *args
55
- Proc.new do
56
- File.exists?(input) ? input : File.join(@base_path, input)
57
- end
58
- end
17
+ def path(*args) to_templ(:path, *args) end
59
18
 
60
- def file(*args)
61
- input = args.size > 1 ? args : args.first
62
- Proc.new do
63
- value = case input.class.to_s
64
- when "String"
65
- Stella.ld "FILE: #{input}"
66
- path = File.exists?(input) ? input : File.join(@base_path, input)
67
- Stella.ld "Creating file object: #{path}"
68
- File.new(path)
69
- when "Proc"
70
- input.call
71
- else
72
- input
73
- end
74
- raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
75
- Stella.ld "FILE: #{value}"
76
- value
77
- end
78
- end
19
+ def file(*args) to_templ(:file, *args) end
79
20
 
80
21
  def random(*args)
81
- if Symbol === args.first
82
- input, index = *args
83
- elsif Array === args.first || args.size == 1
84
- input = args.first
85
- else
86
- input = args
87
- end
88
-
89
- Proc.new do
90
- if @random_value[input.object_id]
91
- value = @random_value[input.object_id]
92
- else
93
- value = case input.class.to_s
94
- when "Symbol"
95
- resource(input)
96
- when "Array"
97
- input
98
- when "Range"
99
- input.to_a
100
- when "Proc"
101
- input.call
102
- when "Fixnum"
103
- Stella::Utils.strand( input )
104
- when "NilClass"
105
- Stella::Utils.strand( rand(100) )
106
- end
107
- raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
108
- Stella.ld "RANDVALUES: #{input} #{value.class} #{value.inspect}"
109
- value = value[ rand(value.size) ] if value.is_a?(Array)
110
- Stella.ld "SELECTED: #{value.class} #{value} "
111
- @random_value[input.object_id] = value
112
- end
113
-
114
- # The resource may be an Array of Arrays (e.g. a CSV file)
115
- if value.is_a?(Array) && !index.nil?
116
- value = value[ index ]
117
- Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
118
- end
119
-
120
- value
121
- end
22
+ to_templ(:random, *args)
122
23
  end
123
24
 
124
25
 
125
26
  # NOTE: This is global across all users
126
27
  def sequential(*args)
127
- if Symbol === args.first
128
- input, index = *args
129
- elsif Array === args.first || args.size == 1
130
- input = args.first
131
- else
132
- input = args
133
- end
134
- Proc.new do
135
- if @sequential_value[input.object_id]
136
- value = @sequential_value[input.object_id]
137
- else
138
- value = case input.class.to_s
139
- when "Symbol"
140
- ret = resource(input)
141
- ret
142
- when "Array"
143
- input
144
- when "Range"
145
- input.to_a
146
- when "Proc"
147
- input.call
148
- end
149
- digest = value.object_id
150
- if value.is_a?(Array)
151
- idx = Stella::Client::Container.sequential_offset(digest, value.size-1)
152
- value = value[ idx ]
153
- Stella.ld "SELECTED(SEQ): #{value} #{idx} #{input} #{digest}"
154
- end
155
-
156
- # I think this needs to be updated for global_sequential:
157
- @sequential_value[input.object_id] = value
158
- end
159
- # The resource may be an Array of Arrays (e.g. a CSV file)
160
- if value.is_a?(Array) && !index.nil?
161
- value = value[ index ]
162
- Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
163
- end
164
- value
165
- end
28
+ to_templ(:sequential, *args)
166
29
  end
167
30
 
168
31
  # NOTE: This is global across all users
169
32
  def rsequential(*args)
170
- if Symbol === args.first
171
- input, index = *args
172
- elsif Array === args.first || args.size == 1
173
- input = args.first
174
- else
175
- input = args
176
- end
177
- Proc.new do
178
- if @rsequential_value[input.object_id]
179
- value = @rsequential_value[input.object_id]
33
+ to_templ(:rsequential, *args)
34
+ end
35
+
36
+ private
37
+
38
+ def args_to_str(*args)
39
+ args.collect! do |el|
40
+ if el.kind_of?(Enumerable) || el.kind_of?(Numeric)
41
+ el.inspect
42
+ elsif el.is_a?(Symbol)
43
+ ":#{el.to_s}"
180
44
  else
181
- value = case input.class.to_s
182
- when "Symbol"
183
- ret = resource(input)
184
- ret
185
- when "Array"
186
- input
187
- when "Range"
188
- input.to_a
189
- when "Proc"
190
- input.call
191
- end
192
- digest = value.object_id
193
- if value.is_a?(Array)
194
- idx = Stella::Client::Container.rsequential_offset(digest, value.size-1)
195
- value = value[ idx ]
196
- Stella.ld "SELECTED(RSEQ): #{value} #{idx} #{input} #{digest}"
197
- end
198
-
199
- # I think this needs to be updated for global_sequential:
200
- @rsequential_value[input.object_id] = value
201
- end
202
- # The resource may be an Array of Arrays (e.g. a CSV file)
203
- if value.is_a?(Array) && !index.nil?
204
- value = value[ index ]
205
- Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
206
- end
207
- value
45
+ "'#{el.to_s}'"
46
+ end
208
47
  end
48
+ args.join(', ')
209
49
  end
210
50
 
211
- ###
212
- ### Disabled b/c it doesn't work anymore since a
213
- ### new Container is created for every repetition.
214
- ###
215
- ##def sequential(*args)
216
- ## if Symbol === args.first
217
- ## input, index = *args
218
- ## elsif Array === args.first || args.size == 1
219
- ## input = args.first
220
- ## else
221
- ## input = args
222
- ## end
223
- ## Proc.new do
224
- ## if @sequential_value[input]
225
- ## value = @sequential_value[input]
226
- ## else
227
- ## value = case input.class.to_s
228
- ## when "Symbol"
229
- ## ret = resource(input)
230
- ## ret
231
- ## when "Array"
232
- ## input
233
- ## when "Range"
234
- ## input.to_a
235
- ## when "Proc"
236
- ## input.call
237
- ## end
238
- ## digest = value.object_id
239
- ## @sequential_offset ||= {}
240
- ## @sequential_offset[digest] ||= 0
241
- ## Stella.ld "SEQVALUES: #{@sequential_offset.object_id} #{value.inspect} #{@sequential_offset[digest]}"
242
- ## if value.is_a?(Array)
243
- ## size = value.size
244
- ## @sequential_offset[digest] = 0 if @sequential_offset[digest] >= size
245
- ## value = value[ @sequential_offset[digest] ]
246
- ## Stella.stdout.info "WHAY: #{value} (#{@sequential_offset[digest]})"
247
- ## @sequential_offset[digest] += 1
248
- ## end
249
- ## Stella.ld "SELECTED: #{value}"
250
- ## @sequential_value[input] = value
251
- ## end
252
- ## # The resource may be an Array of Arrays (e.g. a CSV file)
253
- ## if value.is_a?(Array) && !index.nil?
254
- ## value = value[ index ]
255
- ## Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
256
- ## end
257
- ## value
258
- ## end
259
- ##end
260
- ##
261
- ##def rsequential(*args)
262
- ## if Symbol === args.first
263
- ## input, index = *args
264
- ## elsif Array === args.first || args.size == 1
265
- ## input = args.first
266
- ## else
267
- ## input = args
268
- ## end
269
- ## Proc.new do
270
- ## if @rsequential_value[input.digest]
271
- ## value = @rsequential_value[input.digest]
272
- ## else
273
- ## value = case input.class.to_s
274
- ## when "Symbol"
275
- ## ret = resource(input)
276
- ## ret
277
- ## when "Array"
278
- ## input
279
- ## when "Range"
280
- ## input.to_a
281
- ## when "Proc"
282
- ## input.call
283
- ## end
284
- ## digest = value.object_id
285
- ## @rsequential_offset ||= {}
286
- ## Stella.ld "RSEQVALUES: #{input} #{value.inspect}"
287
- ## if value.is_a?(Array)
288
- ## size = value.size
289
- ## @rsequential_offset[digest] ||= size-1
290
- ## @rsequential_offset[digest] = size-1 if @rsequential_offset[digest] < 0
291
- ## value = value[ @rsequential_offset[digest] ]
292
- ## @rsequential_offset[digest] -= 1
293
- ## end
294
- ## Stella.ld "SELECTED: #{value}"
295
- ## @rsequential_value[input.digest] = value
296
- ## end
297
- ##
298
- ## # The resource may be an Array of Arrays (e.g. a CSV file)
299
- ## if value.is_a?(Array) && !index.nil?
300
- ## value = value[ index ]
301
- ## Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
302
- ## end
303
- ##
304
- ## value
305
- ## end
306
- ##end
307
-
308
-
51
+ def to_templ(meth, *args)
52
+ Stella::Template.to_templ("#{meth}(#{args_to_str(*args)})")
53
+ end
309
54
 
310
- # NOTE: This is global across all users
311
- ## TODO: Broken??
312
- ##def rsequential(*args)
313
- ## if Symbol === args.first
314
- ## input, index = *args
315
- ## elsif Array === args.first || args.size == 1
316
- ## input = args.first
317
- ## else
318
- ## input = args
319
- ## end
320
- ## Proc.new do
321
- ## if @rsequential_value[input.object_id]
322
- ## value = @rsequential_value[input.object_id]
323
- ## else
324
- ## value = case input.class.to_s
325
- ## when "Symbol"
326
- ## ret = resource(input)
327
- ## ret
328
- ## when "Array"
329
- ## input
330
- ## when "Range"
331
- ## input.to_a
332
- ## when "Proc"
333
- ## input.call
334
- ## end
335
- ## digest = value.object_id
336
- ## if value.is_a?(Array)
337
- ## index = Stella::Client::Container.rsequential_offset(digest, value.size-1)
338
- ## value = value[ index ]
339
- ## end
340
- ## Stella.ld "SELECTED(RSEQ): #{value} #{index} #{input} #{digest}"
341
- ## # I think this needs to be updated for global_rsequential:
342
- ## @rsequential_value[input.object_id] = value
343
- ## end
344
- ##
345
- ## # The resource may be an Array of Arrays (e.g. a CSV file)
346
- ## if value.is_a?(Array) && !index.nil?
347
- ## value = value[ index ]
348
- ## Stella.ld "SELECTED INDEX: #{index} #{value.inspect} #{input} #{digest}"
349
- ## end
350
- ##
351
- ## value
352
- ## end
353
- ##end
354
55
  end
355
56
 
356
57
  end
@@ -12,15 +12,22 @@ module Stella::Engine
12
12
 
13
13
  client = Stella::Client.new opts[:hosts].first, 1, opts
14
14
  client.add_observer(self)
15
-
15
+
16
16
  client.enable_nowait_mode if opts[:nowait]
17
17
 
18
+ if Stella::Engine.service
19
+ Stella::Engine.service.testplan_sync plan
20
+ Stella::Engine.service.testrun_create opts
21
+ Stella::Engine.service.client_create client.digest, :index => client.index
22
+ end
23
+
18
24
  Stella.stdout.info2 $/, "Starting test...", $/
19
- sleep 0.3
20
25
 
21
26
  # Identify this thread to Benelux
22
27
  Benelux.current_track :functional
23
28
 
29
+ start_time = Time.now.utc
30
+
24
31
  dig = Stella.stdout.lev > 1 ? plan.digest_cache : plan.digest_cache.shorter
25
32
  Stella.stdout.info " %-65s ".att(:reverse) % ["#{plan.desc} (#{dig})"]
26
33
  plan.usecases.each_with_index do |uc,i|
@@ -30,8 +37,24 @@ module Stella::Engine
30
37
  Stella.rescue { client.execute uc }
31
38
  end
32
39
 
33
- tl = Benelux.thread_timeline
34
- tl.stats.group(:failed).merge.n == 0
40
+ test_time = Time.now.utc - start_time
41
+
42
+ # Need to use thread timeline b/c the clients are running in the
43
+ # main thread which Benelux.update_global_timeline does not touch.
44
+ tt = Benelux.thread_timeline
45
+
46
+ failed = tt.stats.group(:failed).merge
47
+ total = tt.stats.group(:do_request).merge
48
+
49
+ if Stella::Engine.service
50
+ data = tt.messages.filter(:kind => :log).to_json
51
+ Stella::Engine.service.client_log client.digest, data
52
+ Stella::Engine.service.testrun_summary :successful => (total.n-failed.n),
53
+ :failed => failed.n,
54
+ :duration => test_time
55
+ end
56
+
57
+ failed == 0
35
58
  end
36
59
 
37
60
 
@@ -42,7 +65,18 @@ module Stella::Engine
42
65
  Stella.stdout.info2 " %-46s %16s ".bright % [desc, notice]
43
66
  end
44
67
 
68
+
45
69
  def update_receive_response(client_id, usecase, uri, req, params, headers, counter, container)
70
+ log = Stella::Engine::Log.new Time.now.to_f, container.unique_id, client_id,
71
+ 'testplanid',
72
+ usecase.digest, req.digest,
73
+ req.http_method, container.status, uri,
74
+ params, headers,
75
+ container.response.header.dump,
76
+ container.response.body.dump
77
+
78
+ Benelux.thread_timeline.add_message log, :status => container.status, :kind => :log
79
+
46
80
  msg = ' %-6s %-53s ' % [req.http_method, uri]
47
81
  msg << container.status.to_s if Stella.stdout.lev == 1
48
82
  Stella.stdout.info msg
@@ -52,33 +86,33 @@ module Stella::Engine
52
86
  Stella.stdout.info2 " %s: %s" % pair
53
87
  end
54
88
 
55
- Stella.stdout.info2 $/, ' ' << container.response.request.header.send(:request_line)
89
+ Stella.stdout.info3 $/, ' ' << container.response.request.header.send(:request_line)
56
90
 
57
91
  container.response.request.header.all.each do |pair|
58
- Stella.stdout.info2 " %s: %s" % pair
92
+ Stella.stdout.info3 " %s: %s" % pair
59
93
  end
60
94
 
61
95
  if req.http_method == 'POST'
62
96
  cont = container.response.request.body.content
63
97
  if String === cont
64
- Stella.stdout.info3(' ' << cont.split($/).join("#{$/} "))
98
+ Stella.stdout.info4(' ' << cont.split($/).join("#{$/} "))
65
99
  elsif HTTP::Message::Body::Parts === cont
66
100
  cont.parts.each do |part|
67
101
  if File === part
68
- Stella.stdout.info3 "<#{part.path}>"
102
+ Stella.stdout.info4 "<#{part.path}>"
69
103
  else
70
- Stella.stdout.info3 part
104
+ Stella.stdout.info4 part
71
105
  end
72
106
  end
73
107
  end
74
108
  end
75
109
 
76
110
  resh = container.response.header
77
- Stella.stdout.info2 $/, ' HTTP/%s %3d %s' % [resh.http_version, resh.status_code, resh.reason_phrase]
111
+ Stella.stdout.info3 $/, ' HTTP/%s %3d %s' % [resh.http_version, resh.status_code, resh.reason_phrase]
78
112
  container.headers.all.each do |pair|
79
- Stella.stdout.info2 " %s: %s" % pair
113
+ Stella.stdout.info3 " %s: %s" % pair
80
114
  end
81
- Stella.stdout.info3 container.body.empty? ? ' [empty]' : container.body
115
+ Stella.stdout.info4 container.body.empty? ? ' [empty]' : container.body
82
116
  Stella.stdout.info2 $/
83
117
  end
84
118
 
@@ -92,7 +126,7 @@ module Stella::Engine
92
126
 
93
127
  def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
94
128
  #desc = "#{usecase.desc} > #{req.desc}"
95
- Stella.le ' ERROR %24s: %s' % [ex.message, uri]
129
+ Stella.le ' ERROR %24s %s' % [ex.message, uri]
96
130
  Stella.le ' %s' % params.inspect
97
131
  unless req.headers.nil? || req.headers.empty?
98
132
  Stella.le ' %s' % req.headers.inspect
@@ -81,7 +81,7 @@ module Stella::Engine
81
81
  execute_test_plan packages, opts[:repetitions], opts[:duration], opts[:arrival]
82
82
  Stella.stdout.info $/, "Done"
83
83
  rescue Interrupt
84
- Stella.stdout.nstatus "Stopping test"
84
+ Stella.stdout.info $/, "Stopping test"
85
85
  Stella.abort!
86
86
  @threads.each { |t| t.join } unless @threads.nil? || @threads.empty? # wait
87
87
  rescue => ex
data/lib/stella/engine.rb CHANGED
@@ -1,7 +1,25 @@
1
1
 
2
-
3
2
  module Stella::Engine
4
-
3
+ @service = nil
4
+ class << self
5
+ attr_accessor :service
6
+ end
7
+ class Log < Storable
8
+ include Selectable::Object
9
+ field :stamp
10
+ field :uniqueid
11
+ field :clientid
12
+ field :planid
13
+ field :caseid
14
+ field :reqid
15
+ field :httpmethod
16
+ field :httpstatus
17
+ field :uri
18
+ field :params
19
+ field :headers
20
+ field :response_headers
21
+ field :response_body
22
+ end
5
23
  module Base
6
24
  extend self
7
25