solutious-stella 0.5.5 → 0.6.0

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.
Files changed (83) hide show
  1. data/CHANGES.txt +39 -2
  2. data/LICENSE.txt +19 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +54 -59
  5. data/bin/example_test.rb +82 -0
  6. data/bin/example_webapp.rb +63 -0
  7. data/lib/{stella/logger.rb → logger.rb} +6 -11
  8. data/lib/stella.rb +76 -58
  9. data/lib/stella/clients.rb +161 -0
  10. data/lib/stella/command/base.rb +4 -24
  11. data/lib/stella/command/form.rb +36 -0
  12. data/lib/stella/command/get.rb +44 -0
  13. data/lib/stella/common.rb +53 -0
  14. data/lib/stella/crypto.rb +88 -0
  15. data/lib/stella/data/domain.rb +2 -2
  16. data/lib/stella/data/http.rb +164 -36
  17. data/lib/stella/environment.rb +66 -0
  18. data/lib/stella/functest.rb +105 -0
  19. data/lib/stella/loadtest.rb +186 -0
  20. data/lib/{utils → stella}/stats.rb +16 -20
  21. data/lib/stella/testplan.rb +237 -0
  22. data/lib/stella/testrunner.rb +64 -0
  23. data/lib/storable.rb +280 -0
  24. data/lib/threadify.rb +171 -0
  25. data/lib/timeunits.rb +65 -0
  26. data/lib/util/httputil.rb +266 -0
  27. data/stella.gemspec +69 -0
  28. data/tryouts/drb/drb_test.rb +65 -0
  29. data/tryouts/drb/open4.rb +19 -0
  30. data/tryouts/drb/slave.rb +27 -0
  31. data/tryouts/oo_tryout.rb +30 -0
  32. metadata +39 -107
  33. data/README.textile +0 -162
  34. data/bin/stella +0 -12
  35. data/bin/stella.bat +0 -12
  36. data/lib/daemonize.rb +0 -56
  37. data/lib/pcaplet.rb +0 -180
  38. data/lib/stella/adapter/ab.rb +0 -337
  39. data/lib/stella/adapter/base.rb +0 -106
  40. data/lib/stella/adapter/httperf.rb +0 -305
  41. data/lib/stella/adapter/pcap_watcher.rb +0 -221
  42. data/lib/stella/adapter/proxy_watcher.rb +0 -76
  43. data/lib/stella/adapter/siege.rb +0 -341
  44. data/lib/stella/cli.rb +0 -258
  45. data/lib/stella/cli/agents.rb +0 -73
  46. data/lib/stella/cli/base.rb +0 -55
  47. data/lib/stella/cli/language.rb +0 -18
  48. data/lib/stella/cli/localtest.rb +0 -78
  49. data/lib/stella/cli/sysinfo.rb +0 -16
  50. data/lib/stella/cli/watch.rb +0 -278
  51. data/lib/stella/command/localtest.rb +0 -358
  52. data/lib/stella/response.rb +0 -85
  53. data/lib/stella/storable.rb +0 -201
  54. data/lib/stella/support.rb +0 -276
  55. data/lib/stella/sysinfo.rb +0 -257
  56. data/lib/stella/test/definition.rb +0 -79
  57. data/lib/stella/test/run/summary.rb +0 -70
  58. data/lib/stella/test/stats.rb +0 -114
  59. data/lib/stella/text.rb +0 -64
  60. data/lib/stella/text/resource.rb +0 -38
  61. data/lib/utils/crypto-key.rb +0 -84
  62. data/lib/utils/domainutil.rb +0 -47
  63. data/lib/utils/escape.rb +0 -302
  64. data/lib/utils/fileutil.rb +0 -78
  65. data/lib/utils/httputil.rb +0 -266
  66. data/lib/utils/mathutil.rb +0 -15
  67. data/lib/utils/textgraph.rb +0 -267
  68. data/lib/utils/timerutil.rb +0 -58
  69. data/lib/win32/Console.rb +0 -970
  70. data/lib/win32/Console/ANSI.rb +0 -305
  71. data/support/kvm.h +0 -91
  72. data/support/ruby-pcap-takuma-notes.txt +0 -19
  73. data/support/ruby-pcap-takuma-patch.txt +0 -30
  74. data/support/text/en.yaml +0 -80
  75. data/support/text/nl.yaml +0 -7
  76. data/support/useragents.txt +0 -75
  77. data/tests/01-util_test.rb +0 -0
  78. data/tests/02-stella-util_test.rb +0 -42
  79. data/tests/10-stella_test.rb +0 -104
  80. data/tests/11-stella-storable_test.rb +0 -68
  81. data/tests/60-stella-command_test.rb +0 -248
  82. data/tests/80-stella-cli_test.rb +0 -45
  83. data/tests/spec-helper.rb +0 -31
@@ -0,0 +1,66 @@
1
+ module Stella
2
+ class Environment
3
+
4
+
5
+ end
6
+ end
7
+
8
+ module Stella
9
+ class Environment
10
+
11
+ attr_accessor :name
12
+
13
+ # An array of `Stella::Common::Machine objects to be use during the test.
14
+ # @stella_environments.machines << "stellaaahhhh.com:80"
15
+ attr_accessor :machines
16
+ # The default proxy, a Stella::Common::Proxy object containing the proxy to be used for the test.
17
+ attr_accessor :proxy
18
+
19
+ def initialize(name=:development)
20
+ @name = name
21
+ @machines = []
22
+ end
23
+
24
+
25
+ def add_machines(*args)
26
+ return if args.empty?
27
+ args.each do |machine|
28
+ @machines << Stella::Common::Machine.new(machine)
29
+ end
30
+ end
31
+
32
+ # Creates a Stella::TestPlan::Proxy object and stores it to +@proxy+
33
+ def proxy=(*args)
34
+ uri, user, pass = args.flatten
35
+ @proxy = Stella::Common::Proxy.new(uri, user, pass)
36
+ end
37
+
38
+
39
+ end
40
+ end
41
+
42
+ module Stella
43
+ module DSL
44
+ module Environment
45
+ attr_accessor :stella_current_environment
46
+
47
+ def environments
48
+ @stella_environments
49
+ end
50
+
51
+ def environment(name, &define)
52
+ @stella_environments ||= {}
53
+ @stella_current_environment = @stella_environments[name] = Stella::Environment.new(name)
54
+ define.call if define
55
+ end
56
+
57
+ def machines(*args)
58
+ return unless @stella_current_environment.is_a? Stella::Environment
59
+ args.each do |machine|
60
+ @stella_current_environment.add_machines machine
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,105 @@
1
+
2
+
3
+
4
+ module Stella
5
+ class FunctionalTest
6
+ include TestRunner
7
+
8
+ def type; "functional"; end
9
+
10
+
11
+
12
+ def update_start(machine, name)
13
+ puts '-'*60
14
+ puts "%10s: %s" % ["MACHINE", machine]
15
+ end
16
+
17
+ def update_authorized(domain, user, pass)
18
+ note = user
19
+ note += ":****" if pass
20
+ puts "%10s: %s" % ["user", note]
21
+ puts
22
+ end
23
+
24
+ def update_request(method, uri, query, response_status, response_headers, response_body)
25
+ puts "#{method} #{uri}"
26
+ puts "%18s: %s" % ["status", response_status]
27
+ puts "%18s: %s" % ["query", query] if @verbose > 0 && !query.empty?
28
+ puts "%18s: %s" % ["response_headers", response_headers]
29
+ puts "%18s: #{$/}%s" % ["response_body", response_body[0..100]] if @verbose > 0
30
+ puts
31
+ end
32
+
33
+ def update_request_exception(method, uri, query, ex)
34
+ puts "#{method} #{uri}"
35
+ puts "EXCEPTION: #{ex.message}"
36
+ puts ex.backtrace
37
+ end
38
+
39
+ def update_request_unexpected_response(method, uri, query, response_status, response_headers, response_body)
40
+ puts "#{method} #{uri}"
41
+ puts "%18s: %s" % ["status", response_status]
42
+ puts "%18s: %s" % ["note", "unexpected response status"]
43
+ puts "", response_body[0..500]
44
+ puts '...' if response_body.length >= 500
45
+ end
46
+
47
+ def update_retrying(uri, retry_count, total)
48
+ puts "retrying: #{uri} (#{retry_count} of #{total})"
49
+ end
50
+
51
+
52
+ # +environment+ is a Stella::Common::Environment object.
53
+ # +namespace+ is a reference to the namespace which contains the instance
54
+ # variables. This will be the section of code that makes use of the DSL.
55
+ def run(environment, namespace)
56
+ raise "No testplan defined" unless @testplan
57
+ raise "No machines defined for #{environment.name}" if environment.machines.empty?
58
+
59
+
60
+ begin
61
+ if environment.proxy
62
+ http_client = HTTPClient.new(environment.proxy.uri)
63
+ http_client.set_proxy_auth(environment.proxy.user, environment.proxy.pass) if environment.proxy.user
64
+ else
65
+ http_client = HTTPClient.new
66
+ end
67
+ rescue => ex
68
+ puts ex.class
69
+ end
70
+
71
+ request_stats = {}
72
+ environment.machines.each do |machine|
73
+ client = Stella::Client.new
74
+ client.add_observer(self)
75
+ client.execute_testplan(request_stats, http_client, machine, namespace, @testplan, @verbose)
76
+ end
77
+
78
+
79
+ request_stats.each do |rstat|
80
+ puts rstat[1][:stats].to_s
81
+ end
82
+ end
83
+
84
+
85
+ end
86
+ end
87
+
88
+
89
+
90
+
91
+ module Stella
92
+ module DSL
93
+ module FunctionalTest
94
+ include Stella::DSL::TestRunner
95
+
96
+ def functest(name=:default, &define)
97
+ @tests ||= {}
98
+ @current_test = @tests[name] = Stella::FunctionalTest.new(name)
99
+ define.call if define
100
+ end
101
+
102
+
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,186 @@
1
+ # See, re Threadify on JRuby: http://www.ruby-forum.com/topic/158180
2
+
3
+ #
4
+ #
5
+ module Stella
6
+ class LoadTest
7
+ include TestRunner
8
+
9
+ attr_accessor :clients
10
+ attr_accessor :repetitions
11
+ attr_accessor :duration
12
+
13
+ attr_reader :testplans_started
14
+ attr_reader :testplans_completed
15
+
16
+ attr_reader :requests_successful
17
+ attr_reader :requests_failed
18
+
19
+ def init
20
+ @repetitions = 1
21
+ @clients = 1
22
+ @duration = 0
23
+ reset
24
+ end
25
+
26
+ def reset
27
+ @testplans_started = 0
28
+ @testplans_completed = 0
29
+ @requests_successful = 0
30
+ @requests_failed = 0
31
+ end
32
+
33
+ def type; "load"; end
34
+
35
+ def requests_total
36
+ @requests_successful + @requests_failed
37
+ end
38
+
39
+ def update_start(machine, name)
40
+ @testplans_started += 1
41
+ end
42
+
43
+ def update_done(*args)
44
+ @testplans_completed += 1
45
+ end
46
+
47
+ def update_authorized(domain, user, pass)
48
+ end
49
+
50
+ def update_request(method, uri, query, response_status, response_headers, response_body)
51
+ @requests_successful += 1
52
+ end
53
+
54
+ def update_request_exception(method, uri, query, ex)
55
+ @requests_failed += 1
56
+ puts [method, uri, query, ex.message].join("|")
57
+ end
58
+
59
+ def update_request_unexpected_response(method, uri, query, response_status, response_headers, response_body)
60
+ @requests_failed += 1
61
+ #puts [method, uri, query, response_status, response_headers, response_body].join("|")
62
+ end
63
+
64
+ def update_retrying(uri, retry_count, total)
65
+ #print retry_count
66
+ end
67
+
68
+
69
+ # +environment+ is a Stella::Common::Environment object.
70
+ # +namespace+ is a reference to the namespace which contains the instance
71
+ # variables.
72
+ def run(environment, namespace)
73
+ raise "No testplan defined" unless @testplan
74
+ raise "No machines defined for #{environment.name}" if environment.machines.empty?
75
+
76
+ [:duration, :clients, :repetitions].each do |p|
77
+ val = instance_variable_get("@#{p}")
78
+ puts " %11s: %s" % [p, val] if val
79
+ end
80
+
81
+ stats = Stats.new("LoadTest")
82
+ request_stats = {}
83
+
84
+ time_started = Time.now
85
+ seconds_elapsed = 0
86
+ (1..@clients).to_a.threadify do |i|
87
+
88
+ (0..@repetitions).to_a.each do |rep|
89
+
90
+ if environment.proxy
91
+ http_client = HTTPClient.new(environment.proxy.uri)
92
+ http_client.set_proxy_auth(environment.proxy.user, environment.proxy.pass) if environment.proxy.user
93
+ else
94
+ http_client = HTTPClient.new
95
+ end
96
+
97
+
98
+ environment.machines.each do |machine|
99
+ client = Stella::Client.new(i)
100
+ client.add_observer(self)
101
+ client.execute_testplan(request_stats, http_client, machine, namespace, @testplan, @verbose)
102
+ end
103
+
104
+ seconds_elapsed = Time.now - time_started
105
+
106
+ #request_stats.each do |rstat|
107
+ # puts rstat[1][:stats].to_s
108
+ #end
109
+
110
+ # If a duration was given, we make sure to run for that
111
+ # amount of time.
112
+ if @duration > 0
113
+ redo if seconds_elapsed <= @duration
114
+ break if seconds_elapsed >= @duration
115
+ end
116
+ end
117
+ end
118
+
119
+ stats.tick
120
+ puts "DONE! (#{seconds_elapsed.minutes} minutes)"
121
+ instance_variables.each do |name|
122
+ #next unless name =~ /request/
123
+ puts "%20s: %s" % [name, instance_variable_get(name)]
124
+ end
125
+
126
+ puts "Final Status"
127
+ puts stats.to_s
128
+ puts
129
+
130
+ request_stats.each do |rstat|
131
+ puts rstat[1][:stats].to_s
132
+ end
133
+ end
134
+
135
+
136
+ def clients=(*args)
137
+ count = args.flatten.first
138
+ @clients = count
139
+ end
140
+
141
+ def repetitions=(*args)
142
+ @repetitions = args.flatten.first
143
+ end
144
+
145
+ def duration=(*args)
146
+ @duration = args.flatten.first
147
+ end
148
+ end
149
+ end
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+ module Stella
158
+ module DSL
159
+ module LoadTest
160
+ include Stella::DSL::TestRunner
161
+
162
+ def loadtest(name=:default, &define)
163
+ @tests ||= {}
164
+ @current_test = @tests[name] = Stella::LoadTest.new(name)
165
+ define.call if define
166
+ end
167
+
168
+ def rampup(*args)
169
+ end
170
+
171
+ def warmup(*args)
172
+ end
173
+
174
+ [:repetitions, :duration, :clients].each do |method_name|
175
+ eval <<-RUBY, binding, '(Stella::DSL::LoadTest)', 1
176
+ def #{method_name}(*val)
177
+ return unless @current_test.is_a? Stella::LoadTest
178
+ @current_test.#{method_name}=(val)
179
+ end
180
+ private :#{method_name}
181
+ RUBY
182
+ end
183
+
184
+ end
185
+ end
186
+ end
@@ -1,26 +1,20 @@
1
- # Copyright (c) 2005 Zed A. Shaw
2
- # You can redistribute it and/or modify it under the same terms as Ruby.
3
- #
4
- # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
- # for more information.
6
1
 
7
- # A very simple little class for doing some basic fast statistics sampling.
8
- # You feed it either samples of numeric data you want measured or you call
9
- # Stats.tick to get it to add a time delta between the last time you called it.
10
- # When you're done either call sum, sumsq, n, min, max, mean or sd to get
11
- # the information. The other option is to just call dump and see everything.
12
- #
13
- # It does all of this very fast and doesn't take up any memory since the samples
14
- # are not stored but instead all the values are calculated on the fly.
15
2
 
16
- class Stats
3
+ module Stella
4
+ # Based on Mongrel::Stats, Copyright (c) 2005 Zed A. Shaw
5
+ class Stats
6
+
17
7
  attr_reader :sum, :sumsq, :n, :min, :max
18
8
 
19
- def initialize(name=:unknown)
9
+ def initialize(name)
20
10
  @name = name
21
11
  reset
22
12
  end
23
-
13
+
14
+ def +(obj)
15
+ puts obj.class
16
+ end
17
+
24
18
  # Resets the internal counters so you can start sampling again.
25
19
  def reset
26
20
  @sum = 0.0
@@ -41,7 +35,7 @@ class Stats
41
35
  @min = s if @min > s
42
36
  @max = s if @max < s
43
37
  end
44
- (@n+=1).to_f
38
+ @n+=1
45
39
  end
46
40
 
47
41
  # Dump this Stats object with an optional additional message.
@@ -50,7 +44,7 @@ class Stats
50
44
  end
51
45
 
52
46
  # Returns a common display (used by dump)
53
- def to_s
47
+ def to_s
54
48
  "[#{@name}]: SUM=%0.4f, SUMSQ=%0.4f, N=%0.4f, MEAN=%0.4f, SD=%0.4f, MIN=%0.4f, MAX=%0.4f" % [@sum, @sumsq, @n, mean, sd, @min, @max]
55
49
  end
56
50
 
@@ -62,9 +56,10 @@ class Stats
62
56
 
63
57
  # Calculates the standard deviation of the data so far.
64
58
  def sd
59
+ return 0.0 if @n <= 1
65
60
  # (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).n)) / ((s).n-1) ))
66
61
  begin
67
- return Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) ).to_f
62
+ return Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) )
68
63
  rescue Errno::EDOM
69
64
  return 0.0
70
65
  end
@@ -73,7 +68,7 @@ class Stats
73
68
 
74
69
  # Adds a time delta between now and the last time you called this. This
75
70
  # will give you the average time between two activities.
76
- #
71
+ #
77
72
  # An example is:
78
73
  #
79
74
  # t = Stats.new("do_stuff")
@@ -86,3 +81,4 @@ class Stats
86
81
  @last_time = now
87
82
  end
88
83
  end
84
+ end
@@ -0,0 +1,237 @@
1
+
2
+ module Stella
3
+ class TestPlan
4
+ class ResponseHandler
5
+ attr_accessor :action
6
+ attr_accessor :times
7
+ attr_accessor :wait
8
+ def initialize(action, times=1, wait=1)
9
+ @action = action
10
+ @times = times
11
+ @wait = wait
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ module Stella
18
+
19
+ class TestPlan
20
+ # The name of the testplan.
21
+ attr_accessor :name
22
+ # A brief description of this testplan
23
+ attr_accessor :description
24
+ # Used as the default protocol for the testplan. One of: http, https
25
+ attr_accessor :protocol
26
+ # A Stella::TestPlan::Auth object
27
+ attr_accessor :auth
28
+ # An array of Stella::TestPlan::Request objects representing all "primary" requests
29
+ # for the given test plan (an html page for example). Each primary Request object can have an array of "auxilliary"
30
+ # requests which represent dependencies for that resource (javascript, images, callbacks, etc...).
31
+ attr_accessor :requests
32
+
33
+ def initialize(name=:anonymous)
34
+ @name = name
35
+ @requests = []
36
+ @servers = []
37
+ @protocol = "http"
38
+ end
39
+
40
+
41
+ def description
42
+ @description
43
+ end
44
+ def description=(val)
45
+ val = val.first if val.is_a? Array
46
+ @description = val
47
+ end
48
+
49
+ alias :desc :description
50
+ alias :desc= :description=
51
+
52
+ # Append a Stella::TestPlan::Request object to +requests+.
53
+ def add_request(req)
54
+ raise "That is not an instance of Stella::Data::HTTPRequest" unless req.is_a? Stella::Data::HTTPRequest
55
+ @requests << req
56
+ end
57
+
58
+
59
+ # Creates a Stella::TestPlan::Auth object and stores it to +@auth+
60
+ def auth=(*args)
61
+ type, user, pass = args.flatten
62
+ @auth = Stella::Common::Auth.new(type, user, pass)
63
+ end
64
+
65
+ # A string to be parsed by URI#parsed or a URI object. The host and port are added to +@servers+
66
+ # in the form "host:port". The protocol is stored in +@protocol+. NOTE: The
67
+ # protocol is used as a default for the test and if it's already set, this
68
+ # method will not try to overwrite it.
69
+ def base_uri=(*args)
70
+ uri_str = args.flatten.first
71
+ begin
72
+ uri = URI.parse uri_str
73
+ host_str = uri.host
74
+ host_str << ":#{uri.port}" if uri.port
75
+ @servers << host_str
76
+ @protocol = uri.scheme unless @protocol
77
+ rescue => ex
78
+ Stella.fatal(ex)
79
+ end
80
+ end
81
+
82
+
83
+ end
84
+
85
+
86
+ end
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+ module Stella
97
+ module DSL
98
+ module TestPlan
99
+ attr_accessor :current_plan
100
+ attr_accessor :current_request
101
+
102
+ def testplan(name, &define)
103
+ @plans ||= {}
104
+ @current_plan = @plans[name] = Stella::TestPlan.new(name)
105
+ define.call if define
106
+ end
107
+
108
+ def plans
109
+ @plans
110
+ end
111
+
112
+ def repeat(*args)
113
+ raise "Repeat format does not look like a hash" unless args.first.is_a?(Hash)
114
+ response_handler = Stella::TestPlan::ResponseHandler.new(:repeat)
115
+ [:times, :wait].each do |att|
116
+ response_handler.send("#{att}=", args.first[att])
117
+ end
118
+
119
+ response_handler
120
+ end
121
+
122
+ def body(*args)
123
+
124
+ raise "current_plan is not a valid testplan: #{@current_plan}" unless @current_plan.is_a? Stella::TestPlan
125
+
126
+ # NOTE: @current_request must be set in the calling namespace
127
+ # before this method is called. See: make_request
128
+ raise "current_request is not a valid request" unless @current_request.is_a? Stella::Data::HTTPRequest
129
+
130
+ param, content_type, content = args if args.size == 3
131
+ param, content = args if args.size == 2
132
+ content = args.first if args.size == 1
133
+
134
+ @current_request.add_body(content, param, content_type)
135
+ end
136
+
137
+ def name(*args)
138
+ raise "current_plan is not a valid testplan: #{@current_plan}" unless @current_plan.is_a? Stella::TestPlan
139
+
140
+ # NOTE: @current_request must be set in the calling namespace
141
+ # before this method is called. See: make_request
142
+ raise "current_request is not a valid request" unless @current_request.is_a? Stella::Data::HTTPRequest
143
+ @current_request.name = args.first
144
+ end
145
+
146
+
147
+ def response(*args, &b)
148
+ raise "current_plan is not a valid testplan" unless @current_plan.is_a? Stella::TestPlan
149
+
150
+ # NOTE: @current_request must be set in the calling namespace
151
+ # before this method is called. See: make_request
152
+ raise "current_request is not a valid request" unless @current_request.is_a? Stella::Data::HTTPRequest
153
+
154
+ @current_request.add_response_handler(*args, &b)
155
+ end
156
+ private :response
157
+
158
+ # Stella::Data::HTTPRequest#add_ methods
159
+ [:header, :param].each do |method_name|
160
+ eval <<-RUBY, binding, '(Stella::DSL::TestPlan)', 1
161
+ def #{method_name}(*args, &b)
162
+ raise "current_plan is not a valid testplan" unless @current_plan.is_a? Stella::TestPlan
163
+
164
+ # NOTE: @current_request must be set in the calling namespace
165
+ # before this method is called. See: make_request
166
+ raise "current_request is not a valid request" unless @current_request.is_a? Stella::Data::HTTPRequest
167
+
168
+ @current_request.add_#{method_name}(*args, &b)
169
+ end
170
+ private :#{method_name}
171
+ RUBY
172
+ end
173
+
174
+ # TestPlan#= methods
175
+ [:proxy, :auth, :base_uri, :desc, :description].each do |method_name|
176
+ eval <<-RUBY, binding, '(Stella::DSL::TestPlan)', 1
177
+ def #{method_name}(*args)
178
+ return unless @current_plan.is_a? Stella::TestPlan
179
+ @current_plan.#{method_name}=(args)
180
+ end
181
+ private :#{method_name}
182
+ RUBY
183
+ end
184
+
185
+ # = methods
186
+ [:protocol].each do |method_name|
187
+ eval <<-RUBY, binding, '(Stella::DSL::TestPlan)', 1
188
+ def #{method_name}(val)
189
+ return unless @current_plan.is_a? Stella::TestPlan
190
+ @current_plan.#{method_name}=(val.to_s)
191
+ end
192
+ private :#{method_name}
193
+ RUBY
194
+ end
195
+
196
+ def post(uri, &define)
197
+ make_request(:POST, uri, &define)
198
+ end
199
+ def xpost(*args); end;
200
+ def xget(*args); end;
201
+
202
+ def get(uri, &define)
203
+ make_request(:GET, uri, &define)
204
+ end
205
+
206
+ private
207
+
208
+ def make_request(method, uri, &define)
209
+ return unless @current_plan.is_a? Stella::TestPlan
210
+ req = Stella::Data::HTTPRequest.new(uri, method.to_s.upcase)
211
+ @current_plan.add_request req
212
+ index = @current_plan.requests.size
213
+ method_name = :"#{index} #{req.http_method} #{req.uri}"
214
+
215
+ req_method = Proc.new {
216
+ # These instance variables are very important. The bring in the context
217
+ # when the request method is called in the testrunner class. We know what
218
+ # the current plan is while we're executing the DSL blocks to define the
219
+ # request. The response block however, is called only after a require request
220
+ # is made. We set these instance variables so that the response block will
221
+ # know what request it's associated too.
222
+ instance_variable_set('@current_plan', @current_plan)
223
+ instance_variable_set('@current_request', req)
224
+ define.call if define
225
+ req
226
+ }
227
+ metaclass.instance_eval do
228
+ define_method(method_name, &req_method)
229
+ end
230
+
231
+ end
232
+
233
+ end
234
+ end
235
+ end
236
+
237
+