stella 0.7.3.002 → 0.7.4.001
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +9 -0
- data/bin/stella +26 -12
- data/examples/cookies/plan.rb +0 -1
- data/examples/essentials/plan.rb +1 -1
- data/lib/stella.rb +58 -42
- data/lib/stella/cli.rb +12 -4
- data/lib/stella/client.rb +43 -18
- data/lib/stella/client/container.rb +4 -1
- data/lib/stella/common.rb +255 -0
- data/lib/stella/data.rb +6 -4
- data/lib/stella/data/http.rb +126 -2
- data/lib/stella/engine.rb +25 -8
- data/lib/stella/engine/functional.rb +37 -30
- data/lib/stella/engine/load_create.rb +12 -10
- data/lib/stella/engine/load_package.rb +3 -4
- data/lib/stella/engine/load_queue.rb +9 -28
- data/lib/stella/engine/loadbase.rb +218 -82
- data/lib/stella/logger.rb +143 -0
- data/lib/stella/testplan.rb +174 -18
- data/stella.gemspec +5 -18
- metadata +6 -19
- data/lib/stella/client/modifiers.rb +0 -20
- data/lib/stella/config.rb +0 -87
- data/lib/stella/data/http/body.rb +0 -15
- data/lib/stella/data/http/request.rb +0 -129
- data/lib/stella/data/http/response.rb +0 -92
- data/lib/stella/exceptions.rb +0 -20
- data/lib/stella/mixins.rb +0 -5
- data/lib/stella/mixins/numeric.rb +0 -24
- data/lib/stella/mixins/string.rb +0 -16
- data/lib/stella/mixins/thread.rb +0 -6
- data/lib/stella/mixins/time.rb +0 -75
- data/lib/stella/stats.rb +0 -79
- data/lib/stella/testplan/stats.rb +0 -26
- data/lib/stella/testplan/usecase.rb +0 -119
- data/lib/stella/version.rb +0 -15
data/CHANGES.txt
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
STELLA, CHANGES
|
2
2
|
|
3
|
+
#### 0.7.4 (2009-11-11) ###############################
|
4
|
+
|
5
|
+
* FIXED: Proper handling for timeout errors
|
6
|
+
* CHANGE: Log directory is now YYYYMMDD-HH-mm-ss-SHA1
|
7
|
+
* ADDED: Logging to .stella/log
|
8
|
+
* ADDED: Global variables via --var
|
9
|
+
* ADDED: Using naive CSV parsing via quickcsv (CSV lib is slooow for large files)
|
10
|
+
* ADDED: Testplan file cache (load a file only once)
|
11
|
+
|
3
12
|
|
4
13
|
#### 0.7.3 (2009-10-30) ###############################
|
5
14
|
|
data/bin/stella
CHANGED
@@ -13,8 +13,8 @@
|
|
13
13
|
#
|
14
14
|
# $ stella -h
|
15
15
|
# $ stella verify -p plans/basic.rb http://test.example.com/
|
16
|
-
# $ stella
|
17
|
-
# $ stella
|
16
|
+
# $ stella generate -u 10 -t 60 http://test.example.com/
|
17
|
+
# $ stella generate -u 10 -r 40 -p plans/basic.rb http://test.example.com/
|
18
18
|
#
|
19
19
|
#--
|
20
20
|
|
@@ -38,6 +38,15 @@ class Stella::CLI::Definition
|
|
38
38
|
|
39
39
|
#global :A, :apikey, String, "API Key"
|
40
40
|
#global :S, :secret, String, "Secret Key"
|
41
|
+
global :o, :output, String, "Write output to the given file" do |v|
|
42
|
+
String.disable_color
|
43
|
+
Stella.log.output = v
|
44
|
+
end
|
45
|
+
global :var, String, 'Set an arbitrary variable (--var "name=v")' do |var|
|
46
|
+
n, v = *var.split('=')
|
47
|
+
raise "Bad variable format: #{var}" if n.nil? || !n.match(/[a-z]+/i)
|
48
|
+
eval "$#{n} = '#{v}'"
|
49
|
+
end
|
41
50
|
global :p, :pause, Integer, "Seconds to pause before starting test"
|
42
51
|
global :E, :engine, String, "Specify a load engine (experimental)"
|
43
52
|
global :n, :nocolor, "Disable output colors" do
|
@@ -51,8 +60,13 @@ class Stella::CLI::Definition
|
|
51
60
|
Stella.enable_debug
|
52
61
|
end
|
53
62
|
global :v, :verbose, "Increase verbosity of output (e.g. -v or -vv or -vvv)" do
|
54
|
-
Stella.
|
63
|
+
Stella.stdout.lev += 1
|
55
64
|
end
|
65
|
+
global :'disable-stats', "Disable stat collection"
|
66
|
+
global :'disable-logging', "Disable all logging" do
|
67
|
+
Stella::Logger.disable!
|
68
|
+
end
|
69
|
+
global :'disable-templates', "Disable template parsing"
|
56
70
|
global :V, :version, "Display version number" do
|
57
71
|
puts "Stella version: #{Stella::VERSION} (#{Stella::VERSION::PATCH})"
|
58
72
|
exit 0
|
@@ -65,6 +79,10 @@ class Stella::CLI::Definition
|
|
65
79
|
usage "stella example"
|
66
80
|
command :example => Stella::CLI
|
67
81
|
|
82
|
+
about "View Stella configuration"
|
83
|
+
usage "stella config"
|
84
|
+
command :config => Stella::CLI
|
85
|
+
|
68
86
|
about "Preview a test plan"
|
69
87
|
usage "stella preview [-p path/2/testplan.rb] "
|
70
88
|
option :c, :clients, Integer, "Maximum number of virtual clients (ignored)"
|
@@ -103,9 +121,7 @@ class Stella::CLI::Definition
|
|
103
121
|
option :w, :wait, Float, "Wait time (in seconds) between client requests (ignored if testplan supplied)"
|
104
122
|
option :p, :testplan, String, "Path to testplan"
|
105
123
|
option :a, :arrival, Float, "Arrival rate (new clients per second)"
|
106
|
-
option :'disable-templates', "Disable template parsing"
|
107
124
|
command :generate => Stella::CLI
|
108
|
-
|
109
125
|
about "Initialize Stella configuration"
|
110
126
|
command :init do
|
111
127
|
Stella::Config.init
|
@@ -135,11 +151,9 @@ class Stella::CLI::Definition
|
|
135
151
|
end
|
136
152
|
|
137
153
|
after do |obj|
|
138
|
-
Stella.lflush
|
139
154
|
@elapsed = Time.now - @start
|
140
|
-
if
|
141
|
-
puts
|
142
|
-
puts "Elapsed: %.2f seconds" % @elapsed.to_f
|
155
|
+
if @elapsed > 0.1
|
156
|
+
Stella.stdout.puts 2, "#{$/}Elapsed: %.2f seconds" % @elapsed.to_f
|
143
157
|
end
|
144
158
|
code = obj.exit_code if obj.respond_to? :exit_code
|
145
159
|
exit code ||= 0
|
@@ -158,11 +172,11 @@ rescue Drydock::UnknownCommand => ex
|
|
158
172
|
STDERR.puts "Unknown command: %s" % ex.name
|
159
173
|
rescue Stella::Error => ex
|
160
174
|
STDERR.puts ex.message
|
161
|
-
STDERR.puts ex.backtrace if Stella.
|
175
|
+
STDERR.puts ex.backtrace if Stella.stdout.lev > 2 || Stella.debug?
|
162
176
|
rescue Interrupt
|
163
|
-
puts "
|
177
|
+
puts $/, "Exiting... "
|
164
178
|
exit 1
|
165
179
|
rescue => ex
|
166
180
|
STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}"
|
167
|
-
STDERR.puts ex.backtrace if Stella.
|
181
|
+
STDERR.puts ex.backtrace if Stella.stdout.lev > 2 || Stella.debug?
|
168
182
|
end
|
data/examples/cookies/plan.rb
CHANGED
data/examples/essentials/plan.rb
CHANGED
data/lib/stella.rb
CHANGED
@@ -10,53 +10,62 @@ autoload :Drydock, 'drydock'
|
|
10
10
|
autoload :URI, 'uri'
|
11
11
|
autoload :OpenStruct, 'ostruct'
|
12
12
|
autoload :Storable, 'storable'
|
13
|
-
autoload :Gibbler, 'gibbler/aliases'
|
14
13
|
autoload :Attic, 'attic'
|
15
14
|
autoload :ERB, 'erb'
|
16
15
|
|
16
|
+
require 'gibbler/aliases' # important for run time digests and freezes
|
17
17
|
require 'benelux'
|
18
18
|
|
19
|
+
module Stella
|
20
|
+
module VERSION
|
21
|
+
unless defined?(MAJOR)
|
22
|
+
MAJOR = 0.freeze
|
23
|
+
MINOR = 7.freeze
|
24
|
+
TINY = 4.freeze
|
25
|
+
PATCH = '001'.freeze
|
26
|
+
end
|
27
|
+
def self.to_s; [MAJOR, MINOR, TINY].join('.'); end
|
28
|
+
def self.to_f; self.to_s.to_f; end
|
29
|
+
def self.patch; PATCH; end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
module Stella
|
35
|
+
class Error < RuntimeError
|
36
|
+
def initialize(obj=nil); @obj = obj; end
|
37
|
+
def message; @obj; end
|
38
|
+
end
|
39
|
+
class WackyRatio < Stella::Error; end
|
40
|
+
class WackyDuration < Stella::Error; end
|
41
|
+
class InvalidOption < Stella::Error; end
|
42
|
+
class NoHostDefined < Stella::Error; end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
19
46
|
module Stella
|
20
47
|
extend self
|
21
48
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
49
|
+
require 'stella/logger'
|
50
|
+
|
51
|
+
START_TIME = Time.now.freeze
|
52
|
+
|
53
|
+
@globals = {}
|
27
54
|
@sysinfo = nil
|
28
|
-
@logger = Drydock::Screen
|
29
|
-
@loglev = 1
|
30
55
|
@debug = false
|
31
56
|
@abort = false
|
32
|
-
|
57
|
+
@quiet = false
|
58
|
+
@log = Stella::SyncLogger.new
|
59
|
+
@stdout = Stella::Logger.new STDOUT
|
60
|
+
|
33
61
|
class << self
|
34
|
-
attr_accessor :
|
35
|
-
end
|
36
|
-
|
37
|
-
def sleep(metric)
|
38
|
-
unless SLEEP_METRICS.has_key? metric
|
39
|
-
raise "unknown sleep metric: #{metric}"
|
40
|
-
end
|
41
|
-
Kernel.sleep SLEEP_METRICS[metric]
|
62
|
+
attr_accessor :log, :stdout
|
42
63
|
end
|
43
|
-
|
44
|
-
|
45
|
-
def lflush; @logger.flush if @logger.respond_to? :flush; end
|
46
|
-
def li(*msg); msg.each { |m| @logger.puts m } if !quiet? end
|
47
|
-
def li1(*msg); li *msg if @loglev >= 1 end
|
48
|
-
def li2(*msg); li *msg if @loglev >= 2 end
|
49
|
-
def li3(*msg); li *msg if @loglev >= 3 end
|
50
|
-
def li4(*msg); li *msg if @loglev >= 4 end
|
51
|
-
|
52
|
-
# Puts +msg+ to +@logger+ with "ERROR: " prepended
|
53
|
-
def le(*msg); @logger.puts " " << msg.join("#{$/} ").color(:red); end
|
54
|
-
# Puts +msg+ to +@logger+ if +Rudy.debug?+ returns true
|
64
|
+
|
65
|
+
def le(*msg); stdout.info " " << msg.join("#{$/} ").color(:red); end
|
55
66
|
def ld(*msg)
|
56
|
-
|
57
|
-
|
58
|
-
Stella.lflush
|
59
|
-
end
|
67
|
+
return unless Stella.debug?
|
68
|
+
Stella.stdout.info "D(#{Thread.current.object_id}): " << msg.join("#{$/}D: ")
|
60
69
|
end
|
61
70
|
|
62
71
|
def sysinfo
|
@@ -64,10 +73,6 @@ module Stella
|
|
64
73
|
@sysinfo
|
65
74
|
end
|
66
75
|
|
67
|
-
def quiet?() @loglev == 0 end
|
68
|
-
def enable_quiet() @loglev = 0 end
|
69
|
-
def disable_quiet() @loglev = 1 end
|
70
|
-
|
71
76
|
def debug?() @debug == true end
|
72
77
|
def enable_debug() @debug = true end
|
73
78
|
def disable_debug() @debug = false end
|
@@ -75,16 +80,24 @@ module Stella
|
|
75
80
|
def abort?() @abort == true end
|
76
81
|
def abort!() @abort = true end
|
77
82
|
|
83
|
+
def quiet?() @quiet == true end
|
84
|
+
def enable_quiet() @quiet = true end
|
85
|
+
def disable_quiet() @quiet = false end
|
86
|
+
|
87
|
+
def add_global(n,v)
|
88
|
+
Stella.ld "SETGLOBAL: #{n}=#{v}"
|
89
|
+
@globals[n.strip] = v.strip
|
90
|
+
end
|
91
|
+
|
78
92
|
def rescue(&blk)
|
79
93
|
blk.call
|
80
94
|
rescue => ex
|
81
|
-
Stella.
|
82
|
-
Stella.
|
95
|
+
Stella.stdout.info "ERROR: #{ex.message}"
|
96
|
+
Stella.stdout.info ex.backtrace
|
83
97
|
end
|
84
98
|
|
85
|
-
require 'stella/
|
99
|
+
require 'stella/common'
|
86
100
|
|
87
|
-
autoload :VERSION, 'stella/version'
|
88
101
|
autoload :Utils, 'stella/utils'
|
89
102
|
autoload :Config, 'stella/config'
|
90
103
|
autoload :Data, 'stella/data'
|
@@ -92,9 +105,12 @@ module Stella
|
|
92
105
|
autoload :Engine, 'stella/engine'
|
93
106
|
autoload :Client, 'stella/client'
|
94
107
|
|
95
|
-
require 'stella/mixins'
|
96
108
|
end
|
97
109
|
|
110
|
+
Stella.stdout.lev = Stella.quiet? ? 0 : 1
|
111
|
+
Stella.stdout.autoflush!
|
112
|
+
|
113
|
+
|
98
114
|
|
99
115
|
|
100
116
|
|
data/lib/stella/cli.rb
CHANGED
@@ -7,6 +7,10 @@ class Stella::CLI < Drydock::Command
|
|
7
7
|
@exit_code = 0
|
8
8
|
end
|
9
9
|
|
10
|
+
def config
|
11
|
+
puts @conf.to_yaml
|
12
|
+
end
|
13
|
+
|
10
14
|
def verify_valid?
|
11
15
|
create_testplan
|
12
16
|
end
|
@@ -26,15 +30,19 @@ class Stella::CLI < Drydock::Command
|
|
26
30
|
def generate
|
27
31
|
opts = {}
|
28
32
|
opts[:hosts] = @hosts
|
29
|
-
[:nowait, :clients, :repetitions, :duration, :arrival
|
33
|
+
[:nowait, :clients, :repetitions, :duration, :arrival].each do |opt|
|
30
34
|
opts[opt] = @option.send(opt) unless @option.send(opt).nil?
|
31
35
|
end
|
32
|
-
|
36
|
+
[:'disable-templates', :'disable-stats'].each do |opt|
|
37
|
+
opts[opt] = @global.send(opt) unless @global.send(opt).nil?
|
38
|
+
end
|
33
39
|
case @global.engine
|
34
40
|
when "package"
|
35
41
|
ret = Stella::Engine::LoadPackage.run @testplan, opts
|
36
42
|
when "create"
|
37
43
|
ret = Stella::Engine::LoadCreate.run @testplan, opts
|
44
|
+
when "redis"
|
45
|
+
ret = Stella::Engine::LoadRedis.run @testplan, opts
|
38
46
|
else
|
39
47
|
ret = Stella::Engine::LoadQueue.run @testplan, opts
|
40
48
|
end
|
@@ -68,7 +76,7 @@ class Stella::CLI < Drydock::Command
|
|
68
76
|
|
69
77
|
def preview
|
70
78
|
create_testplan
|
71
|
-
Stella.
|
79
|
+
Stella.stdout.info @testplan.pretty(Stella.stdout.lev > 1)
|
72
80
|
end
|
73
81
|
|
74
82
|
private
|
@@ -89,7 +97,7 @@ class Stella::CLI < Drydock::Command
|
|
89
97
|
end
|
90
98
|
@testplan.check! # raise errors, update usecase ratios
|
91
99
|
@testplan.freeze # cascades through usecases and requests
|
92
|
-
Stella.
|
100
|
+
Stella.stdout.info2 " #{@option.testplan || @testplan.desc} (#{@testplan.digest})"
|
93
101
|
true
|
94
102
|
end
|
95
103
|
|
data/lib/stella/client.rb
CHANGED
@@ -5,7 +5,7 @@ Stella::Utils.require_vendor "httpclient", '2.1.5.2'
|
|
5
5
|
|
6
6
|
module Stella
|
7
7
|
class Client
|
8
|
-
|
8
|
+
|
9
9
|
require 'stella/client/container'
|
10
10
|
|
11
11
|
include Gibbler::Complex
|
@@ -58,18 +58,19 @@ module Stella
|
|
58
58
|
user, pass = http_auth.user, http_auth.pass
|
59
59
|
user = container.instance_eval &user if Proc === user
|
60
60
|
pass = container.instance_eval &pass if Proc === pass
|
61
|
-
|
61
|
+
update(:authenticate, usecase, req, http_auth.kind, domain, user, pass)
|
62
62
|
http_client.set_auth(domain, user, pass)
|
63
63
|
end
|
64
64
|
|
65
65
|
raise NoHostDefined, req.uri if uri.host.nil? || uri.host.empty?
|
66
|
-
stella_id = [Time.now, self.digest_cache, req.digest_cache, params, headers, counter].gibbler
|
66
|
+
stella_id = [Time.now.to_f, self.digest_cache, req.digest_cache, params, headers, counter].gibbler
|
67
67
|
|
68
68
|
Benelux.add_thread_tags :request => req.digest_cache
|
69
69
|
Benelux.add_thread_tags :retry => counter
|
70
70
|
Benelux.add_thread_tags :stella_id => stella_id
|
71
71
|
|
72
|
-
|
72
|
+
container.unique_id = stella_id
|
73
|
+
params['__stella'] = headers['X-Stella-ID'] = container.unique_id[0..10]
|
73
74
|
|
74
75
|
meth = req.http_method.to_s.downcase
|
75
76
|
Stella.ld "#{req.http_method}: " << "#{req.uri} " << params.inspect
|
@@ -77,6 +78,7 @@ module Stella
|
|
77
78
|
ret, asset_duration = nil, 0
|
78
79
|
begin
|
79
80
|
send_request http_client, usecase, meth, uri, req, params, headers, container, counter
|
81
|
+
update(:receive_response, usecase, uri, req, params, headers, counter, container)
|
80
82
|
Benelux.add_thread_tags :status => container.status
|
81
83
|
res = container.response
|
82
84
|
[
|
@@ -93,35 +95,35 @@ module Stella
|
|
93
95
|
container.assets.each do |uri|
|
94
96
|
Benelux.add_thread_tags :asset => uri
|
95
97
|
a = http_client.get uri
|
96
|
-
Stella.
|
98
|
+
Stella.stdout.info3 " FETCH ASSET: #{uri} #{a.status}"
|
97
99
|
Benelux.remove_thread_tags :asset
|
98
100
|
end
|
99
101
|
asset_duration = Time.now - asset_start
|
100
|
-
|
102
|
+
rescue HTTPClient::ConnectTimeoutError => ex
|
103
|
+
update(:request_timeout, usecase, uri, req, params, headers, counter, container)
|
101
104
|
rescue => ex
|
102
|
-
|
103
|
-
update(:
|
105
|
+
#p "111111111111111111111111#{ex.class}: #{ex.message}"
|
106
|
+
update(:request_unhandled_exception, usecase, uri, req, params, ex)
|
104
107
|
Benelux.remove_thread_tags :status, :retry, :request, :stella_id
|
105
108
|
next
|
106
109
|
end
|
107
110
|
|
108
|
-
Stella.lflush
|
109
|
-
|
110
111
|
run_sleeper(req.wait, asset_duration) if req.wait != 0 && !nowait?
|
111
112
|
|
112
113
|
# TODO: consider throw/catch
|
113
114
|
case ret.class.to_s
|
114
115
|
when "Stella::Client::Repeat"
|
116
|
+
update(:request_repeat, counter, ret.times+1, uri, container)
|
115
117
|
Benelux.remove_thread_tags :status
|
116
|
-
update(:repeat_request, counter, ret.times+1)
|
117
118
|
redo if counter <= ret.times
|
118
119
|
when "Stella::Client::Quit"
|
120
|
+
update(:usecase_quit, ret.message, uri, container)
|
119
121
|
Benelux.remove_thread_tags :status
|
120
|
-
update(:quit_usecase, ret.message)
|
121
122
|
break
|
122
123
|
when "Stella::Client::Fail"
|
123
|
-
|
124
|
-
|
124
|
+
update(:request_fail, ret.message, uri, container)
|
125
|
+
when "Stella::Client::Error"
|
126
|
+
update(:request_error, ret.message, uri, container)
|
125
127
|
end
|
126
128
|
|
127
129
|
Benelux.remove_thread_tags :status
|
@@ -137,9 +139,9 @@ module Stella
|
|
137
139
|
def nowait?; @nowait == true; end
|
138
140
|
|
139
141
|
private
|
142
|
+
# We use a method so we can time it with Benelux
|
140
143
|
def send_request(http_client, usecase, meth, uri, req, params, headers, container, counter)
|
141
144
|
container.response = http_client.send(meth, uri, params, headers) # booya!
|
142
|
-
update(:receive_response, usecase, uri, req, params, counter, container)
|
143
145
|
end
|
144
146
|
|
145
147
|
def update(kind, *args)
|
@@ -168,7 +170,7 @@ module Stella
|
|
168
170
|
}
|
169
171
|
http_client = HTTPClient.new opts
|
170
172
|
http_client.set_proxy_auth(@proxy.user, @proxy.pass) if @proxy.user
|
171
|
-
http_client.debug_dev = STDOUT if Stella.debug? && Stella.
|
173
|
+
http_client.debug_dev = STDOUT if Stella.debug? && Stella.stdout.lev > 3
|
172
174
|
http_client.protocol_version = "HTTP/1.1"
|
173
175
|
http_client.ssl_config.verify_mode = ::OpenSSL::SSL::VERIFY_NONE
|
174
176
|
http_client
|
@@ -268,7 +270,9 @@ module Stella
|
|
268
270
|
ret = nil
|
269
271
|
handler = find_response_handler container, req
|
270
272
|
if handler.nil?
|
271
|
-
|
273
|
+
if container.status >= 400
|
274
|
+
update(:request_fail, "No handler", req.uri, container)
|
275
|
+
end
|
272
276
|
return
|
273
277
|
end
|
274
278
|
begin
|
@@ -293,4 +297,25 @@ module Stella
|
|
293
297
|
end
|
294
298
|
|
295
299
|
end
|
296
|
-
end
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
class Stella::Client
|
304
|
+
|
305
|
+
class ResponseModifier
|
306
|
+
attr_accessor :message
|
307
|
+
def initialize(msg=nil)
|
308
|
+
@message = msg
|
309
|
+
end
|
310
|
+
end
|
311
|
+
class Repeat < ResponseModifier;
|
312
|
+
attr_accessor :times
|
313
|
+
def initialize(times)
|
314
|
+
@times = times
|
315
|
+
end
|
316
|
+
end
|
317
|
+
class Quit < ResponseModifier; end
|
318
|
+
class Fail < Quit; end
|
319
|
+
class Error < Quit; end
|
320
|
+
|
321
|
+
end
|