stella 0.7.6.005 → 0.7.6.007

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.txt CHANGED
@@ -1,15 +1,37 @@
1
1
  STELLA, CHANGES
2
2
 
3
- #### 0.7.7 (2009-11-??) ###############################
3
+ #### 0.8.0 (2009-12-??) ###############################
4
+
5
+ * FIXED: HTTP auth failures
6
+ * FIXED: Request timeouts should count towards failures
7
+ * FIXED: Stella::Client ID was changing between requests in certain conditions
8
+ * ADDED: follow responses can contain definition blocks
9
+ * ADDED: Support for specifying default path prefix on CLI
10
+ * ADDED: Support for specifying timeouts
11
+
12
+ * TODO: Replace runtime procs with string templates
13
+ * TODO: review cooking handling. Not always sent automatically.
14
+ * TODO: global responses
15
+ * TODO: review :variables in URI elements
16
+
17
+
18
+ #### 0.7.7 (2009-12-05) ###############################
4
19
 
5
20
  * FIXED: JSON parse error when nil body
6
21
  * FIXED: URI query parameter encoding
7
22
  * CHANGE: Removed Stella::Testplan::Stats
23
+ * CHANGE: Better output for errors during functional tests
24
+ * CHANGE: Global variables now implemented in Stella::Testplan.global
25
+ and can be used like usecase and request resources.
26
+ * CHANGE: Variable replacement now checks the client container
27
+ resources before the usecase resources.
8
28
  * ADDED: Stella::Testplan#to_json
9
29
  * ADDED: Stella::Data::Helpers#read_file
10
30
  * ADDED: Stella::Data::Helpers#resequential
11
31
  * ADDED: Stella::Data::Helpers#path
12
32
  * ADDED: no-param, no-header options
33
+ * ADDED: Follow redirects within one request definition
34
+ * ADDED: Support for specifying HTTP AUTH domain in usecase config
13
35
 
14
36
 
15
37
  #### 0.7.6 (2009-11-24) ###############################
data/bin/stella CHANGED
@@ -54,11 +54,7 @@ class Stella::CLI::Definition
54
54
  String.disable_color
55
55
  Stella.log.output = v
56
56
  end
57
- global :var, String, 'Set an arbitrary variable (--var "name=v")' do |var|
58
- n, v = *var.split('=')
59
- raise "Bad variable format: #{var}" if n.nil? || !n.match(/[a-z]+/i)
60
- eval "$#{n} = '#{v}'"
61
- end
57
+ global :var, Array, 'Set an arbitrary variable (--var "name=v")'
62
58
  global :f, :format, String, "Output format (partial support)"
63
59
  global :n, :nocolor, "Disable output colors" do
64
60
  String.disable_color
@@ -69,11 +65,15 @@ class Stella::CLI::Definition
69
65
  global :v, :verbose, "Increase verbosity of output (e.g. -v or -vv or -vvv)" do
70
66
  Stella.stdout.lev += 1
71
67
  end
72
- global :'disable-stats', "Disable stat collection"
73
- global :'disable-logging', "Disable all logging" do
68
+ global :'no-stats', "Disable stat collection" do
69
+ true
70
+ end
71
+ global :'no-logging', "Disable all logging" do
74
72
  Stella::Logger.disable!
75
73
  end
76
- global :'disable-templates', "Disable template parsing"
74
+ global :'no-templates', "Disable template parsing" do
75
+ true
76
+ end
77
77
  global :V, :version, "Display version number" do
78
78
  puts "Stella version: #{Stella::VERSION} (#{Stella::VERSION::PATCH})"
79
79
  exit 0
@@ -0,0 +1,61 @@
1
+ # Stella Test Plan - Dynamic Data (2009-11-28)
2
+ #
3
+ #
4
+ # 1. START THE EXAMPLE APPLICATION
5
+ #
6
+ # This test plan is written to work with the
7
+ # example application that ships with Stella.
8
+ # See:
9
+ #
10
+ # $ stella example
11
+ #
12
+ #
13
+ # 2. RUN THE TEST PLAN
14
+ #
15
+ # $ stella verify -p examples/dynamic/plan.rb http://127.0.0.1:3114/
16
+ #
17
+ # $ stella generate -c 2 -r 2 -p examples/dynamic/plan.rb http://127.0.0.1:3114/
18
+ #
19
+ usecase "Dynamic Data" do
20
+
21
+ # Specify HTTP Authentication (Basic or Digest).
22
+ # Specify a username, password, and optional value
23
+ # to use for the authentication domain. If no domain
24
+ # is specifed, the root URI will be used.
25
+ #auth :user, :password, 'http://domain/'
26
+
27
+ # Retrieve a list of listings and store
28
+ # them in a resource called listing_ids.
29
+ get '/listings.yaml', "Get Listings" do
30
+ response 200 do
31
+ listings = doc.collect! { |l|; l[:id]; }
32
+ set :listing_ids, listings[0..2]
33
+ end
34
+ end
35
+
36
+ # Access each listing page in the order
37
+ get "/listing/:lid.yaml", "Sequential" do
38
+ param :lid => sequential(:listing_ids)
39
+ response 200 do
40
+ repeat 5
41
+ end
42
+ end
43
+
44
+ # Access each listing page in reverse order
45
+ get "/listing/:lid.yaml", "Reverse Sequential" do
46
+ param :lid => rsequential(:listing_ids)
47
+
48
+ response 200 do
49
+ repeat 5
50
+ end
51
+ end
52
+
53
+ # Access listing pages in random order
54
+ get "/listing/:lid.yaml", "Random" do
55
+ param :lid => random(:listing_ids)
56
+ response 200 do
57
+ repeat 5
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,18 @@
1
+ # Stella Test Plan - Timeouts (2009-12-08)
2
+ #
3
+ # TO BE DOCUMENTED.
4
+ #
5
+ # If you're reading this, remind me!
6
+ #
7
+
8
+
9
+ usecase "Timeout" do
10
+ timeout 20
11
+
12
+ get "/" do
13
+ timeout 0.01
14
+ end
15
+
16
+ get "/"
17
+
18
+ end
@@ -0,0 +1,40 @@
1
+ # Stella Test Plan - Using Variables (2009-12-04)
2
+ #
3
+ #
4
+ # 1. START THE EXAMPLE APPLICATION
5
+ #
6
+ # This test plan is written to work with the
7
+ # example application that ships with Stella.
8
+ # See:
9
+ #
10
+ # $ stella example
11
+ #
12
+ # 2. RUN THE TESTPLAN
13
+ #
14
+ # $ stella --var globalvar=smoked verify -p examples/variables/plan.rb
15
+ #
16
+ #
17
+ usecase "Form Example" do
18
+ set :uri => 'http://localhost:3114'
19
+ set :apple => resource(:globalvar)
20
+
21
+ # Variables can be used in the request URIs. Stella looks
22
+ # for a replacement value in the usecase resources, then
23
+ # in the params, and then in global variables.
24
+ get ":uri" do
25
+ end
26
+
27
+ # URI variables can also be specified with a dollar sign.
28
+ get "$uri/search" do
29
+ param :what => resource(:globalvar)
30
+ response do
31
+ puts " Global variable: " << resource(:globalvar)
32
+ puts " Usecase variable: " << resource(:uri)
33
+ puts " Usecase copy of global: " << resource(:apple)
34
+ end
35
+ end
36
+
37
+ get
38
+
39
+ end
40
+
data/lib/stella.rb CHANGED
@@ -23,7 +23,7 @@ module Stella
23
23
  MAJOR = 0.freeze
24
24
  MINOR = 7.freeze
25
25
  TINY = 6.freeze
26
- PATCH = '005'.freeze
26
+ PATCH = '007'.freeze
27
27
  end
28
28
  def self.to_s; [MAJOR, MINOR, TINY].join('.'); end
29
29
  def self.to_f; self.to_s.to_f; end
@@ -123,7 +123,6 @@ class Storable
123
123
  #
124
124
  # This allows an object to have a preset ID.
125
125
  #
126
- # NOTE: Does not assign a value to +@id+.
127
126
  def gibbler_id_processor
128
127
  Proc.new do |val|
129
128
  @id || self.gibbler
data/lib/stella/cli.rb CHANGED
@@ -19,9 +19,10 @@ class Stella::CLI < Drydock::Command
19
19
  opts = {}
20
20
  opts[:hosts] = @hosts
21
21
  opts[:nowait] = true if @option.nowait
22
- [:'disable-templates', :'disable-stats', :'no-header', :'no-param'].each do |opt|
22
+ [:'no-templates', :'no-stats', :'no-header', :'no-param'].each do |opt|
23
23
  opts[opt] = @global.send(opt) unless @global.send(opt).nil?
24
24
  end
25
+
25
26
  ret = Stella::Engine::Functional.run @testplan, opts
26
27
  @exit_code = (ret ? 0 : 1)
27
28
  end
@@ -37,7 +38,7 @@ class Stella::CLI < Drydock::Command
37
38
  opts[opt] = @option.send(opt) unless @option.send(opt).nil?
38
39
  end
39
40
 
40
- [:'disable-templates', :'disable-stats', :'no-header', :'no-param'].each do |opt|
41
+ [:'no-templates', :'no-stats', :'no-header', :'no-param'].each do |opt|
41
42
  opts[opt] = @global.send(opt) unless @global.send(opt).nil?
42
43
  end
43
44
 
@@ -99,6 +100,11 @@ class Stella::CLI < Drydock::Command
99
100
  uri = 'http://' << uri unless uri.match /^https?:\/\//i
100
101
  URI.parse uri;
101
102
  }
103
+ (@global.var || []).each do |var|
104
+ n, v = *var.split('=')
105
+ raise "Bad variable format: #{var}" if n.nil? || !n.match(/[a-z]+/i)
106
+ Stella::Testplan.global(n.to_sym, v)
107
+ end
102
108
  if @option.testplan
103
109
  @testplan = Stella::Testplan.load_file @option.testplan
104
110
  else
data/lib/stella/client.rb CHANGED
@@ -6,6 +6,7 @@ Stella::Utils.require_vendor "httpclient", '2.1.5.2'
6
6
 
7
7
  module Stella
8
8
  class Client
9
+ MAX_REDIRECTS = 5.freeze unless defined?(MAX_REDIRECTS)
9
10
 
10
11
  require 'stella/client/container'
11
12
 
@@ -18,7 +19,7 @@ module Stella
18
19
 
19
20
  def initialize(base_uri=nil, client_id=1, opts={})
20
21
  opts = {
21
- :'disable-templates' => true
22
+ :'no-templates' => false
22
23
  }.merge! opts
23
24
  @opts = opts
24
25
  @base_uri, @client_id = base_uri, client_id
@@ -26,9 +27,10 @@ module Stella
26
27
  @proxy = OpenStruct.new
27
28
  end
28
29
  def execute(usecase, &stat_collector)
29
- # We need to make sure the gibbler cache has a value
30
- self.gibbler if self.digest_cache.nil?
31
-
30
+ # Gibbler.enable_debug
31
+ # We need to make sure the digest cache has a value
32
+ self.digest if self.digest_cache.nil?
33
+ Gibbler.disable_debug
32
34
  http_client = create_http_client
33
35
  stats = {}
34
36
  container = Container.new(self.digest_cache, usecase)
@@ -50,28 +52,35 @@ module Stella
50
52
  headers = prepare_headers(container, req.headers)
51
53
 
52
54
  container.params, container.headers = params, headers
53
-
55
+
54
56
  uri = build_request_uri req.uri, params, container
55
57
 
56
- if http_auth = usecase.http_auth || req.http_auth
58
+ if http_auth = req.http_auth || usecase.http_auth
57
59
  # TODO: The first arg is domain and can include a URI path.
58
60
  # Are there cases where this is important?
59
- domain = '%s://%s:%d%s' % [uri.scheme, uri.host, uri.port, req.uri]
61
+ domain = http_auth.domain
62
+ domain ||= '%s://%s:%d%s' % [uri.scheme, uri.host, uri.port, req.uri]
63
+ domain = container.instance_eval &domain if Proc === domain
60
64
  Stella.ld "DOMAIN " << domain
61
65
  user, pass = http_auth.user, http_auth.pass
62
66
  user = container.instance_eval &user if Proc === user
63
67
  pass = container.instance_eval &pass if Proc === pass
64
- update(:authenticate, usecase, req, http_auth.kind, domain, user, pass)
68
+ update(:authenticate, usecase, req, domain, user, pass)
65
69
  http_client.set_auth(domain, user, pass)
66
70
  end
67
-
71
+
72
+ if tout = req.timeout || usecase.timeout
73
+ http_client.receive_timeout = tout
74
+ end
75
+ Stella.ld "TIMEOUT " << http_client.receive_timeout.to_s
76
+
68
77
  raise NoHostDefined, req.uri if uri.host.nil? || uri.host.empty?
69
- stella_id = [Time.now.to_f, self.digest_cache, req.digest_cache, params, headers, counter].gibbler
78
+ stella_id = [Time.now.to_f, self.digest_cache, req.digest_cache, params, headers, counter].digest
70
79
 
71
80
  Benelux.add_thread_tags :request => req.digest_cache
72
81
  Benelux.add_thread_tags :retry => counter
73
82
  Benelux.add_thread_tags :stella_id => stella_id
74
-
83
+
75
84
  container.unique_id = stella_id[0..10]
76
85
 
77
86
  params['__stella'] = container.unique_id unless @opts[:'no-param']
@@ -111,9 +120,11 @@ module Stella
111
120
  Benelux.remove_thread_tags :asset
112
121
  end
113
122
  asset_duration = Time.now - asset_start
114
- rescue HTTPClient::ConnectTimeoutError => ex
123
+ rescue HTTPClient::ConnectTimeoutError, HTTPClient::SendTimeoutError,
124
+ HTTPClient::ReceiveTimeoutError => ex
115
125
  update(:request_timeout, usecase, uri, req, params, headers, counter, container)
116
126
  Benelux.remove_thread_tags :status, :retry, :request, :stella_id
127
+ next
117
128
  rescue => ex
118
129
  update(:request_unhandled_exception, usecase, uri, req, params, ex)
119
130
  Benelux.remove_thread_tags :status, :retry, :request, :stella_id
@@ -128,6 +139,17 @@ module Stella
128
139
  update(:request_repeat, counter, ret.times+1, uri, container)
129
140
  Benelux.remove_thread_tags :status
130
141
  redo if counter <= ret.times
142
+ when "Stella::Client::Follow"
143
+ ret.uri ||= container.header['Location'].first
144
+ if counter > MAX_REDIRECTS
145
+ update(:max_redirects, counter-1, ret, uri, container)
146
+ break
147
+ else
148
+ req = ret.generate_request(req)
149
+ update(:follow_redirect, ret, uri, container)
150
+ Benelux.remove_thread_tags :status, :request
151
+ redo
152
+ end
131
153
  when "Stella::Client::Quit"
132
154
  update(:usecase_quit, ret.message, uri, container)
133
155
  Benelux.remove_thread_tags :status
@@ -200,7 +222,7 @@ module Stella
200
222
  #Stella.ld "PREPARE HEADERS: #{headers}"
201
223
  hashobj.each_pair do |n,v|
202
224
  v = container.instance_eval &v if v.is_a?(Proc)
203
- if @opts[:'disable-templates']
225
+ unless @opts[:'no-templates']
204
226
  v = container.parse_template v if String === v
205
227
  end
206
228
  v = extra.call(v) unless extra.nil?
@@ -220,6 +242,7 @@ module Stella
220
242
  # if necessary and replaces all variables with literal values.
221
243
  # If no replacement value can be found, the variable will remain.
222
244
  def build_request_uri(uri, params, container)
245
+ raise "Request given with no URI" if uri.nil?
223
246
  newuri = uri.clone # don't modify uri template
224
247
  # We call uri.clone b/c we modify uri.
225
248
  uri.scan(/([:\$])([a-z_]+)/i) do |inst|
@@ -239,8 +262,18 @@ module Stella
239
262
  uri.scheme = base_uri.scheme if uri.scheme.nil?
240
263
  uri.host = base_uri.host if uri.host.nil?
241
264
  uri.port = base_uri.port if uri.port.nil?
242
- uri.path ||= ''
243
- uri.path.gsub! /\/$/, '' # Don't double up on the first slash
265
+
266
+ # Support for specifying default path prefix:
267
+ # $ stella verify -p plan.rb http://localhost/basicauth
268
+ if base_uri.path
269
+ if uri.path.nil? || uri.path.empty?
270
+ uri.path = base_uri.path
271
+ else
272
+ a = base_uri.path.gsub(/\/$/, '')
273
+ b = uri.path.gsub(/^\//, '')
274
+ uri.path = [a,b].join('/')
275
+ end
276
+ end
244
277
 
245
278
  uri
246
279
  end
@@ -258,8 +291,11 @@ module Stella
258
291
  value = base_uri.host
259
292
  elsif params.has_key?(name.to_sym)
260
293
  value = params.delete name.to_sym
294
+ elsif container.resource?( name)
295
+ value = container.resource name
296
+ elsif Stella::Testplan.global?(name)
297
+ Stella::Testplan.global(name)
261
298
  end
262
- value = container.resource name.to_sym if value.nil?
263
299
  value
264
300
  end
265
301
 
@@ -314,15 +350,46 @@ end
314
350
  class Stella::Client
315
351
 
316
352
  class ResponseModifier
317
- attr_accessor :message
318
- def initialize(msg=nil)
319
- @message = msg
353
+ attr_accessor :obj
354
+ def initialize(obj=nil)
355
+ @obj = obj
320
356
  end
357
+ alias_method :message, :obj
358
+ alias_method :message=, :obj=
321
359
  end
322
360
  class Repeat < ResponseModifier;
323
- attr_accessor :times
324
- def initialize(times)
325
- @times = times
361
+ alias_method :times, :obj
362
+ alias_method :times=, :obj=
363
+ end
364
+ #
365
+ # Automatically follow a Location header or you
366
+ # can optionally specify the URI to load.
367
+ #
368
+ # get '/' do
369
+ # response 302 do
370
+ # follow do
371
+ # header :'X-SOME-HEADER' => 'somevalue'
372
+ # end
373
+ # end
374
+ # end
375
+ #
376
+ # The block is optional and accepts the same syntax as regular requests.
377
+ #
378
+ class Follow < ResponseModifier;
379
+ alias_method :uri, :obj
380
+ alias_method :uri=, :obj=
381
+ attr_reader :definition
382
+ def initialize(obj=nil,&definition)
383
+ @obj, @definition = obj, definition
384
+ end
385
+ def generate_request(req)
386
+ n = Stella::Data::HTTP::Request.new :GET, self.uri, req.http_version, &definition
387
+ n.description = "#{req.description || 'Request'} (autofollow)"
388
+ n.http_auth = req.http_auth
389
+ n.response_handler = req.response_handler
390
+ n.autofollow!
391
+ n.freeze
392
+ n
326
393
  end
327
394
  end
328
395
  class Quit < ResponseModifier; end
@@ -147,27 +147,37 @@ class Stella::Client
147
147
  end
148
148
  alias_method :form, :forms
149
149
 
150
- # Return a resource from the usecase or from this
151
- # container (in that order).
150
+ # Return a resource from this container or from
151
+ # the usecase (in that order). Otherwise, nil.
152
152
  def resource(n)
153
- return @usecase.resource(n) if @usecase.resources.has_key? n
154
- return @resources[n] if @resources.has_key? n
155
- nil
153
+ n &&= n.to_sym
154
+ v = @resources.has_key?(n) ? @resources[n] : @usecase.resource(n)
155
+ v = Stella::Testplan.global(n) if Stella::Testplan.global?(n)
156
+ v
157
+ end
158
+
159
+ def resource?(n)
160
+ !resource(n).nil?
156
161
  end
157
162
 
158
163
  def body; @response.body.content; end
159
164
  def headers; @response.header; end
160
165
  alias_method :header, :headers
161
166
  def status; @response.status; end
162
- def set(*args)
163
- h = Hash === args[0] ? args[0] : {args[0]=> args[1]}
164
- @resources.merge! h
167
+ def set(name, *args)
168
+ if Hash === name
169
+ Stella.ld "ARGS IGNORED: #{args.inspect} (#{caller[0]})" if !args.empty?
170
+ @resources.merge! name
171
+ elsif !name.nil? && !args.empty?
172
+ @resources.merge!({name => args[0]})
173
+ end
165
174
  end
166
175
  def wait(t); sleep t; end
167
176
  def quit(msg=nil); Quit.new(msg); end
168
177
  def fail(msg=nil); Fail.new(msg); end
169
178
  def error(msg=nil); Error.new(msg); end
170
179
  def repeat(t=1); Repeat.new(t); end
180
+ def follow(uri=nil,&blk); Follow.new(uri,&blk); end
171
181
 
172
182
 
173
183
 
data/lib/stella/common.rb CHANGED
@@ -227,7 +227,7 @@ class Stella::Config < Storable
227
227
  DEFAULT_CONFIG = <<CONF
228
228
  apikey: ''
229
229
  secret: ''
230
- source: api.solutious.com
230
+ source: ''
231
231
  CONF
232
232
  DEFAULT_CONFIG_HASH = YAML.load(DEFAULT_CONFIG).gibbler
233
233
  end
@@ -21,6 +21,9 @@ module Stella::Data::HTTP
21
21
  field :http_version
22
22
  field :content_type
23
23
  field :http_auth
24
+ field :timeout
25
+
26
+ field :autofollow # boolean. Was this an auto generated follow request.
24
27
 
25
28
  # A hash containing blocks to be executed depending on the HTTP response status.
26
29
  # The hash keys are numeric HTTP Status Codes.
@@ -40,14 +43,24 @@ module Stella::Data::HTTP
40
43
  @http_method, @http_version = method, version
41
44
  @headers, @params, @response_handler = {}, {}, {}
42
45
  @resources = {}
46
+ @autofollow = false
43
47
  @wait = 0
44
48
  self.description = "Request"
45
49
  instance_eval &definition unless definition.nil?
46
50
  end
47
51
 
48
- def auth(user=nil, pass=nil, kind=:basic)
52
+ def autofollow!
53
+ @autofollow = true
54
+ end
55
+
56
+ def auth(user=nil, pass=nil, domain=nil)
49
57
  @http_auth ||= Stella::Testplan::Usecase::Auth.new
50
- @http_auth.user, @http_auth.pass, @http_auth.kind = user, pass, kind
58
+ @http_auth.user, @http_auth.pass, @http_auth.domain = user, pass, domain
59
+ end
60
+
61
+ def timeout(*args)
62
+ @timeout = args.first unless args.empty?
63
+ @timeout
51
64
  end
52
65
 
53
66
  def desc(*args)
@@ -86,16 +86,28 @@ module Stella::Engine
86
86
  end
87
87
 
88
88
  def update_error_execute_response_handler(client_id, ex, req, container)
89
- Stella.le ex.message
89
+ Stella.le "#{ex.message} (#{ex.backtrace.first})"
90
90
  Stella.ld ex.backtrace
91
91
  end
92
92
 
93
93
  def update_request_unhandled_exception(client_id, usecase, uri, req, params, ex)
94
- desc = "#{usecase.desc} > #{req.desc}"
95
- Stella.le ' Client-%s %-45s %s' % [client_id.short, desc, ex.message]
94
+ #desc = "#{usecase.desc} > #{req.desc}"
95
+ Stella.le ' ERROR %24s: %s' % [ex.message, uri]
96
+ Stella.le ' %s' % params.inspect
97
+ unless req.headers.nil? || req.headers.empty?
98
+ Stella.le ' %s' % req.headers.inspect
99
+ end
96
100
  Stella.ld ex.backtrace
97
101
  end
98
102
 
103
+ def update_follow_redirect client_id, ret, req, container
104
+ Stella.stdout.info2 " FOLLOW %-53s" % [ret.uri]
105
+ end
106
+
107
+ def update_max_redirects client_id, counter, ret, req, container
108
+ Stella.stdout.info " MAX REDIRECTS %-53s" % [counter]
109
+ end
110
+
99
111
  def update_usecase_quit client_id, msg, req, container
100
112
  Stella.stdout.info " QUIT %s" % [msg]
101
113
  end
@@ -110,12 +122,17 @@ module Stella::Engine
110
122
  end
111
123
 
112
124
  def update_request_repeat client_id, counter, total, req, container
113
- Stella.stdout.info3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
125
+ Stella.stdout.info3 " REPEAT %d of %d" % [counter, total]
126
+ end
127
+
128
+ def update_authenticate client_id, usecase, req, domain, user, pass
129
+ Stella.stdout.info " AUTH #{domain} (#{user}/#{pass})"
114
130
  end
115
131
 
116
- def update_authenticate client_id, usecase, req, kind, domain, user, pass
117
- Stella.stdout.info " AUTH (#{kind}) #{domain} (#{user}/#{pass})"
132
+ def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container)
133
+ Stella.stdout.info " TIMEOUT %-53s" % [uri]
118
134
  end
135
+
119
136
  end
120
137
  end
121
138
 
@@ -31,7 +31,9 @@ module Stella::Engine
31
31
  reps.times { |rep|
32
32
  break if Stella.abort?
33
33
  Thread.current[:real_reps] += 1
34
- args = [c.digest.short, uc.desc, uc.digest.short, Thread.current[:real_reps]]
34
+ # NOTE: It's important to not call digest or gibbler methods
35
+ # on client object b/c it is not frozen. Always use digest_cache.
36
+ args = [c.digest_cache.short, uc.desc, uc.digest.short, Thread.current[:real_reps]]
35
37
  Stella.stdout.info4 $/, "======== THREAD %s: %s:%s (rep: %d)" % args
36
38
 
37
39
  Benelux.add_thread_tags :rep => rep
@@ -151,7 +151,7 @@ module Stella::Engine
151
151
  @failog.info Benelux.timeline.messages.filter(:kind => :timeout)
152
152
  @authlog.info Benelux.timeline.messages.filter(:kind => :authentication)
153
153
  @reqlog.clear and @failog.clear and @authlog.clear
154
- Benelux.timeline.clear if opts[:"disable-stats"]
154
+ Benelux.timeline.clear if opts[:"no-stats"]
155
155
  end
156
156
 
157
157
  end
@@ -398,14 +398,23 @@ module Stella::Engine
398
398
  Stella.stdout.info3 " Client-%s REPEAT %d of %d" % [client_id.shorter, counter, total]
399
399
  end
400
400
 
401
- def update_authenticate client_id, usecase, req, kind, domain, user, pass
401
+ def update_follow_redirect client_id, ret, req, container
402
+ Stella.stdout.info3 " Client-%s FOLLOW %-53s" % [client_id.shorter, ret.uri]
403
+ end
404
+
405
+ def update_max_redirects client_id, counter, ret, req, container
406
+ Stella.stdout.info3 " Client-%s MAX REDIRECTS %s " % [client_id.shorter, counter]
407
+ end
408
+
409
+ def update_authenticate client_id, usecase, req, domain, user, pass
402
410
  args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
403
411
  args.push usecase.digest.shorter, req.digest.shorter
404
- args.push 'AUTH', kind, domain, user, pass
412
+ args.push 'AUTH', domain, user, pass
405
413
  Benelux.thread_timeline.add_message args.join('; '), :kind => :authentication
406
414
  end
407
415
 
408
416
  def update_request_timeout(client_id, usecase, uri, req, params, headers, counter, container)
417
+ Stella.stdout.info3 " Client-%s TIMEOUT %-53s" % [client_id.shorter, uri]
409
418
  args = [Time.now.to_f, Stella.sysinfo.hostname, client_id.short]
410
419
  Benelux.thread_timeline.add_count :failed, 1
411
420
  args.push [uri, 'TOUT', container.unique_id[0,10]]
@@ -7,9 +7,10 @@ class Testplan < Storable
7
7
  extend Attic
8
8
 
9
9
  @file_cache = {}
10
-
10
+ @globals = {}
11
11
  class << self
12
12
  attr_reader :file_cache
13
+ attr_reader :globals
13
14
  def readlines path
14
15
  if @file_cache.has_key?(path)
15
16
  Stella.ld "FILE CACHE HIT: #{path}"
@@ -18,6 +19,13 @@ class Testplan < Storable
18
19
  Stella.ld "FILE CACHE LOAD: #{path}"
19
20
  @file_cache[path] = File.readlines(path)
20
21
  end
22
+ def global(n,v=nil)
23
+ @globals[n.to_sym] = v unless v.nil?
24
+ @globals[n.to_sym]
25
+ end
26
+ def global?(n)
27
+ @globals.has_key?(n.to_sym)
28
+ end
21
29
  end
22
30
 
23
31
  attic :base_path
@@ -28,11 +36,13 @@ class Testplan < Storable
28
36
 
29
37
  field :usecases
30
38
  field :description
39
+ #field :resources
31
40
 
32
41
  def initialize(uris=[], opts={})
33
42
  self.description = "Test plan"
34
43
  @usecases = []
35
44
  @testplan_current_ratio = 0
45
+ #@resources = {}
36
46
 
37
47
  unless uris.empty?
38
48
  uris = [uris] unless Array === uris
@@ -171,7 +181,7 @@ class Testplan
171
181
  include Stella::Data::Helpers
172
182
  extend Attic
173
183
 
174
- class Auth < Struct.new(:kind, :user, :pass)
184
+ class Auth < Struct.new(:domain, :user, :pass)
175
185
  include Gibbler::Complex
176
186
  end
177
187
 
@@ -185,6 +195,7 @@ class Testplan
185
195
 
186
196
  field :ratio
187
197
  field :http_auth
198
+ field :timeout
188
199
  field :requests
189
200
  field :resources
190
201
 
@@ -202,10 +213,24 @@ class Testplan
202
213
  self.description
203
214
  end
204
215
 
205
- def resource(name, value=nil)
206
- @resources[name] = value unless value.nil?
207
- @resources[name]
216
+ def timeout(*args)
217
+ @timeout = args.first unless args.empty?
218
+ @timeout
219
+ end
220
+
221
+ def resource(name, *args)
222
+ if Hash === name
223
+ Stella.ld "ARGS IGNORED: #{args.inspect} (#{caller[0]})" if !args.empty?
224
+ @resources.merge! name
225
+ elsif !name.nil? && !args.empty?
226
+ @resources.merge!({name => args[0]})
227
+ elsif @resources.has_key?(name)
228
+ @resources[name]
229
+ elsif Stella::Testplan.global?(name)
230
+ Stella::Testplan.global(name)
231
+ end
208
232
  end
233
+ alias_method :set, :resource
209
234
 
210
235
  def ratio
211
236
  r = (@ratio || 0).to_f
@@ -255,12 +280,13 @@ class Testplan
255
280
  self
256
281
  end
257
282
 
258
- def auth(user, pass=nil, kind=:basic)
283
+ def auth(user, pass=nil, domain=nil)
259
284
  @http_auth ||= Auth.new
260
- @http_auth.user, @http_auth.pass, @http_auth.kind = user, pass, kind
285
+ @http_auth.user, @http_auth.pass, @http_auth.domain = user, pass, domain
261
286
  end
262
287
 
263
288
  def add_request(meth, *args, &blk)
289
+ raise "'#{meth}' block given in #{self.plan_path} with no URI" if args[0].nil?
264
290
  req = Stella::Data::HTTP::Request.new meth.to_s.upcase, args[0], &blk
265
291
  req.description = args[1] if args.size > 1 # Description is optional
266
292
  Stella.ld req
data/stella.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  @spec = Gem::Specification.new do |s|
2
2
  s.name = "stella"
3
3
  s.rubyforge_project = 'stella'
4
- s.version = "0.7.6.005"
4
+ s.version = "0.7.6.007"
5
5
  s.summary = "Blame Stella for breaking your web applications."
6
6
  s.description = s.summary
7
7
  s.author = "Delano Mandelbaum"
@@ -34,10 +34,13 @@
34
34
  examples/cookies/plan.rb
35
35
  examples/csvdata/plan.rb
36
36
  examples/csvdata/search_terms.csv
37
+ examples/dynamic/plan.rb
37
38
  examples/essentials/logo.png
38
39
  examples/essentials/plan.rb
39
40
  examples/essentials/search_terms.txt
40
41
  examples/exceptions/plan.rb
42
+ examples/timeout/plan.rb
43
+ examples/variables/plan.rb
41
44
  lib/proc_source.rb
42
45
  lib/stella.rb
43
46
  lib/stella/cli.rb
@@ -233,6 +233,7 @@ class HTTPClient
233
233
  uri = Util.uri_dirname(uri)
234
234
  @auth[uri] = ["#{user}:#{passwd}"].pack('m').tr("\n", '')
235
235
  end
236
+
236
237
  end
237
238
 
238
239
  # Response handler: returns credential.
@@ -119,7 +119,7 @@ class HTTPClient
119
119
  @chunk_size = 4096
120
120
 
121
121
  @connect_timeout = 60
122
- @connect_retry = 1
122
+ @connect_retry = 2
123
123
  @send_timeout = 120
124
124
  @receive_timeout = 60 # For each read_block_size bytes
125
125
  @read_block_size = 1024 * 16 # follows net/http change in 1.8.7
@@ -495,11 +495,11 @@ class HTTPClient
495
495
  @debug_dev = nil
496
496
 
497
497
  @connect_timeout = nil
498
- @connect_retry = 1
498
+ @connect_retry = 2
499
499
  @send_timeout = nil
500
500
  @receive_timeout = nil
501
501
  @read_block_size = nil
502
- @protocol_retry_count = 5
502
+ @protocol_retry_count = 2
503
503
 
504
504
  @ssl_config = nil
505
505
  @ssl_peer_cert = nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stella
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.6.005
4
+ version: 0.7.6.007
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-01 00:00:00 -05:00
12
+ date: 2009-12-09 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -92,10 +92,13 @@ files:
92
92
  - examples/cookies/plan.rb
93
93
  - examples/csvdata/plan.rb
94
94
  - examples/csvdata/search_terms.csv
95
+ - examples/dynamic/plan.rb
95
96
  - examples/essentials/logo.png
96
97
  - examples/essentials/plan.rb
97
98
  - examples/essentials/search_terms.txt
98
99
  - examples/exceptions/plan.rb
100
+ - examples/timeout/plan.rb
101
+ - examples/variables/plan.rb
99
102
  - lib/proc_source.rb
100
103
  - lib/stella.rb
101
104
  - lib/stella/cli.rb