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
@@ -0,0 +1,87 @@
1
+
2
+
3
+ class Stella::Config < Storable
4
+ include Gibbler::Complex
5
+
6
+ field :source
7
+ field :apikey
8
+ field :secret
9
+
10
+ # Returns true when the current config matches the default config
11
+ def default?; to_hash.gibbler == DEFAULT_CONFIG_HASH; end
12
+
13
+ def self.each_path(&blk)
14
+ [PROJECT_PATH, USER_PATH].each do |path|
15
+ Stella.ld "Loading #{path}"
16
+ blk.call(path) if File.exists? path
17
+ end
18
+ end
19
+
20
+ def self.refresh
21
+ conf = {}
22
+ Stella::Config.each_path do |path|
23
+ tmp = YAML.load_file path
24
+ conf.merge! tmp if tmp
25
+ end
26
+ from_hash conf
27
+ end
28
+
29
+ def self.init
30
+ raise AlreadyInitialized, PROJECT_PATH if File.exists? PROJECT_PATH
31
+ dir = File.dirname USER_PATH
32
+ Dir.mkdir(dir, 0700) unless File.exists? dir
33
+ unless File.exists? USER_PATH
34
+ Stella.li "Creating #{USER_PATH} (Add your credentials here)"
35
+ Stella::Utils.write_to_file(USER_PATH, DEFAULT_CONFIG, 'w', 0600)
36
+ end
37
+
38
+ dir = File.dirname PROJECT_PATH
39
+ Dir.mkdir(dir, 0700) unless File.exists? dir
40
+
41
+ Stella.li "Creating #{PROJECT_PATH}"
42
+ Stella::Utils.write_to_file(PROJECT_PATH, 'target:', 'w', 0600)
43
+ end
44
+
45
+ def self.blast
46
+ if File.exists? USER_PATH
47
+ Stella.li "Blasting #{USER_PATH}"
48
+ FileUtils.rm_rf File.dirname(USER_PATH)
49
+ end
50
+ if File.exists? PROJECT_PATH
51
+ Stella.li "Blasting #{PROJECT_PATH}"
52
+ FileUtils.rm_rf File.dirname(PROJECT_PATH)
53
+ end
54
+ end
55
+
56
+
57
+ private
58
+
59
+ def self.find_project_config
60
+ dir = Dir.pwd.split File::SEPARATOR
61
+ path = nil
62
+ while !dir.empty?
63
+ tmp = File.join(dir.join(File::SEPARATOR), DIR_NAME, 'config')
64
+ Stella.ld " -> looking for #{tmp}"
65
+ path = tmp and break if File.exists? tmp
66
+ dir.pop
67
+ end
68
+ path ||= File.join(Dir.pwd, DIR_NAME, 'config')
69
+ path
70
+ end
71
+
72
+
73
+ unless defined?(DIR_NAME)
74
+ DIR_NAME = Stella.sysinfo.os == :windows ? 'Stella' : '.stella'
75
+ USER_PATH = File.join(Stella.sysinfo.home, DIR_NAME, 'config')
76
+ PROJECT_PATH = Stella::Config.find_project_config
77
+ DEFAULT_CONFIG = <<CONF
78
+ apikey: ''
79
+ secret: ''
80
+ remote: stella.solutious.com:443
81
+ CONF
82
+ DEFAULT_CONFIG_HASH = YAML.load(DEFAULT_CONFIG).gibbler
83
+ end
84
+
85
+ class AlreadyInitialized < Stella::Error; end
86
+ end
87
+
@@ -0,0 +1,85 @@
1
+
2
+ module Stella::Data
3
+
4
+ module Helpers
5
+
6
+
7
+ def random(input=nil)
8
+
9
+ Proc.new do
10
+ value = case input.class.to_s
11
+ when "Symbol"
12
+ resource(input)
13
+ when "Array"
14
+ input
15
+ when "Range"
16
+ input.to_a
17
+ when "Fixnum"
18
+ Stella::Utils.strand( input )
19
+ when "NilClass"
20
+ Stella::Utils.strand( rand(100) )
21
+ end
22
+ Stella.ld "RANDVALUES: #{input} #{value.inspect}"
23
+ value = value[ rand(value.size) ] if value.is_a?(Array)
24
+ Stella.ld "SELECTED: #{value}"
25
+ value
26
+ end
27
+ end
28
+
29
+ def sequential(input=nil)
30
+ digest = input.gibbler
31
+ Proc.new do
32
+ value = case input.class.to_s
33
+ when "Symbol"
34
+ ret = resource(input)
35
+ ret
36
+ when "Array"
37
+ input
38
+ when "Range"
39
+ input.to_a
40
+ end
41
+ Stella.ld "SEQVALUES: #{input} #{value.inspect}"
42
+ @sequential_offset ||= {}
43
+ @sequential_offset[digest] ||= 0
44
+ if value.is_a?(Array)
45
+ size = value[ @sequential_offset[digest] ].size
46
+ value = value[ @sequential_offset[digest] ]
47
+ @sequential_offset[digest] += 1
48
+ @sequential_offset[digest] = 0 if @sequential_offset[digest] > size
49
+ end
50
+ Stella.ld "SELECTED: #{value}"
51
+ value
52
+ end
53
+ end
54
+
55
+ def rsequential(input=nil)
56
+ digest = input.gibbler
57
+ Proc.new do
58
+ value = case input.class.to_s
59
+ when "Symbol"
60
+ ret = resource(input)
61
+ ret
62
+ when "Array"
63
+ input
64
+ when "Range"
65
+ input.to_a
66
+ end
67
+ Stella.ld "RSEQVALUES: #{input} #{value.inspect}"
68
+ @rsequential_offset ||= {}
69
+ @rsequential_offset[digest] ||= value.size-1 rescue 1
70
+ if value.is_a?(Array)
71
+ size = value[ @rsequential_offset[digest] ].size
72
+ value = value[ @rsequential_offset[digest] ]
73
+ @rsequential_offset[digest] -= 1
74
+ @rsequential_offset[digest] = size if @rsequential_offset[digest] < 0
75
+ end
76
+ Stella.ld "SELECTED: #{value}"
77
+ value
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ Stella::Utils.require_glob(STELLA_LIB_HOME, 'stella', 'data', '*.rb')
@@ -1,259 +1,4 @@
1
1
 
2
- require 'storable'
3
- require 'util/httputil'
4
- require 'base64'
2
+ module Stella::Data::HTTP; end
5
3
 
6
- module Stella::Data
7
-
8
- # TODO: Implement HTTPHeaders. We should be printing untouched headers.
9
- # HTTPUtil should split the HTTP event lines and that's it. Replace
10
- # parse_header_body with split_header_body
11
- class HTTPHeaders < Storable
12
- attr_reader :raw_data
13
-
14
- def to_s
15
- @raw_data
16
- end
17
-
18
- end
19
-
20
- class HTTPBody < Storable
21
- field :content_type
22
- field :form_param
23
- field :content
24
-
25
- def has_content?
26
- !@content.nil?
27
- end
28
-
29
- end
30
-
31
- class HTTPRequest < Storable
32
- # A string representing a raw HTTP request
33
- attr_reader :raw_data
34
-
35
- # A hash containing blocks to be executed depending on the HTTP response status.
36
- # The hash keys are numeric HTTP Status Codes.
37
- #
38
- # 200 => { ... }
39
- # 304 => { ... }
40
- # 500 => { ... }
41
- #
42
- attr_accessor :response_handler
43
-
44
- field :name
45
- field :stella_id
46
- field :unique_id
47
- field :time => DateTime
48
- field :client_ip
49
- field :server_ip
50
- field :header
51
- field :uri
52
- field :params
53
- field :body
54
- field :http_method
55
- field :http_version
56
-
57
-
58
- def has_body?
59
- !@body.nil? && !@body.empty?
60
- end
61
- def has_request?
62
- false
63
- end
64
-
65
- def initialize (uri_str, method="GET", version="1.1")
66
- @uri = (uri_str.is_a? String) ? URI.parse(uri_str) : uri
67
- @http_method = method
68
- @http_version = version
69
- @headers = {}
70
- @params = {}
71
- @response_handler = {}
72
- @time = Time.now
73
- @stella_id = Stella::Crypto.sign(time.to_i.to_s, "#{@http_method}/#{@uri}/#{@params}")
74
- @unique_id = nil
75
- @body = HTTPBody.new
76
- end
77
-
78
- def set_unique_id(seasoning=rand)
79
- @unique_id = Stella::Crypto.sign(rand.to_s + seasoning.to_s, "#{@http_method}/#{@uri}/#{@params}")
80
- end
81
-
82
-
83
- def from_raw(raw_data=nil)
84
- @raw_data = raw_data
85
- @http_method, @http_version, @uri, @header, @body = self.parse(@raw_data)
86
- @time = DateTime.now
87
- end
88
-
89
- def self.parse(raw)
90
- return unless raw
91
- HTTPUtil::parse_http_request(raw, @uri.host, @uri.port)
92
- end
93
-
94
-
95
- def add_header(*args)
96
- name, value = (args[0].is_a? Hash) ? args[0].to_a.flatten : args
97
- @headers[name.to_s] ||= []
98
- @headers[name.to_s] << value
99
- end
100
- def add_param(*args)
101
- name, value = (args[0].is_a? Hash) ? args[0].to_a.flatten : args
102
-
103
- # BUG: This auto-array shit is causing a problem where the one request
104
- # will set the param and then next will set it again and it becomes
105
- # an array.
106
- #if @params[name.to_s] && !@params[name.to_s].is_a?(Array)
107
- # @params[name.to_s] = [@params[name.to_s]]
108
- #else
109
- # @params[name.to_s] = ""
110
- #end
111
-
112
- @params[name.to_s] = value.to_s
113
- end
114
-
115
- def add_response_handler(*args, &b)
116
- args << 200 if args.empty?
117
- args.each do |status|
118
- @response_handler[status] = b
119
- end
120
- end
121
-
122
- # +content+ can be literal content or a file path
123
- def add_body(content, form_param=nil, content_type=nil)
124
- @body = Stella::Data::HTTPBody.new
125
-
126
- @body.form_param = form_param if form_param
127
- @body.content_type = content_type if content_type
128
-
129
- if File.exists?(content)
130
- @body.content = File.new(content)
131
- @body.content_type ||= "application/x-www-form-urlencoded"
132
- else
133
- @body.content = content
134
- end
135
-
136
- end
137
-
138
-
139
- def body
140
- return nil unless @body
141
- @body
142
- #(!header || header[:Content_Type] || header[:Content_Type] !~ /text/) ? Base64.encode64(@body) : @body
143
- end
144
-
145
-
146
- def headers
147
- return [] unless header
148
- headers = []
149
- header.each_pair do |n,v|
150
- headers << [n.to_s.gsub('_', '-'), v[0]]
151
- end
152
- headers
153
- end
154
-
155
- def inspect
156
- str = "%s %s HTTP/%s" % [http_method, uri.to_s, http_version]
157
- str << $/ + headers.join($/) unless headers.empty?
158
- str << $/ + $/ + body.to_s if body
159
- str
160
- end
161
-
162
- def to_s
163
- str = "%s: %s %s HTTP/%s" % [time.strftime(NICE_TIME_FORMAT), http_method, uri.to_s, http_version]
164
- str
165
- end
166
-
167
- def cookies
168
- return [] if !header.is_a?(Hash) || header[:Cookie].empty?
169
- header[:Cookie]
170
- end
171
-
172
- end
173
-
174
- class HTTPResponse < Storable
175
- attr_reader :raw_data
176
-
177
- field :time => DateTime
178
- field :client_ip => String
179
- field :server_ip => String
180
- field :header => String
181
- field :body => String
182
- field :status => String
183
- field :message => String
184
- field :http_version => String
185
-
186
- def initialize(raw_data=nil)
187
- @raw_data = raw_data
188
- parse(@raw_data)
189
- end
190
-
191
- def parse(raw)
192
- return unless raw
193
- @status, @http_version, @message, @header, @body = HTTPUtil::parse_http_response(raw)
194
- end
195
-
196
- def has_body?
197
- !@body.nil? && !@body.empty?
198
- end
199
- def has_request?
200
- false
201
- end
202
- def has_response?
203
- false
204
- end
205
-
206
-
207
- def body
208
- return nil unless @body
209
- #TODO: Move to HTTPResponse::Body.to_s
210
- if is_binary?
211
- "[skipping binary content]"
212
- elsif is_gzip?
213
- #require 'zlib'
214
- #Zlib::Inflate.inflate(@body)
215
- "[skipping gzip content]"
216
- else
217
- @body
218
- end
219
- end
220
-
221
- def headers
222
- headers = []
223
- header.each_pair do |n,v|
224
- headers << [n.to_s.gsub('_', '-'), v[0]]
225
- end
226
- headers
227
- end
228
-
229
- def is_binary?
230
- (!is_text?) == true
231
- end
232
-
233
- def is_text?
234
- (!header[:Content_Type].nil? && (header[:Content_Type][0].is_a? String) && header[:Content_Type][0][/text/] != nil)
235
- end
236
-
237
- def is_gzip?
238
- (!header[:Content_Encoding].nil? && (header[:Content_Encoding][0].is_a? String) && header[:Content_Encoding][0][/gzip/] != nil)
239
- end
240
-
241
- def inspect
242
- str = "HTTP/%s %s (%s)" % [@http_version, @status, @message]
243
- str << $/ + headers.join($/)
244
- str << $/ + $/ + body if body
245
- str
246
- end
247
-
248
- def to_s
249
- str = "%s: HTTP/%s %s (%s)" % [time.strftime(NICE_TIME_FORMAT), @http_version, @status, @message]
250
- str
251
- end
252
-
253
-
254
- def cookies
255
- return [] unless header.is_a?(Array) && !header[:Set_Cookie].empty?
256
- header[:Set_Cookie]
257
- end
258
- end
259
- end
4
+ Stella::Utils.require_glob(STELLA_LIB_HOME, 'stella', 'data', 'http', '*.rb')
@@ -0,0 +1,15 @@
1
+ module Stella::Data::HTTP
2
+ class Body < Storable
3
+ include Gibbler::Complex
4
+
5
+ field :content_type
6
+ field :form_param
7
+ field :content
8
+
9
+ def has_content?
10
+ !@content.nil?
11
+ end
12
+
13
+ end
14
+
15
+ end