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.
- data/CHANGES.txt +39 -2
- data/LICENSE.txt +19 -0
- data/README.rdoc +85 -0
- data/Rakefile +54 -59
- data/bin/example_test.rb +82 -0
- data/bin/example_webapp.rb +63 -0
- data/lib/{stella/logger.rb → logger.rb} +6 -11
- data/lib/stella.rb +76 -58
- data/lib/stella/clients.rb +161 -0
- data/lib/stella/command/base.rb +4 -24
- data/lib/stella/command/form.rb +36 -0
- data/lib/stella/command/get.rb +44 -0
- data/lib/stella/common.rb +53 -0
- data/lib/stella/crypto.rb +88 -0
- data/lib/stella/data/domain.rb +2 -2
- data/lib/stella/data/http.rb +164 -36
- data/lib/stella/environment.rb +66 -0
- data/lib/stella/functest.rb +105 -0
- data/lib/stella/loadtest.rb +186 -0
- data/lib/{utils → stella}/stats.rb +16 -20
- data/lib/stella/testplan.rb +237 -0
- data/lib/stella/testrunner.rb +64 -0
- data/lib/storable.rb +280 -0
- data/lib/threadify.rb +171 -0
- data/lib/timeunits.rb +65 -0
- data/lib/util/httputil.rb +266 -0
- data/stella.gemspec +69 -0
- data/tryouts/drb/drb_test.rb +65 -0
- data/tryouts/drb/open4.rb +19 -0
- data/tryouts/drb/slave.rb +27 -0
- data/tryouts/oo_tryout.rb +30 -0
- metadata +39 -107
- data/README.textile +0 -162
- data/bin/stella +0 -12
- data/bin/stella.bat +0 -12
- data/lib/daemonize.rb +0 -56
- data/lib/pcaplet.rb +0 -180
- data/lib/stella/adapter/ab.rb +0 -337
- data/lib/stella/adapter/base.rb +0 -106
- data/lib/stella/adapter/httperf.rb +0 -305
- data/lib/stella/adapter/pcap_watcher.rb +0 -221
- data/lib/stella/adapter/proxy_watcher.rb +0 -76
- data/lib/stella/adapter/siege.rb +0 -341
- data/lib/stella/cli.rb +0 -258
- data/lib/stella/cli/agents.rb +0 -73
- data/lib/stella/cli/base.rb +0 -55
- data/lib/stella/cli/language.rb +0 -18
- data/lib/stella/cli/localtest.rb +0 -78
- data/lib/stella/cli/sysinfo.rb +0 -16
- data/lib/stella/cli/watch.rb +0 -278
- data/lib/stella/command/localtest.rb +0 -358
- data/lib/stella/response.rb +0 -85
- data/lib/stella/storable.rb +0 -201
- data/lib/stella/support.rb +0 -276
- data/lib/stella/sysinfo.rb +0 -257
- data/lib/stella/test/definition.rb +0 -79
- data/lib/stella/test/run/summary.rb +0 -70
- data/lib/stella/test/stats.rb +0 -114
- data/lib/stella/text.rb +0 -64
- data/lib/stella/text/resource.rb +0 -38
- data/lib/utils/crypto-key.rb +0 -84
- data/lib/utils/domainutil.rb +0 -47
- data/lib/utils/escape.rb +0 -302
- data/lib/utils/fileutil.rb +0 -78
- data/lib/utils/httputil.rb +0 -266
- data/lib/utils/mathutil.rb +0 -15
- data/lib/utils/textgraph.rb +0 -267
- data/lib/utils/timerutil.rb +0 -58
- data/lib/win32/Console.rb +0 -970
- data/lib/win32/Console/ANSI.rb +0 -305
- data/support/kvm.h +0 -91
- data/support/ruby-pcap-takuma-notes.txt +0 -19
- data/support/ruby-pcap-takuma-patch.txt +0 -30
- data/support/text/en.yaml +0 -80
- data/support/text/nl.yaml +0 -7
- data/support/useragents.txt +0 -75
- data/tests/01-util_test.rb +0 -0
- data/tests/02-stella-util_test.rb +0 -42
- data/tests/10-stella_test.rb +0 -104
- data/tests/11-stella-storable_test.rb +0 -68
- data/tests/60-stella-command_test.rb +0 -248
- data/tests/80-stella-cli_test.rb +0 -45
- 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
|
-
|
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
|
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
|
-
|
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) )
|
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
|
+
|