stella 0.7.6.007 → 0.8.0.000
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +27 -6
- data/README.md +132 -0
- data/Rakefile +3 -3
- data/Rudyfile +17 -16
- data/bin/stella +1 -1
- data/examples/cookies/plan.rb +1 -1
- data/examples/csvdata/plan.rb +6 -1
- data/examples/dynamic/plan.rb +0 -1
- data/examples/variables/plan.rb +0 -2
- data/lib/stella/cli.rb +7 -0
- data/lib/stella/client/container.rb +123 -71
- data/lib/stella/client.rb +19 -11
- data/lib/stella/data/http.rb +22 -0
- data/lib/stella/data.rb +24 -323
- data/lib/stella/engine/functional.rb +47 -13
- data/lib/stella/engine/loadbase.rb +1 -1
- data/lib/stella/engine.rb +20 -2
- data/lib/stella/service.rb +228 -0
- data/lib/stella/testplan.rb +9 -4
- data/lib/stella.rb +28 -6
- data/stella.gemspec +9 -7
- data/tryouts/api/10_functional.rb +20 -0
- data/vendor/httpclient-2.1.5.2/httpclient/session.rb +2 -2
- metadata +12 -10
- data/README.rdoc +0 -114
data/CHANGES.txt
CHANGED
@@ -1,18 +1,39 @@
|
|
1
1
|
STELLA, CHANGES
|
2
2
|
|
3
|
-
#### 0.8.
|
3
|
+
#### 0.8.X (XXXX-XX-XX) ###############################
|
4
|
+
|
5
|
+
* TODO: Force response block content type.
|
6
|
+
* TODO: Add assert methods to response blocks (reconsider)
|
7
|
+
* TODO: Add option to dump full request/response output to a file by client
|
8
|
+
* TODO: review cooking handling. Not always sent automatically.
|
9
|
+
* TODO: review :variables in URI elements
|
10
|
+
* TODO: Stella::Testrun (no local analog for runid so it's set by the service)
|
11
|
+
* TODO: global responses
|
12
|
+
* TODO: request block conditions.
|
13
|
+
|
14
|
+
|
15
|
+
#### 0.8.0 (2010-01-16) ###############################
|
16
|
+
|
17
|
+
NOTE: The configuration language changed slightly in this release.
|
18
|
+
See the README for more information on what needs to be updated.
|
4
19
|
|
5
20
|
* FIXED: HTTP auth failures
|
6
21
|
* FIXED: Request timeouts should count towards failures
|
7
22
|
* FIXED: Stella::Client ID was changing between requests in certain conditions
|
23
|
+
* FIXED: HTTP delete now works correctly
|
24
|
+
* FIXED: Missing rsequential method in Container
|
25
|
+
* FIXED: Don't override user agent header when specified
|
26
|
+
* FIXED: variables testplan example.
|
27
|
+
* FIXED: Print reports again when load test is interrupted
|
28
|
+
* FIXED: Sporadic ERB template error under high concurrency
|
29
|
+
* CHANGE: A proper message displayed when no host specified
|
30
|
+
* CHANGE: Don't append httpclient info to User-Agent header
|
31
|
+
* CHANGE: param and header helper methods now return strings instead of Procs.
|
32
|
+
* CHANGE: Verbosity level 2 now prints only params, 3 w/ headers, 4 w/ body
|
8
33
|
* ADDED: follow responses can contain definition blocks
|
9
34
|
* ADDED: Support for specifying default path prefix on CLI
|
10
35
|
* 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
|
36
|
+
* ADDED: Friendly error for empty request configs
|
16
37
|
|
17
38
|
|
18
39
|
#### 0.7.7 (2009-12-05) ###############################
|
data/README.md
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# Stella - 0.8 BETA
|
2
|
+
|
3
|
+
**Blame Stella for breaking your web application!**
|
4
|
+
|
5
|
+
Stella is an integration and load testing tool. It fits well into an agile development process because the configuration syntax is simple yet powerful and a single config can be used for both kinds of tests (integration and load). Stella runs at the protocol-level which means it generates HTTP requests and parses the responses but does not perform any browser simulation (see Caveats).
|
6
|
+
|
7
|
+
### Important Information Regarding Your Testplans
|
8
|
+
|
9
|
+
*The testplan configuration syntax changed a little in 0.8. Most configs will not be affected. See "News" below for more info.*
|
10
|
+
|
11
|
+
## Features
|
12
|
+
|
13
|
+
* Support for simulating multiple usecases at the same time
|
14
|
+
* Sophisticated response handling
|
15
|
+
* Automatic parsing of HTML, XML, XHTML, YAML, and JSON response bodies
|
16
|
+
* Dynamic variable replacement
|
17
|
+
* Support for testing multiple sites simultaneously
|
18
|
+
|
19
|
+
|
20
|
+
## Caveats
|
21
|
+
|
22
|
+
There are a few known limitations:
|
23
|
+
|
24
|
+
* *SHOW-STOPPER*: An upper limit of around 200-300 concurrent virtual HTTP clients. There is a threading issue in the HTTPClient library which appears under high load.
|
25
|
+
* *SHOW-STOPPER (for some)*: No support for browser or UI based tests (a la Watir or Selenium). If this is a show stopper for you, check out [WatirGrid](http://github.com/90kts/watirgrid)
|
26
|
+
* *ANNOYING*: File uploads do not work with some HTTP servers (WEBrick)
|
27
|
+
* *ANNOYING*: Lack of documentation (see examples/ directory)
|
28
|
+
* *ANNOYING*: Reporting is limited to log files and command-line output. You need to make your own graphs.
|
29
|
+
|
30
|
+
|
31
|
+
## Examples
|
32
|
+
|
33
|
+
|
34
|
+
### Testplan Configuration
|
35
|
+
|
36
|
+
Every load testing tool worth its salt allows you to control the logical flow with some form of programming language. One of the advantages that open source tools have over commercial ones is that the languages used are generally well known whereas most commercial tools use proprietary languages. This makes it possible to define sophisticated and realistic tests.
|
37
|
+
|
38
|
+
Stella test plans are defined in subset of the Ruby programming language. They also typically contain more than one usecase which is important when simulating realistic load.
|
39
|
+
|
40
|
+
usecase "An Example Usecase" do
|
41
|
+
get '/some/path' do
|
42
|
+
param :what => 'food'
|
43
|
+
param :where => 'iowa'
|
44
|
+
response 200 do
|
45
|
+
# code executed when the server returns a 200 response.
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
get '/a/dynamic/:path' do
|
50
|
+
param :path => random(4) # => http://host/a/dynamic/jrr1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
See the [examples/](http://github.com/solutious/stella/tree/0.8/examples/) directory and [Getting Started](http://solutious.com/projects/stella/getting-started/) for more information.
|
56
|
+
|
57
|
+
|
58
|
+
### Running Tests
|
59
|
+
|
60
|
+
Stella is a command-line tool with two main commands: "verify" for integration tests and "generate" for load tests.
|
61
|
+
|
62
|
+
# Verify a test plan is defined correctly
|
63
|
+
# by running a single user functional test.
|
64
|
+
$ stella verify -p examples/essentials/plan.rb http://stellaaahhhh.com/
|
65
|
+
|
66
|
+
# Generate load using the same test plan.
|
67
|
+
$ stella generate -p examples/essentials/plan.rb -c 50 -d 10m http://stellaaahhhh.com/
|
68
|
+
|
69
|
+
|
70
|
+
See <tt>$ stella -h</tt> and <tt>$ stella example</tt> for more info.
|
71
|
+
|
72
|
+
## News
|
73
|
+
|
74
|
+
### 2010-01-16: sequential, random, rsequential etc... methods now return ERB-style templates instead of Procs
|
75
|
+
|
76
|
+
Pre-0.8 would return a Proc that would be evaluated at request time:
|
77
|
+
|
78
|
+
get "/" do
|
79
|
+
param :salt => random(8) # => "#<Proc0x13423c0 ...>"
|
80
|
+
end
|
81
|
+
|
82
|
+
In 0.8 and beyond, the same configuration will return a String:
|
83
|
+
|
84
|
+
get "/" do
|
85
|
+
param :salt => random(8) # => "<%= random(8) %>"
|
86
|
+
end
|
87
|
+
|
88
|
+
## Installation
|
89
|
+
|
90
|
+
Get it in one of the following ways:
|
91
|
+
|
92
|
+
$ gem install stella --source=http://gemcutter.org/
|
93
|
+
$ sudo gem install stella --source=http://gemcutter.org/
|
94
|
+
$ git clone git://github.com/solutious/stella.git
|
95
|
+
|
96
|
+
You can also download via [tarball](http://github.com/solutious/stella/tarball/latest) or [zip](http://github.com/solutious/stella/zipball/latest).
|
97
|
+
|
98
|
+
|
99
|
+
## More Information
|
100
|
+
|
101
|
+
* [Homepage](http://solutious.com/projects/stella)
|
102
|
+
* [Codes](http://github.com/solutious/stella)
|
103
|
+
* [RDocs](http://solutious.com/stella)
|
104
|
+
* [Stellaaahhhh](http://stellaaahhhh.com)
|
105
|
+
|
106
|
+
|
107
|
+
## Credits
|
108
|
+
|
109
|
+
* [Delano Mandelbaum](http://solutious.com)
|
110
|
+
|
111
|
+
|
112
|
+
## Thanks
|
113
|
+
|
114
|
+
* Harm Aarts for the great test case and feedback!
|
115
|
+
* Kalin Harvey for keeping me on track.
|
116
|
+
* Dave L, the best intern money can't buy.
|
117
|
+
* Peter McCurdy for the feedback and bug fixes.
|
118
|
+
|
119
|
+
|
120
|
+
## Related Projects
|
121
|
+
|
122
|
+
* [WatirGrid](http://github.com/90kts/watirgrid)
|
123
|
+
* [Watir](http://watir.com/)
|
124
|
+
* [JMeter](http://jakarta.apache.org/jmeter/)
|
125
|
+
* [Tsung](http://tsung.erlang-projects.org/)
|
126
|
+
* [Grinder](http://grinder.sourceforge.net/)
|
127
|
+
* [Pylot](http://www.pylot.org/)
|
128
|
+
* [Trample](http://github.com/jamesgolick/trample)
|
129
|
+
|
130
|
+
## License
|
131
|
+
|
132
|
+
See LICENSE.txt
|
data/Rakefile
CHANGED
@@ -52,8 +52,8 @@ end
|
|
52
52
|
#about 'Public release to rubyforge'
|
53
53
|
task 'publish:gem' => [:package] do |t|
|
54
54
|
sh <<-end
|
55
|
-
rubyforge add_release -o Any -a CHANGES.txt -f -n README.
|
56
|
-
rubyforge add_file -o Any -a CHANGES.txt -f -n README.
|
55
|
+
rubyforge add_release -o Any -a CHANGES.txt -f -n README.md #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
|
56
|
+
rubyforge add_file -o Any -a CHANGES.txt -f -n README.md #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -64,7 +64,7 @@ Rake::RDocTask.new do |t|
|
|
64
64
|
t.options << '--line-numbers' << '-A cattr_accessor=object'
|
65
65
|
t.options << '--charset' << 'utf-8'
|
66
66
|
t.rdoc_files.include('LICENSE.txt')
|
67
|
-
t.rdoc_files.include('README.
|
67
|
+
t.rdoc_files.include('README.md')
|
68
68
|
t.rdoc_files.include('CHANGES.txt')
|
69
69
|
#t.rdoc_files.include('Rudyfile') # why is the formatting f'd?
|
70
70
|
t.rdoc_files.include('bin/*')
|
data/Rudyfile
CHANGED
@@ -10,7 +10,7 @@ machines do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
env :stage do
|
13
|
-
|
13
|
+
|
14
14
|
role :app do
|
15
15
|
positions 2
|
16
16
|
user :root
|
@@ -19,8 +19,8 @@ machines do
|
|
19
19
|
|
20
20
|
role :gen do
|
21
21
|
user :root
|
22
|
-
size 'm1.
|
23
|
-
ami 'ami-
|
22
|
+
size 'm1.small'
|
23
|
+
ami 'ami-212ccf48' # this is stale and the 64-bit one is broken
|
24
24
|
end
|
25
25
|
|
26
26
|
role :demo do
|
@@ -38,9 +38,11 @@ end
|
|
38
38
|
commands do
|
39
39
|
allow :apt_get, "apt-get", :y, :q
|
40
40
|
allow :gem_install, "/usr/bin/gem", "install", :n, '/usr/bin', :y, :V, "--no-rdoc", "--no-ri"
|
41
|
+
allow :gem19_install, "/usr/local/bin/gem", "install", :n, '/usr/local/bin', :y, :V, "--no-rdoc", "--no-ri"
|
41
42
|
allow :gem_sources, "/usr/bin/gem", "sources"
|
42
43
|
allow :gem_uninstall, "/usr/bin/gem", "uninstall", :V
|
43
44
|
allow :update_rubygems
|
45
|
+
allow :update_rubygems19
|
44
46
|
allow :rake
|
45
47
|
allow :thin
|
46
48
|
allow :stella
|
@@ -123,13 +125,6 @@ routines do
|
|
123
125
|
end
|
124
126
|
end
|
125
127
|
|
126
|
-
install_github do
|
127
|
-
remote :root do
|
128
|
-
gem_sources :a, "http://gems.github.com"
|
129
|
-
gem_install 'solutious-stella'
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
128
|
package_gem do
|
134
129
|
local do
|
135
130
|
rm :r, :f, 'pkg'
|
@@ -146,9 +141,15 @@ routines do
|
|
146
141
|
|
147
142
|
install_gem do
|
148
143
|
before :package_gem
|
144
|
+
local do
|
145
|
+
cd 'pkg'
|
146
|
+
gems = unsafely {ls "*gem"}
|
147
|
+
$gemfile = gems.first
|
148
|
+
end
|
149
149
|
remote :root do
|
150
|
-
file_upload "pkg
|
151
|
-
gem_install "/tmp
|
150
|
+
file_upload "pkg/#{$gemfile}", "/tmp/"
|
151
|
+
gem_install "/tmp/#{$gemfile}"
|
152
|
+
gem19_install "/tmp/#{$gemfile}"
|
152
153
|
end
|
153
154
|
|
154
155
|
end
|
@@ -203,13 +204,13 @@ routines do
|
|
203
204
|
apt_get "install", "ruby1.8-dev", "rdoc", "libzlib-ruby", "rubygems"
|
204
205
|
apt_get "install", "libfcgi-dev", "libfcgi-ruby1.8"
|
205
206
|
apt_get "install", "joe", "siege", "httperf"
|
206
|
-
gem_sources :a, "http://
|
207
|
+
gem_sources :a, "http://gemcutter.org/"
|
207
208
|
mkdir :p, "/var/lib/gems/1.8/bin" # Doesn't get created, but causes Rubygems to fail
|
208
209
|
gem_install "builder", "session"
|
209
|
-
gem_install '
|
210
|
-
|
210
|
+
gem_install 'rubygems-update'
|
211
|
+
gem19_install 'rubygems-update'
|
211
212
|
update_rubygems
|
212
|
-
|
213
|
+
update_rubygems19
|
213
214
|
}
|
214
215
|
}
|
215
216
|
|
data/bin/stella
CHANGED
@@ -49,6 +49,7 @@ class Stella::CLI::Definition
|
|
49
49
|
global :'no-param', "Do not include __stella query parameter header" do
|
50
50
|
true
|
51
51
|
end
|
52
|
+
global :R, :remote
|
52
53
|
global :E, :engine, String, "Specify a load engine (experimental)"
|
53
54
|
global :o, :output, String, "Write output to the given file" do |v|
|
54
55
|
String.disable_color
|
@@ -144,7 +145,6 @@ class Stella::CLI::Definition
|
|
144
145
|
|
145
146
|
# ---------------------------------- STELLA MISCELLANEOUS --------
|
146
147
|
# ------------------------------------------------------------------
|
147
|
-
|
148
148
|
before do |obj|
|
149
149
|
#puts $$
|
150
150
|
@start = Time.now
|
data/examples/cookies/plan.rb
CHANGED
@@ -29,7 +29,7 @@ usecase "Temporary Cookies" do
|
|
29
29
|
|
30
30
|
# Here the cookie will contain the search term
|
31
31
|
get "/search", "Search" do
|
32
|
-
param :what =>
|
32
|
+
param :what => random(['Big', 'Beads', 'Joe'])
|
33
33
|
response do
|
34
34
|
puts "COOKIE: " << headers['Set-Cookie'].first
|
35
35
|
end
|
data/examples/csvdata/plan.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Stella Test Plan - Reading CSV Data (
|
1
|
+
# Stella Test Plan - Reading CSV Data (2010-01-16)
|
2
2
|
#
|
3
3
|
# TO BE DOCUMENTED.
|
4
4
|
#
|
@@ -22,6 +22,11 @@ usecase "Reading CSV Data" do
|
|
22
22
|
param :what => sequential(:search_terms, 0)
|
23
23
|
param :where => sequential(:search_terms, 1)
|
24
24
|
end
|
25
|
+
|
26
|
+
get "/search", "Search (sequential #3)" do
|
27
|
+
param :what => sequential(:search_terms, 0)
|
28
|
+
param :where => sequential(:search_terms, 1)
|
29
|
+
end
|
25
30
|
end
|
26
31
|
|
27
32
|
# d93df136283f3867f462266a98675ce0b2f51b08
|
data/examples/dynamic/plan.rb
CHANGED
data/examples/variables/plan.rb
CHANGED
data/lib/stella/cli.rb
CHANGED
@@ -19,6 +19,13 @@ class Stella::CLI < Drydock::Command
|
|
19
19
|
opts = {}
|
20
20
|
opts[:hosts] = @hosts
|
21
21
|
opts[:nowait] = true if @option.nowait
|
22
|
+
|
23
|
+
if @global.remote
|
24
|
+
require 'bone'
|
25
|
+
s = Stella::Service.new Bone['STELLA_SOURCE'], Bone['STELLA_TOKEN']
|
26
|
+
Stella::Engine.service = s
|
27
|
+
end
|
28
|
+
|
22
29
|
[:'no-templates', :'no-stats', :'no-header', :'no-param'].each do |opt|
|
23
30
|
opts[opt] = @global.send(opt) unless @global.send(opt).nil?
|
24
31
|
end
|
@@ -86,11 +86,10 @@ class Stella::Client
|
|
86
86
|
# ERB BUG?: Under heavy threading, some calls
|
87
87
|
# produce the error:
|
88
88
|
# wrong number of arguments(1 for 0)
|
89
|
-
|
90
|
-
v = template.result(binding)
|
89
|
+
v = t.result(binding)
|
91
90
|
rescue => ex
|
92
91
|
Stella.ld ex.message, ex.backtrace
|
93
|
-
t
|
92
|
+
t.to_s
|
94
93
|
end
|
95
94
|
|
96
95
|
def doc
|
@@ -232,93 +231,146 @@ class Stella::Client
|
|
232
231
|
|
233
232
|
end
|
234
233
|
|
234
|
+
def path(*args)
|
235
|
+
input = File.join *args
|
236
|
+
File.exists?(input) ? input : File.join(@base_path, input)
|
237
|
+
end
|
238
|
+
|
239
|
+
def read_file(*args)
|
240
|
+
f = file *args
|
241
|
+
f.read
|
242
|
+
end
|
243
|
+
|
235
244
|
def random(*args)
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
245
|
+
input, idxcol = *std_arg_processor(*args)
|
246
|
+
|
247
|
+
if @random_value[input.object_id]
|
248
|
+
value = @random_value[input.object_id]
|
240
249
|
else
|
241
|
-
|
250
|
+
value = case input.class.to_s
|
251
|
+
when "Symbol"
|
252
|
+
resource(input)
|
253
|
+
when "Array"
|
254
|
+
input
|
255
|
+
when "Range"
|
256
|
+
input.to_a
|
257
|
+
when "Proc"
|
258
|
+
input.call
|
259
|
+
when "Fixnum"
|
260
|
+
Stella::Utils.strand( input )
|
261
|
+
when "NilClass"
|
262
|
+
Stella::Utils.strand( rand(100) )
|
263
|
+
end
|
264
|
+
raise Stella::Testplan::Usecase::UnknownResource, input if value.nil?
|
265
|
+
Stella.ld "RANDVALUES: #{input} #{value.class} #{value.inspect}"
|
266
|
+
value = value[ rand(value.size) ] if value.is_a?(Array)
|
267
|
+
Stella.ld "SELECTED: #{value.class} #{value} "
|
268
|
+
@random_value[input.object_id] = value
|
242
269
|
end
|
243
|
-
|
244
270
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
271
|
+
# The resource may be an Array of Arrays (e.g. a CSV file)
|
272
|
+
if value.is_a?(Array) && !idxcol.nil?
|
273
|
+
value = value[ idxcol ]
|
274
|
+
Stella.ld "SELECTED INDEX: #{idxcol} #{value.inspect} "
|
275
|
+
end
|
276
|
+
|
277
|
+
value
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
|
283
|
+
# NOTE: This is global across all users
|
284
|
+
def sequential(*args)
|
285
|
+
input, idxcol = *std_arg_processor(*args)
|
286
|
+
|
287
|
+
if @sequential_value[input.object_id]
|
288
|
+
value = @sequential_value[input.object_id]
|
289
|
+
else
|
290
|
+
value = case input.class.to_s
|
291
|
+
when "Symbol"
|
292
|
+
ret = resource(input)
|
293
|
+
ret
|
294
|
+
when "Array"
|
295
|
+
input
|
296
|
+
when "Range"
|
297
|
+
input.to_a
|
298
|
+
when "Proc"
|
299
|
+
input.call
|
267
300
|
end
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
value = value[
|
272
|
-
Stella.ld "SELECTED
|
301
|
+
digest = value.object_id
|
302
|
+
if value.is_a?(Array)
|
303
|
+
idxrow = Stella::Client::Container.sequential_offset(digest, value.size-1)
|
304
|
+
value = value[ idxrow ]
|
305
|
+
Stella.ld "SELECTED(SEQ): #{value} #{idxrow} #{input} #{digest}"
|
306
|
+
end
|
307
|
+
# I think this needs to be updated for global_sequential:
|
308
|
+
@sequential_value[input.object_id] = value
|
309
|
+
end
|
310
|
+
# The resource may be an Array of Arrays (e.g. a CSV file)
|
311
|
+
if value.is_a?(Array) && !idxcol.nil?
|
312
|
+
value = value[ idxcol ]
|
313
|
+
Stella.ld "SELECTED INDEX: #{idxcol} #{value.inspect} "
|
314
|
+
end
|
315
|
+
|
316
|
+
value
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
|
321
|
+
# NOTE: This is global across all users
|
322
|
+
def rsequential(*args)
|
323
|
+
input, idxcol = *std_arg_processor(*args)
|
324
|
+
|
325
|
+
if @rsequential_value[input.object_id]
|
326
|
+
value = @rsequential_value[input.object_id]
|
327
|
+
else
|
328
|
+
value = case input.class.to_s
|
329
|
+
when "Symbol"
|
330
|
+
ret = resource(input)
|
331
|
+
ret
|
332
|
+
when "Array"
|
333
|
+
input
|
334
|
+
when "Range"
|
335
|
+
input.to_a
|
336
|
+
when "Proc"
|
337
|
+
input.call
|
338
|
+
end
|
339
|
+
digest = value.object_id
|
340
|
+
if value.is_a?(Array)
|
341
|
+
idxrow = Stella::Client::Container.rsequential_offset(digest, value.size-1)
|
342
|
+
value = value[ idxrow ]
|
343
|
+
Stella.ld "SELECTED(RSEQ): #{value} #{idxrow} #{input} #{digest}"
|
273
344
|
end
|
274
345
|
|
275
|
-
|
346
|
+
# I think this needs to be updated for global_sequential:
|
347
|
+
@rsequential_value[input.object_id] = value
|
348
|
+
end
|
349
|
+
# The resource may be an Array of Arrays (e.g. a CSV file)
|
350
|
+
if value.is_a?(Array) && !idxcol.nil?
|
351
|
+
value = value[ idxcol ]
|
352
|
+
Stella.ld "SELECTED INDEX: #{idxcol} #{value.inspect} "
|
353
|
+
end
|
354
|
+
value
|
276
355
|
|
277
356
|
end
|
278
357
|
|
279
358
|
|
280
|
-
|
281
|
-
|
359
|
+
private
|
360
|
+
|
361
|
+
def std_arg_processor(*args)
|
362
|
+
input, idxcol = nil, nil
|
282
363
|
if Symbol === args.first
|
283
|
-
input,
|
364
|
+
input, idxcol = *args
|
284
365
|
elsif Array === args.first || args.size == 1
|
285
366
|
input = args.first
|
286
367
|
else
|
287
368
|
input = args
|
288
369
|
end
|
289
|
-
|
290
|
-
if @sequential_value[input.object_id]
|
291
|
-
value = @sequential_value[input.object_id]
|
292
|
-
else
|
293
|
-
value = case input.class.to_s
|
294
|
-
when "Symbol"
|
295
|
-
ret = resource(input)
|
296
|
-
ret
|
297
|
-
when "Array"
|
298
|
-
input
|
299
|
-
when "Range"
|
300
|
-
input.to_a
|
301
|
-
when "Proc"
|
302
|
-
input.call
|
303
|
-
end
|
304
|
-
digest = value.object_id
|
305
|
-
if value.is_a?(Array)
|
306
|
-
index = Stella::Client::Container.sequential_offset(digest, value.size-1)
|
307
|
-
value = value[ index ]
|
308
|
-
end
|
309
|
-
Stella.ld "SELECTED(SEQ): #{value} #{index} #{input} #{digest}"
|
310
|
-
# I think this needs to be updated for global_sequential:
|
311
|
-
@sequential_value[input.object_id] = value
|
312
|
-
end
|
313
|
-
# The resource may be an Array of Arrays (e.g. a CSV file)
|
314
|
-
if value.is_a?(Array) && !index.nil?
|
315
|
-
value = value[ index ]
|
316
|
-
Stella.ld "SELECTED INDEX: #{index} #{value.inspect} "
|
317
|
-
end
|
318
|
-
value
|
319
|
-
|
370
|
+
[input, idxcol]
|
320
371
|
end
|
321
372
|
|
373
|
+
|
322
374
|
end
|
323
375
|
|
324
376
|
end
|
data/lib/stella/client.rb
CHANGED
@@ -13,17 +13,21 @@ module Stella
|
|
13
13
|
include Gibbler::Complex
|
14
14
|
include Observable
|
15
15
|
|
16
|
-
attr_reader :
|
16
|
+
attr_reader :index
|
17
17
|
attr_accessor :base_uri
|
18
18
|
attr_accessor :proxy
|
19
|
+
attr_accessor :created
|
19
20
|
|
20
|
-
|
21
|
+
gibbler :opts, :index, :base_uri, :proxy, :nowait, :created
|
22
|
+
|
23
|
+
def initialize(base_uri=nil, index=1, opts={})
|
24
|
+
@created = Time.now.to_f
|
21
25
|
opts = {
|
22
26
|
:'no-templates' => false
|
23
27
|
}.merge! opts
|
24
28
|
@opts = opts
|
25
|
-
@base_uri, @
|
26
|
-
#@cookie_file = File.new("cookies-#{
|
29
|
+
@base_uri, @index = base_uri, index
|
30
|
+
#@cookie_file = File.new("cookies-#{index}", 'w')
|
27
31
|
@proxy = OpenStruct.new
|
28
32
|
end
|
29
33
|
def execute(usecase, &stat_collector)
|
@@ -47,10 +51,10 @@ module Stella
|
|
47
51
|
# This is for the values that were "set"
|
48
52
|
# in the part before the response body.
|
49
53
|
prepare_resources(container, req.resources)
|
50
|
-
|
54
|
+
|
51
55
|
params = prepare_params(container, req.params)
|
52
56
|
headers = prepare_headers(container, req.headers)
|
53
|
-
|
57
|
+
|
54
58
|
container.params, container.headers = params, headers
|
55
59
|
|
56
60
|
uri = build_request_uri req.uri, params, container
|
@@ -81,7 +85,7 @@ module Stella
|
|
81
85
|
Benelux.add_thread_tags :retry => counter
|
82
86
|
Benelux.add_thread_tags :stella_id => stella_id
|
83
87
|
|
84
|
-
container.unique_id = stella_id
|
88
|
+
container.unique_id = stella_id
|
85
89
|
|
86
90
|
params['__stella'] = container.unique_id unless @opts[:'no-param']
|
87
91
|
headers['X-Stella-ID'] = container.unique_id unless @opts[:'no-header']
|
@@ -175,7 +179,12 @@ module Stella
|
|
175
179
|
private
|
176
180
|
# We use a method so we can time it with Benelux
|
177
181
|
def send_request(http_client, usecase, meth, uri, req, params, headers, container, counter)
|
178
|
-
|
182
|
+
if meth == "delete"
|
183
|
+
args = [meth, uri, headers]
|
184
|
+
else
|
185
|
+
args = [meth, uri, params, headers]
|
186
|
+
end
|
187
|
+
container.response = http_client.send(*args) # booya!
|
179
188
|
end
|
180
189
|
|
181
190
|
def update(kind, *args)
|
@@ -204,7 +213,7 @@ module Stella
|
|
204
213
|
}
|
205
214
|
http_client = HTTPClient.new opts
|
206
215
|
http_client.set_proxy_auth(@proxy.user, @proxy.pass) if @proxy.user
|
207
|
-
http_client.debug_dev = STDOUT if Stella.debug?
|
216
|
+
http_client.debug_dev = STDOUT if Stella.debug? && Stella.stdout.lev >= 3
|
208
217
|
http_client.protocol_version = "HTTP/1.1"
|
209
218
|
http_client.ssl_config.verify_mode = ::OpenSSL::SSL::VERIFY_NONE
|
210
219
|
http_client
|
@@ -221,9 +230,8 @@ module Stella
|
|
221
230
|
newh = {}
|
222
231
|
#Stella.ld "PREPARE HEADERS: #{headers}"
|
223
232
|
hashobj.each_pair do |n,v|
|
224
|
-
v = container.instance_eval &v if v.is_a?(Proc)
|
225
233
|
unless @opts[:'no-templates']
|
226
|
-
v = container.parse_template v
|
234
|
+
v = container.parse_template v
|
227
235
|
end
|
228
236
|
v = extra.call(v) unless extra.nil?
|
229
237
|
newh[n] = v
|