stella 0.7.0.015 → 0.7.0.017
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 +3 -3
- data/README.rdoc +2 -6
- data/Rudyfile +3 -3
- data/bin/stella +38 -26
- data/examples/cookies/plan.rb +9 -1
- data/examples/csvdata/plan.rb +27 -0
- data/examples/csvdata/search_terms.csv +14 -0
- data/examples/essentials/plan.rb +6 -6
- data/examples/essentials/{search_terms.csv → search_terms.txt} +0 -0
- data/examples/exceptions/plan.rb +9 -2
- data/lib/stella.rb +73 -48
- data/lib/stella/cli.rb +9 -23
- data/lib/stella/client.rb +10 -9
- data/lib/stella/client/container.rb +11 -1
- data/lib/stella/data.rb +114 -61
- data/lib/stella/data/http.rb +1 -1
- data/lib/stella/data/http/request.rb +7 -7
- data/lib/stella/engine.rb +36 -11
- data/lib/stella/engine/functional.rb +9 -8
- data/lib/stella/engine/load.rb +311 -14
- data/lib/stella/exceptions.rb +7 -2
- data/lib/stella/mixins.rb +4 -1
- data/lib/stella/mixins/numeric.rb +11 -10
- data/lib/stella/mixins/string.rb +12 -0
- data/lib/stella/mixins/time.rb +75 -0
- data/lib/stella/testplan.rb +15 -18
- data/lib/stella/testplan/usecase.rb +16 -5
- data/lib/stella/utils.rb +7 -5
- data/lib/stella/version.rb +1 -1
- data/stella.gemspec +11 -7
- data/tryouts/01_numeric_mixins_tryouts.rb +40 -0
- data/tryouts/12_digest_tryouts.rb +42 -0
- metadata +12 -17
- data/lib/stella/engine/stress.rb +0 -293
data/lib/stella/exceptions.rb
CHANGED
@@ -6,10 +6,15 @@ module Stella
|
|
6
6
|
def message; "#{self.class}: #{@obj}"; end
|
7
7
|
end
|
8
8
|
|
9
|
-
class
|
9
|
+
class WackyRatio < Stella::Error
|
10
10
|
end
|
11
11
|
|
12
|
-
class
|
12
|
+
class WackyDuration < Stella::Error
|
13
|
+
end
|
14
|
+
|
15
|
+
class InvalidOption < Stella::Error
|
13
16
|
end
|
14
17
|
|
18
|
+
class NoHostDefined < Stella::Error
|
19
|
+
end
|
15
20
|
end
|
data/lib/stella/mixins.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
|
2
2
|
|
3
3
|
class Numeric
|
4
|
-
|
4
|
+
include Time::Units
|
5
|
+
# TODO: Use 1024?
|
5
6
|
def to_bytes
|
6
7
|
args = case self.abs.to_i
|
7
|
-
when 0..
|
8
|
+
when 0..1000
|
8
9
|
[(self).to_s, 'B']
|
9
|
-
when
|
10
|
-
[(self / 1000).to_s, 'KB']
|
11
|
-
when
|
12
|
-
[(self / (1000**2)).to_s, 'MB']
|
13
|
-
when
|
14
|
-
[(self / (1000**3)).to_s, 'GB']
|
15
|
-
when
|
16
|
-
[(self / (1000**4)).to_s, 'TB']
|
10
|
+
when (1000)..(1000**2)
|
11
|
+
[(self / 1000.to_f).to_s, 'KB']
|
12
|
+
when (1000**2)..(1000**3)
|
13
|
+
[(self / (1000**2).to_f).to_s, 'MB']
|
14
|
+
when (1000**3)..(1000**4)
|
15
|
+
[(self / (1000**3).to_f).to_s, 'GB']
|
16
|
+
when (1000**4)..(1000**6)
|
17
|
+
[(self / (1000**4).to_f).to_s, 'TB']
|
17
18
|
else
|
18
19
|
[self, 'B']
|
19
20
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
$KCODE = "u" if RUBY_VERSION =~ /^1.8/
|
4
|
+
|
5
|
+
class Time
|
6
|
+
module Units
|
7
|
+
PER_MICROSECOND = 0.000001.freeze
|
8
|
+
PER_MILLISECOND = 0.001.freeze
|
9
|
+
PER_MINUTE = 60.0.freeze
|
10
|
+
PER_HOUR = 3600.0.freeze
|
11
|
+
PER_DAY = 86400.0.freeze
|
12
|
+
|
13
|
+
def microseconds() seconds * PER_MICROSECOND end
|
14
|
+
def milliseconds() seconds * PER_MILLISECOND end
|
15
|
+
def seconds() self end
|
16
|
+
def minutes() seconds * PER_MINUTE end
|
17
|
+
def hours() seconds * PER_HOUR end
|
18
|
+
def days() seconds * PER_DAY end
|
19
|
+
def weeks() seconds * PER_DAY * 7 end
|
20
|
+
def years() seconds * PER_DAY * 365 end
|
21
|
+
|
22
|
+
def in_years() seconds / PER_DAY / 365 end
|
23
|
+
def in_weeks() seconds / PER_DAY / 7 end
|
24
|
+
def in_days() seconds / PER_DAY end
|
25
|
+
def in_hours() seconds / PER_HOUR end
|
26
|
+
def in_minutes() seconds / PER_MINUTE end
|
27
|
+
def in_milliseconds() seconds / PER_MILLISECOND end
|
28
|
+
def in_microseconds() seconds / PER_MICROSECOND end
|
29
|
+
|
30
|
+
def in_seconds(u=nil)
|
31
|
+
case u.to_s
|
32
|
+
when /\A(y)|(years?)\z/
|
33
|
+
years
|
34
|
+
when /\A(w)|(weeks?)\z/
|
35
|
+
weeks
|
36
|
+
when /\A(d)|(days?)\z/
|
37
|
+
days
|
38
|
+
when /\A(h)|(hours?)\z/
|
39
|
+
hours
|
40
|
+
when /\A(m)|(minutes?)\z/
|
41
|
+
minutes
|
42
|
+
when /\A(ms)|(milliseconds?)\z/
|
43
|
+
milliseconds
|
44
|
+
when /\A(us)|(microseconds?)|(μs)\z/
|
45
|
+
microseconds
|
46
|
+
else
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
## JRuby doesn't like using instance_methods.select here.
|
52
|
+
## It could be a bug or something quirky with Attic
|
53
|
+
## (although it works in 1.8 and 1.9). The error:
|
54
|
+
##
|
55
|
+
## lib/attic.rb:32:in `select': yield called out of block (LocalJumpError)
|
56
|
+
## lib/stella/mixins/numeric.rb:24
|
57
|
+
##
|
58
|
+
## Create singular methods, like hour and day.
|
59
|
+
# instance_methods.select.each do |plural|
|
60
|
+
# singular = plural.to_s.chop
|
61
|
+
# alias_method singular, plural
|
62
|
+
# end
|
63
|
+
|
64
|
+
alias_method :ms, :milliseconds
|
65
|
+
alias_method :'μs', :microseconds
|
66
|
+
alias_method :second, :seconds
|
67
|
+
alias_method :minute, :minutes
|
68
|
+
alias_method :hour, :hours
|
69
|
+
alias_method :day, :days
|
70
|
+
alias_method :week, :weeks
|
71
|
+
alias_method :year, :years
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
data/lib/stella/testplan.rb
CHANGED
@@ -5,9 +5,6 @@ module Stella
|
|
5
5
|
class Testplan
|
6
6
|
include Gibbler::Complex
|
7
7
|
|
8
|
-
class WackyRatio < Stella::Error
|
9
|
-
end
|
10
|
-
|
11
8
|
attr_accessor :usecases
|
12
9
|
attr_accessor :base_path
|
13
10
|
attr_accessor :desc
|
@@ -17,8 +14,9 @@ class Testplan
|
|
17
14
|
@desc, @usecases = "Test plan", []
|
18
15
|
@testplan_current_ratio = 0
|
19
16
|
@stats = Stella::Testplan::Stats.new
|
20
|
-
|
17
|
+
|
21
18
|
unless uris.empty?
|
19
|
+
uris = [uris] unless Array === uris
|
22
20
|
usecase = Stella::Testplan::Usecase.new
|
23
21
|
usecase.ratio = 1.0
|
24
22
|
uris.each do |uri|
|
@@ -26,9 +24,7 @@ class Testplan
|
|
26
24
|
uri = URI.parse uri
|
27
25
|
uri.path = '/' if uri.path.nil? || uri.path.empty?
|
28
26
|
req = usecase.add_request :get, uri.path
|
29
|
-
req.wait = opts[:
|
30
|
-
req.gibbler
|
31
|
-
req.freeze
|
27
|
+
req.wait = opts[:wait] if opts[:wait]
|
32
28
|
end
|
33
29
|
self.add_usecase usecase
|
34
30
|
end
|
@@ -40,8 +36,6 @@ class Testplan
|
|
40
36
|
plan.base_path = File.dirname path
|
41
37
|
# eval so the DSL code can be executed in this namespace.
|
42
38
|
plan.instance_eval conf
|
43
|
-
plan.gibbler
|
44
|
-
plan.freeze
|
45
39
|
plan
|
46
40
|
end
|
47
41
|
|
@@ -56,14 +50,17 @@ class Testplan
|
|
56
50
|
if @testplan_current_ratio > 1.0
|
57
51
|
msg = "Usecase ratio cannot be higher than 1.0"
|
58
52
|
msg << " (#{@testplan_current_ratio})"
|
59
|
-
raise WackyRatio, msg
|
60
|
-
end
|
61
|
-
@usecases.each do |uc|
|
62
|
-
uc.gibbler # make sure gibbler_cache has a value
|
63
|
-
uc.freeze # make sure all clients share identical usecases
|
53
|
+
raise Stella::WackyRatio, msg
|
64
54
|
end
|
65
55
|
end
|
66
|
-
|
56
|
+
|
57
|
+
# make sure all clients share identical test plans
|
58
|
+
def freeze
|
59
|
+
@usecases.each { |uc| uc.freeze }
|
60
|
+
super
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
67
64
|
def usecase(*args, &blk)
|
68
65
|
return @usecases if args.empty?
|
69
66
|
ratio, name = nil,nil
|
@@ -91,15 +88,15 @@ class Testplan
|
|
91
88
|
|
92
89
|
def pretty(long=false)
|
93
90
|
str = []
|
94
|
-
dig = long ? self.
|
91
|
+
dig = long ? self.digest_cache : self.digest_cache.shorter
|
95
92
|
str << " %-66s ".att(:reverse) % ["#{@desc} (#{dig})"]
|
96
93
|
@usecases.each_with_index do |uc,i|
|
97
|
-
dig = long ? uc.
|
94
|
+
dig = long ? uc.digest_cache : uc.digest_cache.shorter
|
98
95
|
desc = uc.desc || "Usecase ##{i+1}"
|
99
96
|
desc += " (#{dig}) "
|
100
97
|
str << (' ' << " %-61s %s%% ".att(:reverse).bright) % [desc, uc.ratio_pretty]
|
101
98
|
requests = uc.requests.each do |r|
|
102
|
-
dig = long ? r.
|
99
|
+
dig = long ? r.digest_cache : r.digest_cache.shorter
|
103
100
|
str << " %-62s".bright % ["#{r.desc} (#{dig})"]
|
104
101
|
str << " %s" % [r]
|
105
102
|
if Stella.loglev > 2
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
autoload :CSV, 'csv'
|
2
2
|
|
3
3
|
module Stella
|
4
4
|
class Testplan
|
@@ -19,13 +19,15 @@ class Testplan
|
|
19
19
|
#
|
20
20
|
class Usecase
|
21
21
|
include Gibbler::Complex
|
22
|
+
extend Attic
|
23
|
+
|
24
|
+
attic :base_path # we don't want gibbler to see this
|
22
25
|
|
23
26
|
attr_accessor :desc
|
24
27
|
attr_writer :ratio
|
25
28
|
|
26
29
|
attr_accessor :requests
|
27
30
|
attr_accessor :resources
|
28
|
-
attr_accessor :base_path
|
29
31
|
|
30
32
|
class UnknownResource < Stella::Error
|
31
33
|
def message; "UnknownResource: #{@obj}"; end
|
@@ -60,7 +62,7 @@ class Testplan
|
|
60
62
|
# Reads the contents of the file <tt>path</tt> (the current working
|
61
63
|
# directory is assumed to be the same directory containing the test plan).
|
62
64
|
def read(path)
|
63
|
-
path = File.join(
|
65
|
+
path = File.join(base_path, path) if base_path
|
64
66
|
File.read(path)
|
65
67
|
end
|
66
68
|
|
@@ -68,13 +70,22 @@ class Testplan
|
|
68
70
|
read(path).split $/
|
69
71
|
end
|
70
72
|
|
73
|
+
def csv(path)
|
74
|
+
path = File.join(base_path, path) if base_path
|
75
|
+
CSV.read(path)
|
76
|
+
end
|
77
|
+
|
78
|
+
def freeze
|
79
|
+
@requests.each { |r| r.freeze }
|
80
|
+
super
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
71
84
|
def add_request(meth, *args, &blk)
|
72
85
|
req = Stella::Data::HTTP::Request.new meth.to_s.upcase, args[0], &blk
|
73
86
|
req.desc = args[1] if args.size > 1 # Description is optional
|
74
87
|
Stella.ld req
|
75
88
|
@requests << req
|
76
|
-
req.gibbler
|
77
|
-
req.freeze
|
78
89
|
req
|
79
90
|
end
|
80
91
|
def get(*args, &blk); add_request :get, *args, &blk; end
|
data/lib/stella/utils.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
|
2
|
-
require 'socket'
|
3
|
-
|
4
|
-
require 'date'
|
5
|
-
require 'timeout'
|
2
|
+
require 'socket' # Why doesn't socket work with autoload?
|
3
|
+
autoload :Timeout, 'timeout'
|
6
4
|
|
7
5
|
module Stella
|
8
6
|
|
@@ -66,10 +64,14 @@ module Stella
|
|
66
64
|
# vendor/httpclient-2.1.5.2/httpclient
|
67
65
|
#
|
68
66
|
def require_vendor(name, version)
|
69
|
-
$:.unshift File.join(
|
67
|
+
$:.unshift File.join(STELLA_LIB_HOME, '..', 'vendor', "#{name}-#{version}")
|
70
68
|
require name
|
71
69
|
end
|
72
70
|
|
71
|
+
# Same as <tt>require_vendor</tt>, but uses <tt>autoload</tt> instead.
|
72
|
+
def autoload_vendor(mod, name, version)
|
73
|
+
autoload mod, File.join(STELLA_LIB_HOME, '..', 'vendor', "#{name}-#{version}", name)
|
74
|
+
end
|
73
75
|
|
74
76
|
# Checks whether something is listening to a socket.
|
75
77
|
# * +host+ A hostname
|
data/lib/stella/version.rb
CHANGED
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.0.
|
4
|
+
s.version = "0.7.0.017"
|
5
5
|
s.summary = "Stella: Perform load tests on your web applications with beauty and brute strength."
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|
@@ -15,12 +15,11 @@
|
|
15
15
|
|
16
16
|
s.executables = %w[stella]
|
17
17
|
|
18
|
-
s.add_dependency 'benelux', '>= 0.4.
|
18
|
+
s.add_dependency 'benelux', '>= 0.4.3'
|
19
19
|
s.add_dependency 'drydock', '>= 0.6.8'
|
20
|
-
s.add_dependency 'gibbler', '>= 0.
|
20
|
+
s.add_dependency 'gibbler', '>= 0.7.0'
|
21
21
|
s.add_dependency 'sysinfo', '>= 0.7.0'
|
22
|
-
s.add_dependency 'storable', '>= 0.5.
|
23
|
-
s.add_dependency 'httpclient', '>= 2.1.5'
|
22
|
+
s.add_dependency 'storable', '>= 0.5.8'
|
24
23
|
s.add_dependency 'nokogiri'
|
25
24
|
|
26
25
|
# = MANIFEST =
|
@@ -33,9 +32,11 @@
|
|
33
32
|
Rudyfile
|
34
33
|
bin/stella
|
35
34
|
examples/cookies/plan.rb
|
35
|
+
examples/csvdata/plan.rb
|
36
|
+
examples/csvdata/search_terms.csv
|
36
37
|
examples/essentials/logo.png
|
37
38
|
examples/essentials/plan.rb
|
38
|
-
examples/essentials/search_terms.
|
39
|
+
examples/essentials/search_terms.txt
|
39
40
|
examples/exceptions/plan.rb
|
40
41
|
lib/stella.rb
|
41
42
|
lib/stella/cli.rb
|
@@ -51,12 +52,13 @@
|
|
51
52
|
lib/stella/engine.rb
|
52
53
|
lib/stella/engine/functional.rb
|
53
54
|
lib/stella/engine/load.rb
|
54
|
-
lib/stella/engine/stress.rb
|
55
55
|
lib/stella/exceptions.rb
|
56
56
|
lib/stella/guidelines.rb
|
57
57
|
lib/stella/mixins.rb
|
58
58
|
lib/stella/mixins/numeric.rb
|
59
|
+
lib/stella/mixins/string.rb
|
59
60
|
lib/stella/mixins/thread.rb
|
61
|
+
lib/stella/mixins/time.rb
|
60
62
|
lib/stella/stats.rb
|
61
63
|
lib/stella/testplan.rb
|
62
64
|
lib/stella/testplan/stats.rb
|
@@ -69,6 +71,8 @@
|
|
69
71
|
support/sample_webapp/app.rb
|
70
72
|
support/sample_webapp/config.ru
|
71
73
|
support/useragents.txt
|
74
|
+
tryouts/01_numeric_mixins_tryouts.rb
|
75
|
+
tryouts/12_digest_tryouts.rb
|
72
76
|
vendor/httpclient-2.1.5.2/httpclient.rb
|
73
77
|
vendor/httpclient-2.1.5.2/httpclient/auth.rb
|
74
78
|
vendor/httpclient-2.1.5.2/httpclient/cacert.p7s
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
#encoding: utf-8
|
3
|
+
$KCODE = "u" if RUBY_VERSION =~ /^1.8/
|
4
|
+
|
5
|
+
group "Numeric mixins"
|
6
|
+
library :stella, 'lib'
|
7
|
+
|
8
|
+
tryouts "Natural language" do
|
9
|
+
|
10
|
+
drill "base == 1.hour", 1.hour, 3600
|
11
|
+
drill "1.milliseconds", 1.milliseconds, 0.001
|
12
|
+
drill "1.microseconds", 1.microseconds, 0.000001
|
13
|
+
drill "10.minutes / 60.seconds", 10.minutes / 60.seconds, 10
|
14
|
+
drill "1.day", 1.day, 86400
|
15
|
+
drill "1.year == 365.days", 1.year, 31536000
|
16
|
+
drill "1.week == 7.days", 1.week, 604800
|
17
|
+
drill "1.week == 186.hours", 1.week, 168.hours
|
18
|
+
|
19
|
+
drill "60.in_minutes", 60.in_minutes, 1
|
20
|
+
drill "3600.in_hours", 3600.in_hours, 1
|
21
|
+
drill "5400.in_hours", 5400.in_hours, 1.5
|
22
|
+
drill "604800.in_days", 604800.in_days, 7
|
23
|
+
|
24
|
+
drill "60.hours - 1.day", 60.hours - 1.day, 129600.0
|
25
|
+
drill "1.year - 5.days", 1.year - 5.days, 31104000.0
|
26
|
+
|
27
|
+
drill "100 - 90", 100 - 90, 10.seconds
|
28
|
+
drill "90 + 9", 51 + 9, 1.minute
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
tryouts "Bytes" do
|
34
|
+
drill "1000 == 1000.00B", 1000.to_bytes, "1000.00B"
|
35
|
+
drill "1010", 1010.to_bytes, "1.01KB"
|
36
|
+
drill "1020100", (1010 ** 2).to_bytes, "1.02MB"
|
37
|
+
drill "1030301000", (1010 ** 3).to_bytes, "1.03GB"
|
38
|
+
drill "1040604010000", (1010 ** 4).to_bytes, "1.04TB"
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
group "Stella"
|
3
|
+
library :stella, 'lib'
|
4
|
+
tryouts "Object Digests" do
|
5
|
+
setup do
|
6
|
+
#Gibbler.enable_debug
|
7
|
+
end
|
8
|
+
clean do
|
9
|
+
Gibbler.disable_debug
|
10
|
+
end
|
11
|
+
|
12
|
+
dream "90199c341ea7ea4e22139e690e3d68a78ec6fce3"
|
13
|
+
drill "Request can gibbler" do
|
14
|
+
r = Stella::Data::HTTP::Request.new :get, '/'
|
15
|
+
r.digest
|
16
|
+
end
|
17
|
+
|
18
|
+
dream "9ef5fb0707526e47547b3e6a59d8d3e3de64667f"
|
19
|
+
drill "Usecase can gibbler" do
|
20
|
+
u = Stella::Testplan::Usecase.new
|
21
|
+
u.digest
|
22
|
+
end
|
23
|
+
|
24
|
+
dream "0d5d6ac215563f09d4143d7e1ca9ac0611cc164d"
|
25
|
+
drill "Testplan can gibbler" do
|
26
|
+
t = Stella::Testplan.new 'localhost'
|
27
|
+
t.digest
|
28
|
+
end
|
29
|
+
|
30
|
+
dream "a04e699bf8d354c68101ae62bf3e4f32fbae3221"
|
31
|
+
drill "Complex Testplan can gibbler" do
|
32
|
+
u = Stella::Testplan::Usecase.new
|
33
|
+
r = u.add_request :get, '/', 'homepage'
|
34
|
+
r.param :user => :name
|
35
|
+
t = Stella::Testplan.new 'localhost'
|
36
|
+
t.add_usecase u
|
37
|
+
t.digest
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|