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.
@@ -6,10 +6,15 @@ module Stella
6
6
  def message; "#{self.class}: #{@obj}"; end
7
7
  end
8
8
 
9
- class InvalidOption < Stella::Error
9
+ class WackyRatio < Stella::Error
10
10
  end
11
11
 
12
- class NoHostDefined < Stella::Error
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
@@ -1,2 +1,5 @@
1
1
 
2
- Stella::Utils.require_glob(Stella::LIB_HOME, 'stella', 'mixins', '*.rb')
2
+ require 'stella/mixins/time'
3
+ require 'stella/mixins/string'
4
+ require 'stella/mixins/numeric'
5
+ require 'stella/mixins/thread'
@@ -1,19 +1,20 @@
1
1
 
2
2
 
3
3
  class Numeric
4
- # TODO: Use 1024
4
+ include Time::Units
5
+ # TODO: Use 1024?
5
6
  def to_bytes
6
7
  args = case self.abs.to_i
7
- when 0..1_000
8
+ when 0..1000
8
9
  [(self).to_s, 'B']
9
- when 1_000..1_000_000
10
- [(self / 1000).to_s, 'KB']
11
- when 1_000_000..1_000_000_000
12
- [(self / (1000**2)).to_s, 'MB']
13
- when 1_000_000_000..1_000_000_000_000
14
- [(self / (1000**3)).to_s, 'GB']
15
- when 1_000_000_000_000..1_000_000_000_000_000
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,12 @@
1
+ # Assumes Time::Units and Numeric mixins are available.
2
+
3
+ class String
4
+
5
+ def in_seconds
6
+ # "60m" => ["60", "m"]
7
+ q,u = self.scan(/([\d\.]+)([s,m,h])?/).flatten
8
+ q &&= q.to_f and u ||= 's'
9
+ q &&= q.in_seconds(u)
10
+ end
11
+
12
+ 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
+
@@ -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[:delay] if opts[:delay]
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.gibbler_cache : self.gibbler_cache.shorter
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.gibbler_cache : uc.gibbler_cache.shorter
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.gibbler_cache : r.gibbler_cache.shorter
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(@base_path, path) if @base_path
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
@@ -1,8 +1,6 @@
1
1
 
2
- require 'socket'
3
- require 'open-uri'
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(LIB_HOME, '..', 'vendor', "#{name}-#{version}")
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
@@ -6,7 +6,7 @@ module Stella
6
6
  MAJOR = 0.freeze
7
7
  MINOR = 7.freeze
8
8
  TINY = 0.freeze
9
- PATCH = '015'.freeze
9
+ PATCH = '017'.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
@@ -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.015"
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.2'
18
+ s.add_dependency 'benelux', '>= 0.4.3'
19
19
  s.add_dependency 'drydock', '>= 0.6.8'
20
- s.add_dependency 'gibbler', '>= 0.6.3'
20
+ s.add_dependency 'gibbler', '>= 0.7.0'
21
21
  s.add_dependency 'sysinfo', '>= 0.7.0'
22
- s.add_dependency 'storable', '>= 0.5.7'
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.csv
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
+