stella 0.7.6.005 → 0.7.6.007
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.
- data/CHANGES.txt +23 -1
- data/bin/stella +8 -8
- data/examples/dynamic/plan.rb +61 -0
- data/examples/timeout/plan.rb +18 -0
- data/examples/variables/plan.rb +40 -0
- data/lib/stella.rb +1 -2
- data/lib/stella/cli.rb +8 -2
- data/lib/stella/client.rb +89 -22
- data/lib/stella/client/container.rb +18 -8
- data/lib/stella/common.rb +1 -1
- data/lib/stella/data/http.rb +15 -2
- data/lib/stella/engine/functional.rb +23 -6
- data/lib/stella/engine/load_queue.rb +3 -1
- data/lib/stella/engine/loadbase.rb +12 -3
- data/lib/stella/testplan.rb +33 -7
- data/stella.gemspec +4 -1
- data/vendor/httpclient-2.1.5.2/httpclient/auth.rb +1 -0
- data/vendor/httpclient-2.1.5.2/httpclient/session.rb +3 -3
- metadata +5 -2
data/CHANGES.txt
CHANGED
@@ -1,15 +1,37 @@
|
|
1
1
|
STELLA, CHANGES
|
2
2
|
|
3
|
-
#### 0.
|
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,
|
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 :'
|
73
|
-
|
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 :'
|
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,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 = '
|
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
|
-
[:'
|
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
|
-
[:'
|
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
|
-
:'
|
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
|
-
|
30
|
-
|
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 =
|
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 =
|
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,
|
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].
|
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
|
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
|
-
|
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
|
-
|
243
|
-
|
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 :
|
318
|
-
def initialize(
|
319
|
-
@
|
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
|
-
|
324
|
-
|
325
|
-
|
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
|
151
|
-
#
|
150
|
+
# Return a resource from this container or from
|
151
|
+
# the usecase (in that order). Otherwise, nil.
|
152
152
|
def resource(n)
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
164
|
-
|
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
data/lib/stella/data/http.rb
CHANGED
@@ -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
|
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.
|
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 '
|
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 "
|
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
|
117
|
-
Stella.stdout.info "
|
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
|
-
|
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[:"
|
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
|
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',
|
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]]
|
data/lib/stella/testplan.rb
CHANGED
@@ -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(:
|
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
|
206
|
-
@
|
207
|
-
@
|
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,
|
283
|
+
def auth(user, pass=nil, domain=nil)
|
259
284
|
@http_auth ||= Auth.new
|
260
|
-
@http_auth.user, @http_auth.pass, @http_auth.
|
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.
|
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
|
@@ -119,7 +119,7 @@ class HTTPClient
|
|
119
119
|
@chunk_size = 4096
|
120
120
|
|
121
121
|
@connect_timeout = 60
|
122
|
-
@connect_retry =
|
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 =
|
498
|
+
@connect_retry = 2
|
499
499
|
@send_timeout = nil
|
500
500
|
@receive_timeout = nil
|
501
501
|
@read_block_size = nil
|
502
|
-
@protocol_retry_count =
|
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.
|
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-
|
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
|