stella 0.7.0.019 → 0.7.1
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 +1 -1
- data/README.rdoc +5 -6
- data/Rudyfile +32 -20
- data/bin/stella +1 -2
- data/examples/essentials/plan.rb +1 -1
- data/examples/exceptions/plan.rb +1 -1
- data/lib/stella.rb +0 -4
- data/lib/stella/cli.rb +9 -1
- data/lib/stella/engine.rb +10 -6
- data/lib/stella/engine/functional.rb +5 -1
- data/lib/stella/engine/load_create.rb +84 -0
- data/lib/stella/engine/load_package.rb +39 -0
- data/lib/stella/engine/load_queue.rb +85 -0
- data/lib/stella/engine/{load.rb → loadbase.rb} +18 -86
- data/lib/stella/testplan.rb +4 -2
- data/lib/stella/version.rb +2 -2
- data/stella.gemspec +9 -5
- data/support/sample_webapp/app.rb +11 -8
- data/tryouts/proofs/thread_queue.rb +21 -0
- data/vendor/httpclient-2.1.5.2/httpclient.rb +2 -0
- data/vendor/httpclient-2.1.5.2/httpclient/http.rb +4 -2
- metadata +12 -8
data/CHANGES.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Stella - 0.7 PREVIEW
|
2
2
|
|
3
|
-
<b>
|
3
|
+
<b>Blame Stella for breaking your web applications.</b>
|
4
4
|
|
5
5
|
== Features
|
6
6
|
|
@@ -24,8 +24,8 @@ This is an early preview of Stella. The following features are still under devel
|
|
24
24
|
# by running a single user functional test.
|
25
25
|
$ stella verify -p examples/basic/plan.rb http://stellaaahhhh.com/
|
26
26
|
|
27
|
-
# Generate
|
28
|
-
$ stella generate -p examples/basic/plan.rb http://stellaaahhhh.com/
|
27
|
+
# Generate load using the same test plan.
|
28
|
+
$ stella generate -p examples/basic/plan.rb -c 50 http://stellaaahhhh.com/
|
29
29
|
|
30
30
|
|
31
31
|
== Test Plan Example
|
@@ -47,8 +47,8 @@ Test plans are defined in the Ruby programming language. This makes it possible
|
|
47
47
|
|
48
48
|
get "/search", "Search Results" do
|
49
49
|
wait 2..5
|
50
|
-
param :what => '
|
51
|
-
param :where => '
|
50
|
+
param :what => 'Sarsaparilla'
|
51
|
+
param :where => 'Lexington'
|
52
52
|
response 200 do
|
53
53
|
listing = doc.css('div.listing').first
|
54
54
|
set :lid, listing['id'].match(/(\d+)/)[0]
|
@@ -99,7 +99,6 @@ Get it in one of the following ways:
|
|
99
99
|
== Credits
|
100
100
|
|
101
101
|
* Delano Mandelbaum (http://solutious.com)
|
102
|
-
* Threadify (C) Ara T Howard (http://codeforpeople.com/)
|
103
102
|
|
104
103
|
|
105
104
|
== Thanks
|
data/Rudyfile
CHANGED
@@ -11,16 +11,19 @@ machines do
|
|
11
11
|
|
12
12
|
env :stage do
|
13
13
|
|
14
|
-
role :app do
|
14
|
+
role :app do
|
15
|
+
positions 2
|
15
16
|
user :root
|
16
|
-
size 'm1.small'
|
17
|
+
size 'm1.small'
|
17
18
|
end
|
18
|
-
|
19
|
+
|
19
20
|
role :gen do
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
user :root
|
22
|
+
size 'm1.large'
|
23
|
+
ami 'ami-f0f61599'
|
24
|
+
end
|
23
25
|
end
|
26
|
+
|
24
27
|
|
25
28
|
end
|
26
29
|
|
@@ -36,6 +39,8 @@ commands do
|
|
36
39
|
allow :thin
|
37
40
|
allow :stella
|
38
41
|
allow :rm
|
42
|
+
allow :ulimit
|
43
|
+
|
39
44
|
allow :rackup_path do
|
40
45
|
"/usr/lib/ruby/gems/1.8/gems/stella-#{Stella::VERSION}/support/sample_webapp/config.ru"
|
41
46
|
end
|
@@ -48,7 +53,11 @@ routines do
|
|
48
53
|
# rudy -r app -v start
|
49
54
|
start do
|
50
55
|
remote do
|
51
|
-
|
56
|
+
ulimit :n, '30000'
|
57
|
+
ulimit :n
|
58
|
+
rm 'thin.log'
|
59
|
+
mkdir :p, 'stats'
|
60
|
+
thin :d, :l, 'thin.log', :p, 3114, :R, rackup_path, '--stats', './stats', '--max-conns', 8192, 'start'
|
52
61
|
end
|
53
62
|
end
|
54
63
|
|
@@ -61,10 +70,6 @@ routines do
|
|
61
70
|
end
|
62
71
|
end
|
63
72
|
|
64
|
-
end
|
65
|
-
|
66
|
-
role :gen do
|
67
|
-
|
68
73
|
# rudy -v -r gen verify ip-10-251-27-245.ec2.internal:3114
|
69
74
|
verify do
|
70
75
|
remote do |arg|
|
@@ -75,13 +80,16 @@ routines do
|
|
75
80
|
# rudy -v -r gen generate ip-10-251-27-245.ec2.internal:3114
|
76
81
|
generate do
|
77
82
|
remote do |arg|
|
78
|
-
|
83
|
+
ulimit :n, '30000'
|
84
|
+
ulimit :n
|
85
|
+
stella :v, 'generate', :c, 200, :d, '10m', :W, "#{arg.first}"
|
79
86
|
end
|
80
87
|
end
|
81
88
|
|
82
89
|
end
|
83
|
-
|
84
|
-
setup do
|
90
|
+
|
91
|
+
setup do
|
92
|
+
before :startup
|
85
93
|
after :sysupdate, :installdeps, :install_gem
|
86
94
|
end
|
87
95
|
|
@@ -90,7 +98,11 @@ routines do
|
|
90
98
|
|
91
99
|
reboot do
|
92
100
|
end
|
93
|
-
|
101
|
+
|
102
|
+
install_netperf do
|
103
|
+
#ftp://ftp.netperf.org/netperf/netperf-2.4.5.tar.bz2
|
104
|
+
end
|
105
|
+
|
94
106
|
install_rubyforge do
|
95
107
|
remote :root do
|
96
108
|
gem_install 'stella', :V
|
@@ -127,7 +139,6 @@ routines do
|
|
127
139
|
|
128
140
|
end
|
129
141
|
|
130
|
-
|
131
142
|
installdeps do
|
132
143
|
remote :root do
|
133
144
|
gem_install "test-spec", "rspec", "camping", "fcgi", "memcache-client"
|
@@ -148,13 +159,14 @@ routines do
|
|
148
159
|
end
|
149
160
|
end
|
150
161
|
|
151
|
-
sysupdate
|
152
|
-
remote
|
162
|
+
sysupdate {
|
163
|
+
remote {
|
153
164
|
apt_get "update"
|
154
165
|
apt_get "install", "libxml2-dev", "libxslt-dev"
|
155
166
|
apt_get "install", "build-essential", "git-core"
|
156
167
|
apt_get "install", "ruby1.8-dev", "rdoc", "libzlib-ruby", "rubygems"
|
157
168
|
apt_get "install", "libfcgi-dev", "libfcgi-ruby1.8"
|
169
|
+
apt_get "install", "joe", "siege", "httperf"
|
158
170
|
gem_sources :a, "http://gems.github.com"
|
159
171
|
mkdir :p, "/var/lib/gems/1.8/bin" # Doesn't get created, but causes Rubygems to fail
|
160
172
|
gem_install "builder", "session"
|
@@ -162,8 +174,8 @@ routines do
|
|
162
174
|
gem_install 'rubygems-update', "-v=1.3.4"
|
163
175
|
update_rubygems
|
164
176
|
gem_install 'hoe'
|
165
|
-
|
166
|
-
|
177
|
+
}
|
178
|
+
}
|
167
179
|
|
168
180
|
|
169
181
|
end
|
data/bin/stella
CHANGED
@@ -39,6 +39,7 @@ class Stella::CLI::Definition
|
|
39
39
|
#global :A, :apikey, String, "API Key"
|
40
40
|
#global :S, :secret, String, "Secret Key"
|
41
41
|
global :p, :pause, Integer, "Seconds to pause before starting test"
|
42
|
+
global :E, :engine, String, "Specify a load engine (experimental)"
|
42
43
|
global :n, :nocolor, "Disable output colors" do
|
43
44
|
String.disable_color
|
44
45
|
end
|
@@ -100,8 +101,6 @@ class Stella::CLI::Definition
|
|
100
101
|
option :w, :wait, Float, "Wait time (in seconds) between client requests (ignored if testplan supplied)"
|
101
102
|
option :p, :testplan, String, "Path to testplan"
|
102
103
|
command :generate => Stella::CLI
|
103
|
-
# command_alias :generate, :load
|
104
|
-
# command_alias :generate, :stress
|
105
104
|
|
106
105
|
about "Initialize Stella configuration"
|
107
106
|
command :init do
|
data/examples/essentials/plan.rb
CHANGED
data/examples/exceptions/plan.rb
CHANGED
@@ -9,7 +9,7 @@ usecase "Exception Handling" do
|
|
9
9
|
|
10
10
|
get "/search", "Search Results" do
|
11
11
|
param :what => 'No Such Listing'
|
12
|
-
param :where => random('Toronto', 'Montreal', 'Vancouver')
|
12
|
+
param :where => random(['Toronto', 'Montreal', 'Vancouver'])
|
13
13
|
response 404 do
|
14
14
|
raise NoSearchResults
|
15
15
|
end
|
data/lib/stella.rb
CHANGED
data/lib/stella/cli.rb
CHANGED
@@ -29,7 +29,15 @@ class Stella::CLI < Drydock::Command
|
|
29
29
|
[:nowait, :clients, :repetitions, :duration].each do |opt|
|
30
30
|
opts[opt] = @option.send(opt) unless @option.send(opt).nil?
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
|
+
case @global.engine
|
34
|
+
when "package"
|
35
|
+
ret = Stella::Engine::LoadPackage.run @testplan, opts
|
36
|
+
when "create"
|
37
|
+
ret = Stella::Engine::LoadCreate.run @testplan, opts
|
38
|
+
else
|
39
|
+
ret = Stella::Engine::LoadQueue.run @testplan, opts
|
40
|
+
end
|
33
41
|
@exit_code = (ret ? 0 : 1)
|
34
42
|
end
|
35
43
|
|
data/lib/stella/engine.rb
CHANGED
@@ -60,15 +60,19 @@ module Stella::Engine
|
|
60
60
|
def update_request_error(*args) raise end
|
61
61
|
|
62
62
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
|
64
|
+
autoload :Functional, 'stella/engine/functional'
|
65
|
+
autoload :Load, 'stella/engine/loadbase'
|
66
|
+
autoload :LoadPackage, 'stella/engine/load_package'
|
67
|
+
autoload :LoadCreate, 'stella/engine/load_create'
|
68
|
+
autoload :LoadQueue, 'stella/engine/load_queue'
|
69
|
+
|
67
70
|
# These timers are interesting from a reporting perspective.
|
68
71
|
Benelux.add_counter Stella::Client, :execute_response_handler
|
69
72
|
Benelux.add_timer HTTPClient, :do_request
|
70
|
-
|
71
|
-
Benelux.add_timer HTTPClient::Session, :
|
73
|
+
## These are contained in connect
|
74
|
+
#Benelux.add_timer HTTPClient::Session, :create_socket
|
75
|
+
#Benelux.add_timer HTTPClient::Session, :create_ssl_socket
|
72
76
|
Benelux.add_timer HTTPClient::Session, :connect
|
73
77
|
Benelux.add_timer HTTPClient::Session, :query
|
74
78
|
Benelux.add_timer HTTPClient::Session, :socket_gets_first_byte
|
@@ -44,7 +44,9 @@ module Stella::Engine
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def update_receive_response(client_id, usecase, uri, req, params, counter, container)
|
47
|
-
|
47
|
+
msg = ' %-59s ' % [uri]
|
48
|
+
msg << container.status.to_s if Stella.loglev == 1
|
49
|
+
Stella.li msg
|
48
50
|
|
49
51
|
Stella.li2 ' ' << container.response.request.header.send(:request_line)
|
50
52
|
|
@@ -58,6 +60,8 @@ module Stella::Engine
|
|
58
60
|
Stella.li2 " %s: %s" % pair
|
59
61
|
end
|
60
62
|
|
63
|
+
Stella.li2 $/, " Response-Status: %3d" % [container.status]
|
64
|
+
|
61
65
|
Stella.li2 $/, " Response-Headers:"
|
62
66
|
container.headers.all.each do |pair|
|
63
67
|
Stella.li2 " %s: %s" % pair
|
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
module Stella::Engine
|
3
|
+
module LoadCreate
|
4
|
+
extend Stella::Engine::Base
|
5
|
+
extend Stella::Engine::Load
|
6
|
+
extend self
|
7
|
+
|
8
|
+
|
9
|
+
def execute_test_plan(packages, reps=1, duration=0)
|
10
|
+
time_started = Time.now
|
11
|
+
|
12
|
+
(1..reps).to_a.each { |rep|
|
13
|
+
@real_reps += 1 # Increments when duration is specified.
|
14
|
+
Stella.li3 "*** REPETITION #{@real_reps} of #{reps} ***"
|
15
|
+
packages.each { |package|
|
16
|
+
if running_threads.size <= packages.size
|
17
|
+
@threads << Thread.new do
|
18
|
+
c, uc = package.client, package.usecase
|
19
|
+
msg = "THREAD START: client %s: " % [c.digest.short]
|
20
|
+
msg << "%s:%s (rep: %d)" % [uc.desc, uc.digest.short, @real_reps]
|
21
|
+
Stella.li4 $/, "======== " << msg
|
22
|
+
# This thread will stay on this one track.
|
23
|
+
Benelux.current_track c.digest
|
24
|
+
Benelux.add_thread_tags :usecase => uc.digest_cache
|
25
|
+
|
26
|
+
Benelux.add_thread_tags :rep => @real_reps
|
27
|
+
Stella::Engine::Load.rescue(c.digest_cache) {
|
28
|
+
break if Stella.abort?
|
29
|
+
print '.' if Stella.loglev == 2
|
30
|
+
stats = c.execute uc
|
31
|
+
}
|
32
|
+
Benelux.remove_thread_tags :rep
|
33
|
+
Benelux.remove_thread_tags :usecase
|
34
|
+
|
35
|
+
end
|
36
|
+
Stella.sleep :create_thread
|
37
|
+
end
|
38
|
+
|
39
|
+
if running_threads.size > @max_clients
|
40
|
+
@max_clients = running_threads.size
|
41
|
+
end
|
42
|
+
|
43
|
+
if @mode == :rolling
|
44
|
+
tries = 0
|
45
|
+
while (reps > 1 || duration > 0) && running_threads.size >= packages.size
|
46
|
+
Stella.sleep :check_threads
|
47
|
+
msg = "#{running_threads.size} (max: #{@max_clients})"
|
48
|
+
Stella.li3 "*** RUNNING THREADS: #{msg} ***"
|
49
|
+
(tries += 1)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
}
|
53
|
+
|
54
|
+
if @mode != :rolling && running_threads.size > 0
|
55
|
+
args = [running_threads.size, @max_clients]
|
56
|
+
Stella.li3 "*** WAITING FOR %d THREADS TO FINISH (max: %d) ***" % args
|
57
|
+
@threads.each { |t| t.join } # wait
|
58
|
+
end
|
59
|
+
|
60
|
+
# If a duration was given, we make sure
|
61
|
+
# to run for only that amount of time.
|
62
|
+
# TODO: do not redo if
|
63
|
+
# time_elapsed + usecase.mean > duration
|
64
|
+
if duration > 0
|
65
|
+
time_elapsed = (Time.now - time_started).to_i
|
66
|
+
msg = "#{time_elapsed} of #{duration} (threads: %d)" % running_threads.size
|
67
|
+
Stella.li3 "*** TIME ELAPSED: #{msg} ***"
|
68
|
+
redo if time_elapsed <= duration
|
69
|
+
break if time_elapsed >= duration
|
70
|
+
end
|
71
|
+
|
72
|
+
}
|
73
|
+
|
74
|
+
if @mode == :rolling && running_threads.size > 0
|
75
|
+
Stella.li3 "*** WAITING FOR THREADS TO FINISH ***"
|
76
|
+
@threads.each { |t| t.join } # wait
|
77
|
+
end
|
78
|
+
Stella.li2 $/, $/
|
79
|
+
end
|
80
|
+
|
81
|
+
Benelux.add_timer Stella::Engine::LoadCreate, :execute_test_plan
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module Stella::Engine
|
3
|
+
module LoadPackage
|
4
|
+
extend Stella::Engine::Base
|
5
|
+
extend Stella::Engine::Load
|
6
|
+
extend self
|
7
|
+
|
8
|
+
|
9
|
+
def execute_test_plan(packages, reps=1,duration=0)
|
10
|
+
require 'threadify'
|
11
|
+
|
12
|
+
Thread.ify packages, :threads => packages.size do |package|
|
13
|
+
Thread.current[:real_reps] = 0
|
14
|
+
# This thread will stay on this one track.
|
15
|
+
Benelux.current_track package.client.gibbler
|
16
|
+
Benelux.add_thread_tags :usecase => package.usecase.digest_cache
|
17
|
+
(1..reps).to_a.each do |rep|
|
18
|
+
Thread.current[:real_reps] += 1
|
19
|
+
Benelux.add_thread_tags :rep => rep
|
20
|
+
Stella::Engine::Load.rescue(package.client.digest_cache) {
|
21
|
+
break if Stella.abort?
|
22
|
+
print '.' if Stella.loglev == 2
|
23
|
+
stats = package.client.execute package.usecase
|
24
|
+
}
|
25
|
+
Benelux.remove_thread_tags :rep
|
26
|
+
Stella.sleep :check_threads
|
27
|
+
end
|
28
|
+
|
29
|
+
Benelux.remove_thread_tags :usecase
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
Stella.li2 $/, $/
|
34
|
+
end
|
35
|
+
|
36
|
+
Benelux.add_timer Stella::Engine::LoadPackage, :execute_test_plan
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
|
2
|
+
module Stella::Engine
|
3
|
+
module LoadQueue
|
4
|
+
extend Stella::Engine::Base
|
5
|
+
extend Stella::Engine::Load
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def execute_test_plan(packages, reps=1,duration=0)
|
9
|
+
time_started = Time.now
|
10
|
+
|
11
|
+
pqueue = Queue.new
|
12
|
+
packages.each { |p| pqueue << p }
|
13
|
+
|
14
|
+
@real_reps += 1 # Increments when duration is specified.
|
15
|
+
@threads = []
|
16
|
+
packages.size.times {
|
17
|
+
@max_clients += 1
|
18
|
+
@threads << Thread.new do
|
19
|
+
package = pqueue.pop
|
20
|
+
Thread.current[:real_reps] = 0
|
21
|
+
Thread.current[:real_uctime] = Benelux::Stats::Calculator.new
|
22
|
+
c, uc = package.client, package.usecase
|
23
|
+
Stella.li4 $/, "======== THREAD %s: START" % [c.digest.short]
|
24
|
+
|
25
|
+
# This thread will stay on this one track.
|
26
|
+
Benelux.current_track c.digest
|
27
|
+
Benelux.add_thread_tags :usecase => uc.digest_cache
|
28
|
+
|
29
|
+
Thread.current[:real_uctime].first_tick
|
30
|
+
prev_ptime ||= Time.now
|
31
|
+
reps.times { |rep|
|
32
|
+
break if Stella.abort?
|
33
|
+
Thread.current[:real_reps] += 1
|
34
|
+
args = [c.digest.short, uc.desc, uc.digest.short, Thread.current[:real_reps]]
|
35
|
+
Stella.li4 $/, "======== THREAD %s: %s:%s (rep: %d)" % args
|
36
|
+
|
37
|
+
Benelux.add_thread_tags :rep => rep
|
38
|
+
#Stella.li [package.client.gibbler.shorter, package.usecase.gibbler.shorter, rep].inspect
|
39
|
+
Stella::Engine::Load.rescue(c.digest_cache) {
|
40
|
+
break if Stella.abort?
|
41
|
+
print '.' if Stella.loglev == 2
|
42
|
+
stats = c.execute uc
|
43
|
+
}
|
44
|
+
Benelux.remove_thread_tags :rep
|
45
|
+
|
46
|
+
Thread.current[:real_uctime].tick
|
47
|
+
time_elapsed = (Time.now - time_started).to_i
|
48
|
+
|
49
|
+
if Stella.loglev >= 2 &&
|
50
|
+
Thread.current == @threads.first &&
|
51
|
+
(Time.now - prev_ptime).to_i >= 5
|
52
|
+
prev_ptime, ruct = Time.now, Thread.current[:real_uctime]
|
53
|
+
args = [time_elapsed.to_i, ruct.n, ruct.mean, ruct.sd]
|
54
|
+
Stella.li2 $/, "REAL UC TIME: %ds (reps: %d): %.4fs %.4f(SD)" % args
|
55
|
+
Stella.lflush
|
56
|
+
end
|
57
|
+
|
58
|
+
# If a duration was given, we make sure
|
59
|
+
# to run for only that amount of time.
|
60
|
+
if duration > 0
|
61
|
+
break if (time_elapsed+Thread.current[:real_uctime].mean) >= duration
|
62
|
+
redo if (time_elapsed+Thread.current[:real_uctime].mean) <= duration
|
63
|
+
end
|
64
|
+
}
|
65
|
+
|
66
|
+
Benelux.remove_thread_tags :usecase
|
67
|
+
|
68
|
+
pqueue << package # return the package to the queue
|
69
|
+
end
|
70
|
+
}
|
71
|
+
|
72
|
+
repscalc = Benelux::Stats::Calculator.new
|
73
|
+
@threads.each { |t| t.join } # wait
|
74
|
+
@threads.each { |t| repscalc.sample(t[:real_reps]) }
|
75
|
+
@real_reps = repscalc.mean.to_i
|
76
|
+
|
77
|
+
#Stella.li "*** REPETITION #{@real_reps} of #{reps} ***"
|
78
|
+
|
79
|
+
Stella.li2 $/, $/
|
80
|
+
end
|
81
|
+
|
82
|
+
Benelux.add_timer Stella::Engine::LoadQueue, :execute_test_plan
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -13,9 +13,10 @@ module Stella::Engine
|
|
13
13
|
|
14
14
|
def run(plan, opts={})
|
15
15
|
opts = process_options! plan, opts
|
16
|
+
@threads, @max_clients, @real_reps = [], 0, 0
|
16
17
|
|
17
18
|
if Stella.loglev > 1
|
18
|
-
Load.timers += [:
|
19
|
+
Load.timers += [:query, :connect, :socket_gets_first_byte, :get_body]
|
19
20
|
Load.counts = [:request_header_size, :request_content_size]
|
20
21
|
Load.counts += [:response_headers_size, :response_content_size]
|
21
22
|
end
|
@@ -42,35 +43,37 @@ module Stella::Engine
|
|
42
43
|
rescue Interrupt
|
43
44
|
Stella.li "Stopping test...", $/
|
44
45
|
Stella.abort!
|
46
|
+
@threads.each { |t| t.join } unless @threads.nil? || @threads.empty? # wait
|
45
47
|
ensure
|
46
48
|
Stella.li "Processing statistics...", $/
|
47
49
|
Stella.lflush
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
+
Benelux.update_global_timeline
|
52
|
+
|
53
|
+
bt = Benelux.timeline
|
51
54
|
tt = Benelux.thread_timeline
|
52
|
-
test_time = tt.stats.group(:execute_test_plan).mean
|
53
55
|
|
56
|
+
test_time = tt.stats.group(:execute_test_plan).mean
|
54
57
|
generate_report plan, test_time
|
58
|
+
report_time = tt.stats.group(:generate_report).mean
|
55
59
|
|
56
|
-
#
|
60
|
+
# Here is the calcualtion for the number of
|
61
|
+
# Benelux assets created for each request:
|
62
|
+
#
|
63
|
+
# [5*2*REQ+6, 5*1*REQ+3, 13*REQ]
|
64
|
+
#
|
57
65
|
|
58
66
|
Stella.li "Summary: "
|
59
67
|
Stella.li " max clients: %d" % @max_clients
|
60
68
|
Stella.li " repetitions: %d" % @real_reps
|
61
69
|
Stella.li " test time: %10.2fs" % test_time
|
62
|
-
Stella.li "
|
63
|
-
Stella.li " post time: %10.2fs" % tt.stats.group(:generate_report).mean
|
70
|
+
Stella.li " post time: %10.2fs" % report_time
|
64
71
|
Stella.li $/
|
65
72
|
end
|
66
73
|
|
67
74
|
# errors?
|
68
75
|
end
|
69
76
|
|
70
|
-
def wait_for_reporter
|
71
|
-
Benelux.reporter.force_update
|
72
|
-
end
|
73
|
-
|
74
77
|
protected
|
75
78
|
class ThreadPackage
|
76
79
|
attr_accessor :index
|
@@ -119,78 +122,10 @@ module Stella::Engine
|
|
119
122
|
packages.compact # TODO: Why one nil element sometimes?
|
120
123
|
end
|
121
124
|
|
122
|
-
def execute_test_plan(
|
123
|
-
|
124
|
-
|
125
|
-
@threads, @max_clients, @real_reps = [], 0, 0
|
126
|
-
(1..reps).to_a.each { |rep|
|
127
|
-
@real_reps += 1 # Increments when duration is specified.
|
128
|
-
Stella.li3 "*** REPETITION #{@real_reps} of #{reps} ***"
|
129
|
-
packages.each { |package|
|
130
|
-
if running_threads.size <= packages.size
|
131
|
-
@threads << Thread.new do
|
132
|
-
c, uc = package.client, package.usecase
|
133
|
-
msg = "THREAD START: client %s: " % [c.digest.short]
|
134
|
-
msg << "%s:%s (rep: %d)" % [uc.desc, uc.digest.short, @real_reps]
|
135
|
-
Stella.li4 $/, "======== " << msg
|
136
|
-
# This thread will stay on this one track.
|
137
|
-
Benelux.current_track c.digest
|
138
|
-
Benelux.add_thread_tags :usecase => uc.digest_cache
|
139
|
-
|
140
|
-
Benelux.add_thread_tags :rep => @real_reps
|
141
|
-
Stella::Engine::Load.rescue(c.digest_cache) {
|
142
|
-
break if Stella.abort?
|
143
|
-
print '.' if Stella.loglev == 2
|
144
|
-
stats = c.execute uc
|
145
|
-
}
|
146
|
-
Benelux.remove_thread_tags :rep
|
147
|
-
Benelux.remove_thread_tags :usecase
|
148
|
-
|
149
|
-
end
|
150
|
-
Stella.sleep :create_thread
|
151
|
-
end
|
152
|
-
|
153
|
-
if running_threads.size > @max_clients
|
154
|
-
@max_clients = running_threads.size
|
155
|
-
end
|
156
|
-
|
157
|
-
if @mode == :rolling
|
158
|
-
tries = 0
|
159
|
-
while (reps > 1 || duration > 0) && running_threads.size >= packages.size
|
160
|
-
Stella.sleep :check_threads
|
161
|
-
msg = "#{running_threads.size} (max: #{@max_clients})"
|
162
|
-
Stella.li3 "*** RUNNING THREADS: #{msg} ***"
|
163
|
-
(tries += 1)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
}
|
167
|
-
|
168
|
-
if @mode != :rolling && running_threads.size > 0
|
169
|
-
args = [running_threads.size, @max_clients]
|
170
|
-
Stella.li3 "*** WAITING FOR %d THREADS TO FINISH (max: %d) ***" % args
|
171
|
-
@threads.each { |t| t.join } # wait
|
172
|
-
end
|
173
|
-
|
174
|
-
# If a duration was given, we make sure
|
175
|
-
# to run for only that amount of time.
|
176
|
-
# TODO: do not redo if
|
177
|
-
# time_elapsed + usecase.mean > duration
|
178
|
-
if duration > 0
|
179
|
-
time_elapsed = (Time.now - time_started).to_i
|
180
|
-
msg = "#{time_elapsed} of #{duration} (threads: %d)" % running_threads.size
|
181
|
-
Stella.li3 "*** TIME ELAPSED: #{msg} ***"
|
182
|
-
redo if time_elapsed <= duration
|
183
|
-
break if time_elapsed >= duration
|
184
|
-
end
|
185
|
-
|
186
|
-
}
|
187
|
-
|
188
|
-
if @mode == :rolling && running_threads.size > 0
|
189
|
-
Stella.li3 "*** WAITING FOR THREADS TO FINISH ***"
|
190
|
-
@threads.each { |t| t.join } # wait
|
191
|
-
end
|
192
|
-
Stella.li2 $/, $/
|
125
|
+
def execute_test_plan(*args)
|
126
|
+
raise "Override execute_test_plan method in #{self}"
|
193
127
|
end
|
128
|
+
|
194
129
|
def running_threads
|
195
130
|
@threads.select { |t| t.status } # non-false status are still running
|
196
131
|
end
|
@@ -330,12 +265,9 @@ module Stella::Engine
|
|
330
265
|
Stella.li3 ex.backtrace
|
331
266
|
end
|
332
267
|
|
333
|
-
|
334
268
|
Benelux.add_timer Stella::Engine::Load, :build_thread_package
|
335
|
-
Benelux.add_timer Stella::Engine::Load, :execute_test_plan
|
336
269
|
Benelux.add_timer Stella::Engine::Load, :generate_report
|
337
|
-
|
338
|
-
|
270
|
+
|
339
271
|
end
|
340
272
|
end
|
341
273
|
|
data/lib/stella/testplan.rb
CHANGED
@@ -4,9 +4,11 @@ require 'stella/testplan/stats'
|
|
4
4
|
module Stella
|
5
5
|
class Testplan
|
6
6
|
include Gibbler::Complex
|
7
|
+
extend Attic
|
8
|
+
|
9
|
+
attic :base_path
|
7
10
|
|
8
11
|
attr_accessor :usecases
|
9
|
-
attr_accessor :base_path
|
10
12
|
attr_accessor :desc
|
11
13
|
attr_reader :stats
|
12
14
|
|
@@ -67,7 +69,7 @@ class Testplan
|
|
67
69
|
ratio, name = args[0], args[1] if args[0].is_a?(Numeric)
|
68
70
|
ratio, name = args[1], args[0] if args[0].is_a?(String)
|
69
71
|
uc = Stella::Testplan::Usecase.new
|
70
|
-
uc.base_path =
|
72
|
+
uc.base_path = self.base_path
|
71
73
|
uc.instance_eval &blk
|
72
74
|
uc.ratio, uc.desc = (ratio || -1).to_f, name
|
73
75
|
@testplan_current_ratio += uc.ratio if uc.ratio > 0
|
data/lib/stella/version.rb
CHANGED
@@ -5,8 +5,8 @@ module Stella
|
|
5
5
|
unless defined?(MAJOR)
|
6
6
|
MAJOR = 0.freeze
|
7
7
|
MINOR = 7.freeze
|
8
|
-
TINY =
|
9
|
-
PATCH = '
|
8
|
+
TINY = 1.freeze
|
9
|
+
PATCH = '001'.freeze
|
10
10
|
end
|
11
11
|
def self.to_s; [MAJOR, MINOR, TINY, PATCH].join('.'); end
|
12
12
|
def self.to_f; self.to_s.to_f; end
|
data/stella.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "stella"
|
3
3
|
s.rubyforge_project = 'stella'
|
4
|
-
s.version = "0.7.
|
5
|
-
s.summary = "Stella
|
4
|
+
s.version = "0.7.1"
|
5
|
+
s.summary = "Blame Stella for breaking your web applications."
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|
8
8
|
s.email = "delano@solutious.com"
|
@@ -15,9 +15,9 @@
|
|
15
15
|
|
16
16
|
s.executables = %w[stella]
|
17
17
|
|
18
|
-
s.add_dependency 'benelux', '>= 0.
|
18
|
+
s.add_dependency 'benelux', '>= 0.5.0'
|
19
19
|
s.add_dependency 'drydock', '>= 0.6.8'
|
20
|
-
s.add_dependency 'gibbler', '>= 0.7.
|
20
|
+
s.add_dependency 'gibbler', '>= 0.7.1'
|
21
21
|
s.add_dependency 'sysinfo', '>= 0.7.0'
|
22
22
|
s.add_dependency 'storable', '>= 0.5.8'
|
23
23
|
s.add_dependency 'nokogiri'
|
@@ -51,7 +51,10 @@
|
|
51
51
|
lib/stella/data/http/response.rb
|
52
52
|
lib/stella/engine.rb
|
53
53
|
lib/stella/engine/functional.rb
|
54
|
-
lib/stella/engine/
|
54
|
+
lib/stella/engine/load_create.rb
|
55
|
+
lib/stella/engine/load_package.rb
|
56
|
+
lib/stella/engine/load_queue.rb
|
57
|
+
lib/stella/engine/loadbase.rb
|
55
58
|
lib/stella/exceptions.rb
|
56
59
|
lib/stella/guidelines.rb
|
57
60
|
lib/stella/mixins.rb
|
@@ -73,6 +76,7 @@
|
|
73
76
|
support/useragents.txt
|
74
77
|
tryouts/01_numeric_mixins_tryouts.rb
|
75
78
|
tryouts/12_digest_tryouts.rb
|
79
|
+
tryouts/proofs/thread_queue.rb
|
76
80
|
vendor/httpclient-2.1.5.2/httpclient.rb
|
77
81
|
vendor/httpclient-2.1.5.2/httpclient/auth.rb
|
78
82
|
vendor/httpclient-2.1.5.2/httpclient/cacert.p7s
|
@@ -24,14 +24,15 @@ set :reload => true
|
|
24
24
|
set :max_listings => 1000
|
25
25
|
|
26
26
|
LISTINGS = [
|
27
|
-
{ :id => 1000, :name => 'John West Smoked Oysters', :city => 'Toronto'
|
28
|
-
{ :id => 1001, :name => 'Fire Town Lightning Rods', :city => 'Toronto'
|
29
|
-
{ :id => 1002, :name => 'Oversized Pen and Ink Co', :city => 'Toronto'
|
30
|
-
{ :id => 1003, :name => 'The Rathzenburg Brothers', :city => 'Toronto'
|
31
|
-
{ :id => 1004, :name => 'Forever and Always Beads', :city => 'Montreal'
|
32
|
-
{ :id => 1005, :name => "Big Al's Flavour Country", :city => 'Montreal'
|
33
|
-
{ :id => 1006, :name => 'Big Time Furniture World', :city => 'Montreal'
|
34
|
-
{ :id => 1007, :name => 'High-End Keyboard Makers', :city => 'Montreal'
|
27
|
+
{ :id => 1000, :name => 'John West Smoked Oysters', :city => 'Toronto' },
|
28
|
+
{ :id => 1001, :name => 'Fire Town Lightning Rods', :city => 'Toronto' },
|
29
|
+
{ :id => 1002, :name => 'Oversized Pen and Ink Co', :city => 'Toronto' },
|
30
|
+
{ :id => 1003, :name => 'The Rathzenburg Brothers', :city => 'Toronto' },
|
31
|
+
{ :id => 1004, :name => 'Forever and Always Beads', :city => 'Montreal' },
|
32
|
+
{ :id => 1005, :name => "Big Al's Flavour Country", :city => 'Montreal' },
|
33
|
+
{ :id => 1006, :name => 'Big Time Furniture World', :city => 'Montreal' },
|
34
|
+
{ :id => 1007, :name => 'High-End Keyboard Makers', :city => 'Montreal' },
|
35
|
+
{ :id => 1009, :name => 'Sarsaparilla Making Bros', :city => 'Lexington' }
|
35
36
|
]
|
36
37
|
|
37
38
|
set :listings => LISTINGS.clone
|
@@ -50,6 +51,7 @@ end
|
|
50
51
|
|
51
52
|
get '/' do
|
52
53
|
@title << " - Search"
|
54
|
+
#sleep 0.05
|
53
55
|
erb :search_form
|
54
56
|
end
|
55
57
|
|
@@ -141,6 +143,7 @@ before do
|
|
141
143
|
@cookie[:location] = ''
|
142
144
|
set :listings => LISTINGS.clone
|
143
145
|
end
|
146
|
+
sleep 0.05 if params[:enablesleep]
|
144
147
|
@cookie[:history].delete params[:what]
|
145
148
|
@cookie[:history].unshift params[:what] unless blank?(params[:what])
|
146
149
|
@cookie[:history].pop if @cookie[:history].size > 5
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
queue = Queue.new
|
4
|
+
|
5
|
+
producer = Thread.new do
|
6
|
+
5.times do |i|
|
7
|
+
sleep rand(i) # simulate expense
|
8
|
+
queue << i
|
9
|
+
puts "#{i} produced"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
consumer = Thread.new do
|
14
|
+
5.times do |i|
|
15
|
+
value = queue.pop
|
16
|
+
sleep rand(i/2) # simulate expense
|
17
|
+
puts "consumed #{value}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
consumer.join
|
@@ -1005,6 +1005,8 @@ private
|
|
1005
1005
|
|
1006
1006
|
def do_get_header(req, res, sess)
|
1007
1007
|
res.version, res.status, res.reason, headers = sess.get_header
|
1008
|
+
## NOTE: If you re-enable, investigate whether it
|
1009
|
+
## should call Benelux.timeline.add_count instead
|
1008
1010
|
#Benelux.thread_timeline.add_count :response_header_size, res.header
|
1009
1011
|
headers.each do |key, value|
|
1010
1012
|
res.header.add(key, value)
|
@@ -456,8 +456,10 @@ module HTTP
|
|
456
456
|
dev << header
|
457
457
|
end
|
458
458
|
|
459
|
-
|
460
|
-
|
459
|
+
## NOTE: If you re-enable, investigate whether it
|
460
|
+
## should call Benelux.timeline.add_count instead
|
461
|
+
##Benelux.thread_timeline.add_count :data_sent, header_size, :type => :header
|
462
|
+
##Benelux.thread_timeline.add_count :data_sent, body_size, :type => :body
|
461
463
|
|
462
464
|
dev
|
463
465
|
end
|
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.
|
4
|
+
version: 0.7.1
|
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-10-
|
12
|
+
date: 2009-10-21 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 0.5.0
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: drydock
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.7.
|
43
|
+
version: 0.7.1
|
44
44
|
version:
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
46
|
name: sysinfo
|
@@ -72,7 +72,7 @@ dependencies:
|
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: "0"
|
74
74
|
version:
|
75
|
-
description:
|
75
|
+
description: Blame Stella for breaking your web applications.
|
76
76
|
email: delano@solutious.com
|
77
77
|
executables:
|
78
78
|
- stella
|
@@ -109,7 +109,10 @@ files:
|
|
109
109
|
- lib/stella/data/http/response.rb
|
110
110
|
- lib/stella/engine.rb
|
111
111
|
- lib/stella/engine/functional.rb
|
112
|
-
- lib/stella/engine/
|
112
|
+
- lib/stella/engine/load_create.rb
|
113
|
+
- lib/stella/engine/load_package.rb
|
114
|
+
- lib/stella/engine/load_queue.rb
|
115
|
+
- lib/stella/engine/loadbase.rb
|
113
116
|
- lib/stella/exceptions.rb
|
114
117
|
- lib/stella/guidelines.rb
|
115
118
|
- lib/stella/mixins.rb
|
@@ -131,6 +134,7 @@ files:
|
|
131
134
|
- support/useragents.txt
|
132
135
|
- tryouts/01_numeric_mixins_tryouts.rb
|
133
136
|
- tryouts/12_digest_tryouts.rb
|
137
|
+
- tryouts/proofs/thread_queue.rb
|
134
138
|
- vendor/httpclient-2.1.5.2/httpclient.rb
|
135
139
|
- vendor/httpclient-2.1.5.2/httpclient/auth.rb
|
136
140
|
- vendor/httpclient-2.1.5.2/httpclient/cacert.p7s
|
@@ -150,7 +154,7 @@ post_install_message:
|
|
150
154
|
rdoc_options:
|
151
155
|
- --line-numbers
|
152
156
|
- --title
|
153
|
-
-
|
157
|
+
- Blame Stella for breaking your web applications.
|
154
158
|
- --main
|
155
159
|
- README.rdoc
|
156
160
|
require_paths:
|
@@ -173,6 +177,6 @@ rubyforge_project: stella
|
|
173
177
|
rubygems_version: 1.3.2
|
174
178
|
signing_key:
|
175
179
|
specification_version: 3
|
176
|
-
summary:
|
180
|
+
summary: Blame Stella for breaking your web applications.
|
177
181
|
test_files: []
|
178
182
|
|