solutious-stella 0.6.0 → 0.7.0.001

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGES.txt +3 -15
  2. data/LICENSE.txt +1 -1
  3. data/README.rdoc +90 -60
  4. data/Rakefile +32 -42
  5. data/bin/stella +138 -0
  6. data/examples/basic/listing_ids.csv +7 -0
  7. data/examples/basic/plan.rb +71 -0
  8. data/lib/stella.rb +57 -104
  9. data/lib/stella/cli.rb +66 -0
  10. data/lib/stella/client.rb +197 -0
  11. data/lib/stella/config.rb +87 -0
  12. data/lib/stella/data.rb +85 -0
  13. data/lib/stella/data/http.rb +2 -257
  14. data/lib/stella/data/http/body.rb +15 -0
  15. data/lib/stella/data/http/request.rb +116 -0
  16. data/lib/stella/data/http/response.rb +92 -0
  17. data/lib/stella/dsl.rb +5 -0
  18. data/lib/stella/engine.rb +55 -0
  19. data/lib/stella/engine/functional.rb +39 -0
  20. data/lib/stella/engine/load.rb +106 -0
  21. data/lib/stella/exceptions.rb +15 -0
  22. data/lib/stella/guidelines.rb +18 -0
  23. data/lib/stella/mixins.rb +2 -0
  24. data/lib/stella/stats.rb +3 -7
  25. data/lib/stella/testplan.rb +95 -220
  26. data/lib/stella/testplan/stats.rb +26 -0
  27. data/lib/stella/testplan/usecase.rb +67 -0
  28. data/lib/stella/utils.rb +126 -0
  29. data/lib/{util → stella/utils}/httputil.rb +0 -0
  30. data/lib/stella/version.rb +15 -0
  31. data/lib/threadify.rb +0 -6
  32. data/stella.gemspec +43 -49
  33. data/support/example_webapp.rb +246 -0
  34. data/support/useragents.txt +75 -0
  35. metadata +66 -31
  36. data/bin/example_test.rb +0 -82
  37. data/bin/example_webapp.rb +0 -63
  38. data/lib/logger.rb +0 -79
  39. data/lib/stella/clients.rb +0 -161
  40. data/lib/stella/command/base.rb +0 -20
  41. data/lib/stella/command/form.rb +0 -36
  42. data/lib/stella/command/get.rb +0 -44
  43. data/lib/stella/common.rb +0 -53
  44. data/lib/stella/crypto.rb +0 -88
  45. data/lib/stella/data/domain.rb +0 -82
  46. data/lib/stella/environment.rb +0 -66
  47. data/lib/stella/functest.rb +0 -105
  48. data/lib/stella/loadtest.rb +0 -186
  49. data/lib/stella/testrunner.rb +0 -64
  50. data/lib/storable.rb +0 -280
  51. data/lib/timeunits.rb +0 -65
  52. data/tryouts/drb/drb_test.rb +0 -65
  53. data/tryouts/drb/open4.rb +0 -19
  54. data/tryouts/drb/slave.rb +0 -27
  55. data/tryouts/oo_tryout.rb +0 -30
@@ -1,21 +1,9 @@
1
1
  STELLA, CHANGES
2
2
 
3
- #### TODO
4
-
5
- * TODO: prepend instance variables with "stella_"
6
- * TODO: implement session handling
7
- * BUG: http://jira.codehaus.org/browse/JRUBY-2992
8
- * TODO: variable interpolation that happens at test time so instance variables can be grabbed from the calling space.
9
- #
10
- # get "/product/${token}" do
11
- # ## TODO: Override environment settings.
12
- # #protocol :https
13
- # response 200 do |headers, body|
14
- # data = YAML.load(body)
15
- # puts "ID: #{data[:id]}"
16
- # end
17
- # end
18
3
 
4
+ #### 0.7.0 (2009-09-05) ###############################
5
+
6
+ NOTE: Complete rewrite
19
7
 
20
8
 
21
9
  #### 0.6.0 (2009-03-15) ###############################
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Delano Mandelbaum
1
+ Copyright (c) 2009 Solutious Inc, Delano Mandelbaum
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -1,64 +1,91 @@
1
- = Stella - 0.6.0 ALPHA
2
-
3
- Stella is a Ruby library for writing functional tests in a sexy DSL (domain specific language).
4
-
5
- ==== NOTE: The 0.6 release was a complete rewrite from previous versions. All commands, APIs, and documentation have changed!*
6
-
7
- == Example 1
8
-
9
- testplan :maintain_value do
10
- desc "Maintain a value between requests"
11
- auth :basic, "stella", "stella"
12
- protocol :http
13
-
14
- post "/upload" do
15
- name "Add Product"
16
- body "bill", "/path/2/file.txt"
17
- header "X-Stella" => "Version #{Stella::VERSION}"
18
- param :convert => true
19
- param :rand => rand
20
-
21
- response 200, 201 do |headers, body, objid|
22
- data = YAML.load(body)
23
- @product_id = data[:id] # Save a response value
24
- end
25
- end
26
-
27
- get "/product" do
28
- name "View Product"
29
- param 'id' => @product_id # Use the saved value
30
-
31
- response 200 do |header, body, objid|
32
- data = YAML.load(body)
33
- repeat :times => 2, :wait => 1.second # Repeat this request twice
34
- end
35
- end
36
- end
37
-
38
- functest :quick_test do
39
- plan :product_api
40
- clients 2
41
- duration 5.minutes
42
- verbose
43
- end
44
-
45
- environment :development do
46
- machines "localhost:3114"
47
- # machine "localhost:3115"
48
- # ...
49
- end
50
-
51
- run :development, :quick_test
52
-
53
-
54
- See bin/example_test.rb for a running example.
55
-
56
-
1
+ = Stella - 0.7 PREVIEW
2
+
3
+ Perform load tests on your web applications with beauty and brute strength.
4
+
5
+ <i>NOTE: 0.7 release is not compatible with previous releases!</i>
6
+
7
+ == Features
8
+
9
+ * Realistic load simulation
10
+ * Sophisticated response handling (with automatic HTML document parsing)
11
+ * Dynamic variable replacement
12
+
13
+ == PREVIEW NOTICE
14
+
15
+ This is an early preview of Stella. It's still missing the following features (as of 2009-09-15):
16
+
17
+ * Reporting of any kind.
18
+ * Documentation.
19
+ * File uploads.
20
+
21
+ == Usage Example
22
+
23
+ # Verify a test plan is defined correctly
24
+ # by running a single user functional test.
25
+ $ stella verify -p examples/basic/plan.rb http://stellaaahhhh.com/
26
+
27
+ # Perform a load test
28
+ # using the same test plan.
29
+ $ stella load -p examples/basic/plan.rb http://stellaaahhhh.com/
30
+
31
+ # Preview a test plan
32
+ $ stella preview -p examples/basic/plan.rb
33
+
34
+
35
+ == Test Plan Example
36
+
37
+ Test plans are defined in the Ruby programming language. This makes it possible to define sophisticated logic to handle responses. They also typically contain more than one usecase which is important when simulating realistic load. In this example, 65% of virtual users will execute the first usecase and 35% will execute the second.
38
+
39
+ usecase 65, "Simple search" do
40
+
41
+ get "/", "Homepage" do
42
+ wait 1..5
43
+ response 200 do
44
+ status # => 200
45
+ headers['Content-Type'] # => ['text/html']
46
+ body # => <html>...
47
+ doc # => Nokigiri::HTML::Document
48
+ end
49
+ end
50
+
51
+ get "/search", "Search Results" do
52
+ wait 2..5
53
+ param :what => 'Big Al'
54
+ param :where => 'Toronto'
55
+ response 200 do
56
+ listing = doc.css('div.listing').first
57
+ set :lid, listing['id'].match(/(\d+)/)[0]
58
+ end
59
+ end
60
+
61
+ get "/listing/:lid" do # URIs can contain variables.
62
+ desc "Selected listing" # This one will be replaced by
63
+ wait 1..8 # the one stored in the previous
64
+ end # request.
65
+
66
+ end
67
+
68
+ usecase 35, "YAML API" do
69
+
70
+ resource :listing_ids, list('ids.csv')
71
+
72
+ get "/listing/:lid.yaml" do
73
+ desc "Select listing"
74
+ param :lid => random(:listing_ids)
75
+ response 200 do
76
+ repeat 5
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ See examples/ for more.
83
+
84
+
57
85
  == Installation
58
86
 
59
87
  Get it in one of the following ways:
60
88
 
61
- * RubyForge: http://stella.rubyforge.org/
62
89
  * gem install stella
63
90
  * git clone git://github.com/solutious/stella.git
64
91
  * gem install solutious-stella --source http://gems.github.com
@@ -66,13 +93,16 @@ Get it in one of the following ways:
66
93
 
67
94
  == More Information
68
95
 
69
- Stellaaahhhh[http://www.youtube.com/watch?v=wmq-JDonTpc]
96
+ * Homepage[http://solutious.com/projects/stella]
97
+ * Codes[http://github.com/solutious/stella]
98
+ * RDocs[http://solutious.com/stella]
99
+ * Stellaaahhhh[http://www.youtube.com/watch?v=jHHprvyl-Hc]
70
100
 
71
101
 
72
102
  == Credits
73
103
 
74
- * Delano Mandelbaum (delano@solutious.com)
75
-
104
+ * Delano Mandelbaum (http://solutious.com)
105
+ * Threadify (C) Ara T Howard (http://codeforpeople.com/)
76
106
 
77
107
  == Thanks
78
108
 
data/Rakefile CHANGED
@@ -1,83 +1,73 @@
1
- require 'rubygems'
1
+
2
2
  require 'rake/clean'
3
3
  require 'rake/gempackagetask'
4
4
  require 'hanna/rdoctask'
5
+ require 'rake/testtask'
6
+ require 'shoulda/tasks'
7
+ require 'rake/runtest'
8
+ require 'monkeyspecdoc' # http://jgre.org/2008/09/03/monkeyspecdoc/
5
9
  require 'fileutils'
6
10
  include FileUtils
7
11
 
8
- task :default => :package
9
-
10
- # CONFIG =============================================================
12
+ task :default => :test
11
13
 
12
- # Change the following according to your needs
13
- README = "README.rdoc"
14
- CHANGES = "CHANGES.txt"
15
- LICENSE = "LICENSE.txt"
16
14
 
17
- # Files and directories to be deleted when you run "rake clean"
18
- CLEAN.include [ 'pkg', '*.gem', '.config', 'doc']
15
+ # PACKAGE =============================================================
19
16
 
20
- # Virginia assumes your project and gemspec have the same name
21
- name = (Dir.glob('*.gemspec') || ['stella']).first.split('.').first
17
+ name = "stella"
22
18
  load "#{name}.gemspec"
23
- version = @spec.version
24
-
25
- # That's it! The following defaults should allow you to get started
26
- # on other things.
27
-
28
-
29
- # TESTS/SPECS =========================================================
30
-
31
-
32
19
 
33
- # INSTALL =============================================================
20
+ version = @spec.version
34
21
 
35
22
  Rake::GemPackageTask.new(@spec) do |p|
36
23
  p.need_tar = true if RUBY_PLATFORM !~ /mswin/
37
24
  end
38
25
 
39
- task :release => [ :rdoc, :package ]
26
+ task :release => [ "publish:gem", :clean, "publish:rdoc" ] do
27
+ $: << File.join(File.dirname(__FILE__), 'lib')
28
+ require "rudy"
29
+ abort if Drydock.debug?
30
+ end
31
+
40
32
  task :install => [ :rdoc, :package ] do
41
33
  sh %{sudo gem install pkg/#{name}-#{version}.gem}
42
34
  end
35
+
43
36
  task :uninstall => [ :clean ] do
44
37
  sh %{sudo gem uninstall #{name}}
45
38
  end
46
39
 
47
40
 
48
- # RUBYFORGE RELEASE / PUBLISH TASKS ==================================
41
+ # Rubyforge Release / Publish Tasks ==================================
49
42
 
50
- if @spec.rubyforge_project
51
- desc 'Publish website to rubyforge'
52
- task 'publish:rdoc' => 'doc/index.html' do
53
- sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
54
- end
43
+ #about 'Publish website to rubyforge'
44
+ task 'publish:rdoc' => 'doc/index.html' do
45
+ sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
46
+ end
55
47
 
56
- desc 'Public release to rubyforge'
57
- task 'publish:gem' => [:package] do |t|
58
- sh <<-end
59
- rubyforge add_release -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
60
- rubyforge add_file -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
61
- end
48
+ #about 'Public release to rubyforge'
49
+ task 'publish:gem' => [:package] do |t|
50
+ sh <<-end
51
+ rubyforge add_release -o Any -a CHANGES.txt -f -n README.rdoc #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
52
+ rubyforge add_file -o Any -a CHANGES.txt -f -n README.rdoc #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
62
53
  end
63
54
  end
64
55
 
65
56
 
66
-
67
- # RUBY DOCS TASK ==================================
68
-
69
57
  Rake::RDocTask.new do |t|
70
58
  t.rdoc_dir = 'doc'
71
59
  t.title = @spec.summary
72
- t.options << '--line-numbers'
60
+ t.options << '--line-numbers' << '-A cattr_accessor=object'
73
61
  t.options << '--charset' << 'utf-8'
74
- t.rdoc_files.include(LICENSE)
75
- t.rdoc_files.include(README)
76
- t.rdoc_files.include(CHANGES)
62
+ t.rdoc_files.include('LICENSE.txt')
63
+ t.rdoc_files.include('README.rdoc')
64
+ t.rdoc_files.include('CHANGES.txt')
65
+ #t.rdoc_files.include('Rudyfile') # why is the formatting f'd?
77
66
  t.rdoc_files.include('bin/*')
78
67
  t.rdoc_files.include('lib/**/*.rb')
79
68
  end
80
69
 
70
+ CLEAN.include [ 'pkg', '*.gem', '.config', 'doc', 'coverage*' ]
81
71
 
82
72
 
83
73
 
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # = Stella
4
+ #
5
+ # === Your friend in web app performance testing
6
+ #
7
+ # Config (default paths):
8
+ #
9
+ # ./.stella/config (current directory)
10
+ # ~/.stella/config (your home directory)
11
+ #
12
+ # Usage:
13
+ #
14
+ # $ stella -h
15
+ # $ stella verify
16
+ # $ stella load -u 10 -t 60 http://test.example.com/
17
+ # $ stella load -u 10 -r 40 -p plans/basic.rb http://test.example.com/
18
+
19
+ STELLA_LIB_HOME = File.expand_path File.join(File.dirname(__FILE__), '..', 'lib')
20
+
21
+ $:.unshift STELLA_LIB_HOME # Put our local lib in first place
22
+
23
+ require 'drydock'
24
+ require 'stella'
25
+ require 'stella/cli'
26
+
27
+ # Command-line interface for bin/stella
28
+ class Stella::CLI::Definition
29
+ extend Drydock
30
+
31
+ debug :off
32
+ default :verify # when no command is provided
33
+
34
+ # ---------------------------------------- STELLA GLOBALS --------
35
+ # ------------------------------------------------------------------
36
+
37
+ global :A, :apikey, String, "API Key"
38
+ global :S, :secret, String, "Secret Key"
39
+ global :q, :quiet, "Be quiet!" do
40
+ Stella.enable_quiet
41
+ end
42
+ global :D, :debug, "Enable debug mode" do
43
+ Drydock.debug true
44
+ Stella.enable_debug
45
+ end
46
+ global :v, :verbose, "Increase verbosity of output (e.g. -v or -vv or -vvv)" do
47
+ Stella.loglev += 1
48
+ end
49
+ global :V, :version, "Display version number" do
50
+ puts "Stella version: #{Stella::VERSION} (#{Stella::VERSION::PATCH})"
51
+ exit 0
52
+ end
53
+
54
+
55
+ # ------------------------------------------------ STELLA --------
56
+ # ------------------------------------------------------------------
57
+
58
+ about "Run a functional test"
59
+ usage "stella verify http://stellaaahhhh.com/"
60
+ usage "stella verify -p path/2/testplan.rb http://stellaaahhhh.com/"
61
+ option :b, :benchmark, "Benchmark mode (ignore wait times)"
62
+ option :p, :testplan, String, "Path to testplan" do |v|
63
+ raise Stella::InvalidOption, "Bad path: #{v}" unless File.exists?(v)
64
+ v
65
+ end
66
+ command :verify => Stella::CLI
67
+
68
+ about "Run a load test"
69
+ usage "stella load http://stellaaahhhh.com/"
70
+ usage "stella load -p path/2/testplan.rb http://stellaaahhhh.com/"
71
+ option :b, :benchmark, "Benchmark mode (ignore wait times)"
72
+ option :u, :users, Integer, "Number of virtual users"
73
+ option :r, :repetitions, Integer, "Number of times to repeat the testplan (per vuser)"
74
+ option :t, :time, String, "Max duration to run test"
75
+ option :d, :delay, Float, "Delay between client requests (s)"
76
+ option :p, :testplan, String, "Path to testplan" do |v|
77
+ raise Stella::InvalidOption, "Bad path: #{v}" unless File.exists?(v)
78
+ v
79
+ end
80
+ command :load => Stella::CLI
81
+
82
+ about "Preview a testplan"
83
+ usage "stella preview -p path/2/testplan.rb http://stellaaahhhh.com/"
84
+ option :p, :testplan, String, "Path to testplan" do |v|
85
+ raise Stella::InvalidOption, "Bad path: #{v}" unless File.exists?(v)
86
+ v
87
+ end
88
+ command :preview => Stella::CLI
89
+
90
+ about "Initialize Stella"
91
+ command :init do
92
+ Stella::Config.init
93
+ end
94
+
95
+ if Drydock.debug?
96
+ about "Blast away all Stella config assets"
97
+ command :blast do
98
+ Stella::Config.blast
99
+ end
100
+ end
101
+
102
+
103
+ # ---------------------------------- STELLA MISCELLANEOUS --------
104
+ # ------------------------------------------------------------------
105
+
106
+ before do |obj|
107
+ @start = Time.now
108
+ Stella.enable_debug if Drydock.debug?
109
+ end
110
+
111
+ after do |obj|
112
+ Drydock::Screen.flush
113
+ @elapsed = Time.now - @start
114
+ if Stella.loglev > 1 && @elapsed > 0.1
115
+ puts
116
+ puts "Elapsed: %.2f seconds" % @elapsed.to_f
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ begin
123
+ Drydock.run!(ARGV, STDIN) if Drydock.run? && !Drydock.has_run?
124
+ rescue Drydock::ArgError, Drydock::OptError => ex
125
+ STDERR.puts ex.message
126
+ STDERR.puts ex.usage
127
+ rescue Drydock::InvalidArgument => ex
128
+ STDERR.puts ex.message
129
+ rescue Stella::Error => ex
130
+ STDERR.puts ex.message
131
+ STDERR.puts ex.backtrace if Drydock.debug?
132
+ rescue Interrupt
133
+ puts "#{$/}Exiting... "
134
+ exit 1
135
+ rescue => ex
136
+ STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}"
137
+ STDERR.puts ex.backtrace if Drydock.debug?
138
+ end