solutious-stella 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|