stella 0.8.1.002 → 0.8.2.001

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .stella
2
+ tmp
data/.gitmodules ADDED
@@ -0,0 +1,4 @@
1
+ [submodule "vendor/useragent"]
2
+ path = vendor/useragent
3
+ url = git://github.com/delano/useragent.git
4
+
data/CHANGES.txt CHANGED
@@ -3,7 +3,6 @@ STELLA, CHANGES
3
3
  #### 0.8.X (XXXX-XX-XX) ###############################
4
4
 
5
5
  * TODO: Force response block content type.
6
- * TODO: Add assert methods to response blocks (reconsider)
7
6
  * TODO: Add option to dump full request/response output to a file by client
8
7
  * TODO: review cookie handling. Not always sent automatically.
9
8
  * TODO: review :variables in URI elements
@@ -11,6 +10,21 @@ STELLA, CHANGES
11
10
  * TODO: request block conditions.
12
11
  * TODO: process templates for calls to set in get blocks
13
12
 
13
+
14
+ #### 0.8.2 (2010-03-05) ###############################
15
+
16
+ * FIXED: Misc issues with usage via module (Stella::Engine.load)
17
+ * CHANGE: Remove all logs except summary and exceptions
18
+ * CHANGE: Renamed .stella/logs/latest/request-exceptions to .stella/logs/latest/exceptions
19
+ * CHANGE: Removed unused Load implementations and renamed LoadQueue to Load
20
+ * CHANGE: Added proper names for statistics (response_time instead of do_request)
21
+ * CHANGE: Benelux 0.5.8 dependency
22
+ * CHANGE: Cleaned up generate mode CLI output
23
+ * CHANGE: Removed no-logging option
24
+ * CHANGE: Renamed Testrun#summary to Testrun#stats
25
+ * ADDED: JSON statistics log (.stella/logs/latest/stats)
26
+
27
+
14
28
  #### 0.8.1.002 (2010-02-20) ###############################
15
29
 
16
30
  * FIXED: fail on connection error
data/Rakefile CHANGED
@@ -1,46 +1,48 @@
1
+ require "rubygems"
2
+ require "rake"
3
+ require "rake/rdoctask"
4
+ require "rake/clean"
5
+ require 'yaml'
1
6
 
2
- require 'rake/clean'
3
- require 'rake/gempackagetask'
4
- require 'rake/testtask'
5
- require 'rake/runtest'
6
- require 'fileutils'
7
- include FileUtils
8
-
9
- task :default => :test
7
+ config = YAML.load_file("VERSION.yml")
8
+ task :default => ["build"]
9
+ CLEAN.include [ 'pkg', 'doc', 'rdoc', 'coverage*' ]
10
10
 
11
11
  begin
12
- require 'hanna/rdoctask'
12
+ require "jeweler"
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.version = "#{config[:MAJOR]}.#{config[:MINOR]}.#{config[:PATCH]}.#{config[:BUILD]}"
15
+ gem.name = "stella"
16
+ gem.rubyforge_project = gem.name
17
+ gem.summary = "Blame Stella for breaking your web application!"
18
+ gem.description = "Blame Stella for breaking your web application!"
19
+ gem.email = "delano@solutious.com"
20
+ gem.homepage = "http://blamestella.com/"
21
+ gem.authors = ["Delano Mandelbaum"]
22
+ gem.add_dependency("gibbler", ">= 0.7.4")
23
+ gem.add_dependency("drydock", ">= 0.6.9")
24
+ gem.add_dependency("benelux", ">= 0.5.8")
25
+ gem.add_dependency('sysinfo', '>= 0.7.3')
26
+ gem.add_dependency('storable', '>= 0.6.3')
27
+ gem.add_dependency("nokogiri")
28
+
29
+ #gem.add_development_dependency("rspec", ">= 1.2.9")
30
+ #gem.add_development_dependency("mocha", ">= 0.9.8")
31
+ end
32
+ Jeweler::GemcutterTasks.new
13
33
  rescue LoadError
14
- require 'rake/rdoctask'
15
- end
16
-
17
- # PACKAGE =============================================================
18
-
19
- name = "stella"
20
- load "#{name}.gemspec"
21
-
22
- version = @spec.version
23
-
24
- Rake::GemPackageTask.new(@spec) do |p|
25
- p.need_tar = true if RUBY_PLATFORM !~ /mswin/
26
- end
27
-
28
- task :test do
29
- puts "Success!"
30
- end
31
-
32
- task :release => [ "publish:gem", :clean, "publish:rdoc" ] do
33
- $: << File.join(File.dirname(__FILE__), 'lib')
34
- require "rudy"
35
- abort if Drydock.debug?
34
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
36
35
  end
37
36
 
38
- task :install => [ :rdoc, :package ] do
39
- sh %{sudo gem install pkg/#{name}-#{version}.gem}
40
- end
41
37
 
42
- task :uninstall => [ :clean ] do
43
- sh %{sudo gem uninstall #{name}}
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = "#{config[:MAJOR]}.#{config[:MINOR]}.#{config[:PATCH]}.#{config[:BUILD]}"
40
+ rdoc.rdoc_dir = "rdoc"
41
+ rdoc.title = "stella #{version}"
42
+ rdoc.rdoc_files.include("README*")
43
+ rdoc.rdoc_files.include("LICENSE.txt")
44
+ rdoc.rdoc_files.include("bin/*.rb")
45
+ rdoc.rdoc_files.include("lib/**/*.rb")
44
46
  end
45
47
 
46
48
 
@@ -60,20 +62,5 @@ task 'publish:gem' => [:package] do |t|
60
62
  end
61
63
 
62
64
 
63
- Rake::RDocTask.new do |t|
64
- t.rdoc_dir = 'doc'
65
- t.title = @spec.summary
66
- t.options << '--line-numbers' << '-A cattr_accessor=object'
67
- t.options << '--charset' << 'utf-8'
68
- t.rdoc_files.include('LICENSE.txt')
69
- t.rdoc_files.include('README.md')
70
- t.rdoc_files.include('CHANGES.txt')
71
- #t.rdoc_files.include('Rudyfile') # why is the formatting f'd?
72
- t.rdoc_files.include('bin/*')
73
- t.rdoc_files.include('lib/**/*.rb')
74
- end
75
-
76
- CLEAN.include [ 'pkg', '*.gem', '.config', 'doc', 'coverage*' ]
77
-
78
65
 
79
66
 
data/VERSION.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ :MAJOR: 0
3
+ :MINOR: 8
4
+ :PATCH: 2
5
+ :BUILD: '001'
data/bin/stella CHANGED
@@ -46,7 +46,6 @@ class Stella::CLI::Definition
46
46
  global :'with-header', "Include X-Stella-ID request header"
47
47
  global :'with-param', "Include __stella query parameter header"
48
48
  global :R, :remote
49
- global :E, :engine, String, "Specify a load engine (experimental)"
50
49
  global :o, :output, String, "Write output to the given file" do |v|
51
50
  String.disable_color
52
51
  Stella.log.output = v
@@ -65,9 +64,6 @@ class Stella::CLI::Definition
65
64
  global :'no-stats', "Disable stat collection" do
66
65
  true
67
66
  end
68
- global :'no-logging', "Disable all logging" do
69
- Stella::Logger.disable!
70
- end
71
67
  global :'no-templates', "Disable template parsing" do
72
68
  true
73
69
  end
data/lib/stella.rb CHANGED
@@ -19,19 +19,21 @@ require 'proc_source'
19
19
 
20
20
  module Stella
21
21
  module VERSION
22
- unless defined?(MAJOR)
23
- MAJOR = 0.freeze
24
- MINOR = 8.freeze
25
- TINY = 1.freeze
26
- PATCH = '002'.freeze
22
+ def self.to_s
23
+ load_config
24
+ [@version[:MAJOR], @version[:MINOR], @version[:PATCH]].join('.')
25
+ end
26
+ def self.inspect
27
+ load_config
28
+ [@version[:MAJOR], @version[:MINOR], @version[:PATCH], @version[:BUILD]].join('.')
29
+ end
30
+ def self.load_config
31
+ require 'yaml'
32
+ @version ||= YAML.load_file(File.join(STELLA_LIB_HOME, '..', 'VERSION.yml'))
27
33
  end
28
- def self.to_s; [MAJOR, MINOR, TINY].join('.'); end
29
- def self.to_f; self.to_s.to_f; end
30
- def self.patch; PATCH; end
31
34
  end
32
35
  end
33
36
 
34
-
35
37
  module Stella
36
38
  class Error < RuntimeError
37
39
  def initialize(obj=nil); @obj = obj; end
@@ -79,7 +81,7 @@ module Stella
79
81
  attr_accessor :log, :stdout
80
82
  end
81
83
 
82
- def le(*msg); stdout.info " " << msg.join("#{$/} ").color(:red); end
84
+ def le(*msg); stdout.info " " << msg.join("#{$/} ").colour(:red); end
83
85
  def ld(*msg)
84
86
  return unless Stella.debug?
85
87
  prefix = "D(#{Thread.current.object_id}): "
@@ -99,8 +101,8 @@ module Stella
99
101
  def abort!() @abort = true end
100
102
 
101
103
  def quiet?() @quiet == true end
102
- def enable_quiet() @quiet = true end
103
- def disable_quiet() @quiet = false end
104
+ def enable_quiet() @quiet = true; @stdout.disable!; end
105
+ def disable_quiet() @quiet = false; @stdout.enable!; end
104
106
 
105
107
  def add_global(n,v)
106
108
  Stella.ld "SETGLOBAL: #{n}=#{v}"
@@ -120,6 +122,7 @@ module Stella
120
122
  autoload :Config, 'stella/config'
121
123
  autoload :Data, 'stella/data'
122
124
  autoload :Testplan, 'stella/testplan'
125
+ autoload :Testrun, 'stella/engine'
123
126
  autoload :Engine, 'stella/engine'
124
127
  autoload :Client, 'stella/client'
125
128
  autoload :Service, 'stella/service'
data/lib/stella/cli.rb CHANGED
@@ -47,16 +47,8 @@ class Stella::CLI < Drydock::Command
47
47
 
48
48
  connect_service if @global.remote
49
49
 
50
- case @global.engine
51
- when "package"
52
- ret = Stella::Engine::LoadPackage.run @testplan, opts
53
- when "create"
54
- ret = Stella::Engine::LoadCreate.run @testplan, opts
55
- when "em"
56
- ret = Stella::Engine::LoadEventMachine.run @testplan, opts
57
- else
58
- ret = Stella::Engine::LoadQueue.run @testplan, opts
59
- end
50
+ ret = Stella::Engine::Load.run @testplan, opts
51
+
60
52
  Stella.ld "ENGINE: #{@global.engine}: #{ret.class}"
61
53
 
62
54
  @exit_code = (ret ? 0 : 1)
@@ -122,11 +114,10 @@ class Stella::CLI < Drydock::Command
122
114
  else
123
115
  opts = {}
124
116
  opts[:wait] = @option.wait if @option.wait
125
- @testplan = Stella::Testplan.new(@argv, opts)
117
+ @testplan = Stella::Testplan.new(@argv)
126
118
  end
127
119
  @testplan.check! # raise errors, update usecase ratios
128
120
  @testplan.freeze # cascades through usecases and requests
129
- Stella.stdout.info2 " #{@option.testplan || @testplan.desc} (#{@testplan.digest})"
130
121
  true
131
122
  end
132
123
 
data/lib/stella/client.rb CHANGED
@@ -100,7 +100,6 @@ module Stella
100
100
  ret, asset_duration = nil, 0
101
101
  rescue => ex
102
102
  update(:request_unhandled_exception, usecase, uri, req, params, ex)
103
- update(:usecase_error, ex.message, uri, container)
104
103
  Benelux.remove_thread_tags :status, :retry, :request, :stella_id
105
104
  break
106
105
  end
data/lib/stella/common.rb CHANGED
@@ -7,6 +7,22 @@ $KCODE = "u" if RUBY_VERSION =~ /^1.8/
7
7
 
8
8
  class String
9
9
 
10
+ def colour(*args)
11
+ self
12
+ end
13
+
14
+ def color(*args)
15
+ self
16
+ end
17
+
18
+ def att(*args)
19
+ self
20
+ end
21
+
22
+ def bright(*args)
23
+ self
24
+ end
25
+
10
26
  def in_seconds
11
27
  # "60m" => ["60", "m"]
12
28
  q,u = self.scan(/([\d\.]+)([s,m,h])?/).flatten
data/lib/stella/engine.rb CHANGED
@@ -58,6 +58,9 @@ module Stella::Engine
58
58
  end
59
59
 
60
60
  def process_options!(plan, opts={})
61
+ # Plan must be frozen before running (see freeze methods)
62
+ plan.frozen? || plan.freeze
63
+
61
64
  opts = {
62
65
  :hosts => [],
63
66
  :clients => 1,
@@ -67,7 +70,19 @@ module Stella::Engine
67
70
  :repetitions => 1
68
71
  }.merge! opts
69
72
 
70
- Stella.stdout.info2 " Options: #{opts.inspect}"
73
+ Stella.ld " Options: #{opts.inspect}"
74
+
75
+ unless Array === opts[:hosts]
76
+ opts[:hosts] = [opts[:hosts]]
77
+ end
78
+
79
+ opts[:hosts].collect! do |host|
80
+ if URI::Generic === host
81
+ host
82
+ else
83
+ URI.parse host
84
+ end
85
+ end
71
86
 
72
87
  opts[:clients] = plan.usecases.size if opts[:clients] < plan.usecases.size
73
88
 
@@ -104,22 +119,18 @@ module Stella::Engine
104
119
  end
105
120
 
106
121
  autoload :Functional, 'stella/engine/functional'
107
- autoload :Load, 'stella/engine/loadbase'
108
- autoload :LoadPackage, 'stella/engine/load_package'
109
- autoload :LoadCreate, 'stella/engine/load_create'
110
- autoload :LoadQueue, 'stella/engine/load_queue'
111
- autoload :LoadEventMachine, 'stella/engine/load_em'
122
+ autoload :Load, 'stella/engine/load'
112
123
 
113
124
  # These timers are interesting from a reporting perspective.
114
125
  Benelux.add_counter Stella::Client, :execute_response_handler
115
- Benelux.add_timer HTTPClient, :do_request
126
+ Benelux.add_timer HTTPClient, :do_request, :response_time
116
127
  ## These are contained in connect
117
128
  #Benelux.add_timer HTTPClient::Session, :create_socket
118
129
  #Benelux.add_timer HTTPClient::Session, :create_ssl_socket
119
- Benelux.add_timer HTTPClient::Session, :connect
120
- Benelux.add_timer HTTPClient::Session, :query
121
- Benelux.add_timer HTTPClient::Session, :socket_gets_first_byte
122
- Benelux.add_timer HTTPClient::Session, :get_body
130
+ Benelux.add_timer HTTPClient::Session, :connect, :socket_connect
131
+ Benelux.add_timer HTTPClient::Session, :query, :send_request
132
+ Benelux.add_timer HTTPClient::Session, :socket_gets_first_byte, :first_byte
133
+ Benelux.add_timer HTTPClient::Session, :get_body, :receive_response
123
134
 
124
135
  end
125
136
 
@@ -128,7 +139,7 @@ class Stella::Testrun < Storable
128
139
  attic :remote_digest
129
140
  field :samples => Array
130
141
  field :plan
131
- field :summary
142
+ field :stats
132
143
  field :hosts
133
144
  field :events
134
145
  field :mode # (f)unctional or (l)oad
@@ -139,24 +150,28 @@ class Stella::Testrun < Storable
139
150
  field :nowait => Integer
140
151
  def initialize(plan, events, opts={})
141
152
  @plan, @events = plan, events
142
- @samples, @summary = nil, nil
153
+ @samples, @stats = nil, nil
143
154
  opts.each_pair do |n,v|
144
155
  self.send("#{n}=", v) if has_field? n
145
156
  end
146
157
  reset
147
158
  end
148
159
 
160
+ def save(path)
161
+ Stella::Utils.write_to_file(path, self.to_json, 'w', 0644)
162
+ end
163
+
149
164
  def reset
150
165
  @samples = []
151
- @summary = { :summary => {} }
166
+ @stats = { :summary => {} }
152
167
  @plan.usecases.each do |uc|
153
168
  @events.each do |event|
154
- @summary[:summary][event] = Benelux::Stats::Calculator.new
155
- @summary[uc.digest] ||= { :summary => {} }
156
- @summary[uc.digest][:summary][event] = Benelux::Stats::Calculator.new
169
+ @stats[:summary][event] = Benelux::Stats::Calculator.new
170
+ @stats[uc.digest] ||= { :summary => {} }
171
+ @stats[uc.digest][:summary][event] = Benelux::Stats::Calculator.new
157
172
  uc.requests.each do |req|
158
- @summary[uc.digest][req.digest] ||= {}
159
- @summary[uc.digest][req.digest][event] = Benelux::Stats::Calculator.new
173
+ @stats[uc.digest][req.digest] ||= {}
174
+ @stats[uc.digest][req.digest][event] = Benelux::Stats::Calculator.new
160
175
  end
161
176
  end
162
177
  end
@@ -182,9 +197,9 @@ class Stella::Testrun < Storable
182
197
  stats = tl.stats.group(event)[filter].merge
183
198
  sam.stats[uc.digest][req.digest][event] = stats
184
199
  # Tally request, usecase and total summaries at the same time.
185
- @summary[uc.digest][req.digest][event] += stats
186
- @summary[uc.digest][:summary][event] += stats
187
- @summary[:summary][event] += stats
200
+ @stats[uc.digest][req.digest][event] += stats
201
+ @stats[uc.digest][:summary][event] += stats
202
+ @stats[:summary][event] += stats
188
203
  end
189
204
  end
190
205
  end
@@ -193,13 +208,14 @@ class Stella::Testrun < Storable
193
208
 
194
209
  begin
195
210
  if Stella::Engine.service
196
- Stella::Engine.service.testrun_stats @summary, @samples
211
+ Stella::Engine.service.testrun_stats @stats, @samples
197
212
  end
198
213
  rescue => ex
199
214
  Stella.stdout.info "Error syncing to #{Stella::Engine.service.source}"
200
215
  Stella.stdout.info ex.message, ex.backtrace if Stella.debug?
201
216
  end
202
217
 
218
+ sam
203
219
  end
204
220
 
205
221
 
@@ -7,7 +7,6 @@ module Stella::Engine
7
7
  def run(plan, opts={})
8
8
  opts = process_options! plan, opts
9
9
 
10
- Stella.ld "OPTIONS: #{opts.inspect}"
11
10
  Stella.stdout.info2 "Hosts: " << opts[:hosts].join(', ') if !opts[:hosts].empty?
12
11
 
13
12
  client = Stella::Client.new opts[:hosts].first, 1, opts
@@ -15,7 +14,7 @@ module Stella::Engine
15
14
 
16
15
  client.enable_nowait_mode if opts[:nowait]
17
16
 
18
- @testrun = Stella::Testrun.new plan, [:do_request, :failed], opts
17
+ @testrun = Stella::Testrun.new plan, [:response_time, :failed], opts
19
18
  @testrun.mode = 'f'
20
19
 
21
20
  if Stella::Engine.service
@@ -60,7 +59,7 @@ module Stella::Engine
60
59
  @testrun.add_sample 1, 1, tt
61
60
  end
62
61
 
63
- @testrun.summary[:summary][:failed].n == 0
62
+ @testrun.stats[:summary][:failed].n == 0
64
63
  end
65
64
 
66
65