blitz 0.1.12 → 0.1.13

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.
@@ -47,21 +47,38 @@ class Error < StandardError # :nodoc:
47
47
  class DNS < Region
48
48
  end
49
49
 
50
+ # This exception is raised when the arguments to sprint or rush is invalid
51
+ class Parse < Region
52
+ end
53
+
54
+ # This exception is raised when a particular step fails in some ways
55
+ class Step < Region
56
+ # The step index where the error occurred
57
+ attr_reader :step
58
+
59
+ # An array of Blitz::Curl::Sprint::Step objects each containing requests
60
+ # and [potentially] responses. Depending on which step of the transaction
61
+ # the failure was, this array could potentially be empty
62
+ attr_reader :steps
63
+
64
+ def initialize json # :nodoc:
65
+ @step = json['step']
66
+ @steps = json['steps'].map { |s| Sprint::Step.new s }
67
+ super
68
+ end
69
+ end
70
+
50
71
  # This exception is raised when the connection to your app fails
51
- class Connect < Region
72
+ class Connect < Step
52
73
  end
53
74
 
54
75
  # This exception is raised when the connection or the response times out
55
- class Timeout < Region
76
+ class Timeout < Step
56
77
  end
57
78
 
58
- # This exception is raised when the arguments to sprint or rush is invalid
59
- class Parse < Region
60
- end
61
-
62
79
  # This exception is raised when you have an explicit status code check and
63
80
  # the assertion fails
64
- class Status < Region
81
+ class Status < Step
65
82
  end
66
83
  end
67
84
  end # Curl
@@ -4,6 +4,32 @@ module Curl # :nodoc:
4
4
  # include the entire timeline containing the average duration, the concurrency,
5
5
  # the bytes sent/received, etc.
6
6
  class Rush
7
+ # Per-step (for transactional rushes) metrics of a rush at time[i]
8
+ class Step
9
+ # The duration of this step, when successful
10
+ attr_reader :duration
11
+
12
+ # Average TCP connect times for this step
13
+ attr_reader :connect
14
+
15
+ # Cummulative errors for this step
16
+ attr_reader :errors
17
+
18
+ # Cummulative timeouts for this step
19
+ attr_reader :timeouts
20
+
21
+ # Cummulative assertion failures on status code for this step
22
+ attr_reader :asserts
23
+
24
+ def initialize json
25
+ @duration = json['d']
26
+ @connect = json['c']
27
+ @errors = json['e']
28
+ @timeouts = json['t']
29
+ @asserts = json['a']
30
+ end
31
+ end
32
+
7
33
  # Snapshot of a rush at time[i] containing information about hits, errors
8
34
  # timeouts, etc.
9
35
  class Point
@@ -34,6 +60,9 @@ class Rush
34
60
  # The total number of bytes received
35
61
  attr_reader :rxbytes
36
62
 
63
+ # Per-step metric at this point in time
64
+ attr_reader :steps
65
+
37
66
  def initialize json # :nodoc:
38
67
  @timestamp = json['timestamp']
39
68
  @duration = json['duration']
@@ -44,6 +73,7 @@ class Rush
44
73
  @volume = json['volume']
45
74
  @txbytes = json['txbytes']
46
75
  @rxbytes = json['rxbytes']
76
+ @steps = json['steps'].map { |s| Step.new s }
47
77
  end
48
78
  end
49
79
 
@@ -128,6 +158,8 @@ class Rush
128
158
  raise Error::DNS.new(result)
129
159
  elsif error == 'authorize'
130
160
  raise Error::Authorize.new(result)
161
+ elsif error == 'parse'
162
+ raise Error::Parse.new(result)
131
163
  else
132
164
  raise Error
133
165
  end
@@ -58,30 +58,46 @@ class Sprint
58
58
  end
59
59
  end
60
60
 
61
- # Contains the result from a successful sprint
62
- class Result
63
- # The region from which this sprint was executed
64
- attr_reader :region
65
-
66
- # The overall response time for the successful hit
67
- attr_reader :duration
68
-
61
+ # Represents a step in the transaction (even if there's only one). Each
62
+ # step contains the request and response objects as well as the stats
63
+ # associated with them.
64
+ class Step
69
65
  # The time it took for the TCP connection
70
66
  attr_reader :connect
71
67
 
68
+ # The time it took for this step (includes the connect, send and receive)
69
+ attr_reader :duration
70
+
72
71
  # The request object containing the URL, headers and content, if any
73
72
  attr_reader :request
74
73
 
75
74
  # The response object containing the status code, headers and content, if any
76
75
  attr_reader :response
77
76
 
77
+ def initialize json # :nodoc:
78
+ @connect = json['connect']
79
+ @duration = json['duration']
80
+ @request = Request.new json['request'] if json['request']
81
+ @response = Response.new json['response'] if json['response']
82
+ end
83
+ end
84
+
85
+ # Contains the result from a successful sprint
86
+ class Result
87
+ # The region from which this sprint was executed
88
+ attr_reader :region
89
+
90
+ # The overall response time for the entire transaction
91
+ attr_reader :duration
92
+
93
+ # Stats about the individual steps
94
+ attr_reader :steps
95
+
78
96
  def initialize json # :nodoc:
79
97
  result = json['result']
80
98
  @region = result['region']
81
99
  @duration = result['duration']
82
- @connect = result['connect']
83
- @request = Request.new result['request']
84
- @response = Response.new result['response']
100
+ @steps = result['steps'].map { |step| Step.new step }
85
101
  end
86
102
  end
87
103
 
@@ -139,7 +155,7 @@ class Sprint
139
155
  raise Error::Timeout.new(result)
140
156
  elsif error == 'parse'
141
157
  raise Error::Parse.new(result)
142
- elsif result['assert'] == 0
158
+ elsif error == 'assert'
143
159
  raise Error::Status.new(result)
144
160
  else
145
161
  raise Error
@@ -1,248 +1,244 @@
1
- describe "arg parsing" do
2
-
3
- TEST_URL = "http://foo.com"
4
- VAR = 'foo'
5
- TEST_VAR_URL = 'http://foo.com?var=#{foo}'
6
- MIN = 10
7
- MAX = 30
8
- # because of 1.8.7 and 1.9.2 differences, maintain both LIST and LIST_AS_STRING constants
9
- LIST = [ 'a', 'b', 'c', '1', '2', '3']
10
- LIST_AS_STRING = "[a,b,c,1,2,3]"
11
- COUNT = 60
12
- COUNT_DEFAULT = 1000
13
- DURATION = 100
14
- REGION = 'california'
15
-
16
- curl = ::Blitz::Command::Curl.new
17
- describe "basic args" do
18
-
19
- describe "pattern and region" do
20
- @args = {
21
- "expanded parameters" => [ '--pattern', '1-250:60', "--region", "#{REGION}", "#{TEST_URL}" ],
22
- "short parameters" => [ '-p', '1-250:60', "--region", "#{REGION}", "#{TEST_URL}" ]
23
- }
24
-
25
- @args.each do |name, argv|
26
- parsed_args = curl.__send__ :parse_cli, argv
27
-
28
- it "should return a hash from the method when sending #{name}" do
29
- parsed_args.should be_a(Hash)
30
- end
31
-
32
- it "should populate the URL into the url key when sending #{name}" do
33
- parsed_args['url'].should be_a(String)
34
- parsed_args['url'].should == TEST_URL
35
- end
36
-
37
- it "should put --pattern arguments in the correct structure when sending #{name}" do
38
- parsed_args['pattern'].should be_a(Hash)
39
- parsed_args['pattern']['iterations'].should be_equal 1
40
- parsed_args['pattern']['intervals'].should be_a(Array)
41
- parsed_args['pattern']['intervals'][0].should be_a(Hash)
42
- parsed_args['pattern']['intervals'][0]['start'].should be_equal 1
43
- parsed_args['pattern']['intervals'][0]['end'].should be_equal 250
44
- parsed_args['pattern']['intervals'][0]['duration'].should be_equal 60
45
- end
46
-
47
- it "should allow a specific region to be passed when sending #{name}" do
48
- parsed_args['region'].should be_a(String)
49
- parsed_args['region'].should == REGION
50
- end
1
+ describe "parse_cli" do
2
+ attr_reader :curl
3
+
4
+ before :each do
5
+ @curl = Blitz::Command::Curl.new
6
+ class << @curl
7
+ def parse args
8
+ parse_cli args
51
9
  end
52
10
  end
53
-
54
- @command_args = [
55
- { :short => '-A', :long => '--user-agent', :params => '"TEST STRING"' },
56
- { :short => '-b', :long => '--cookie', :params => 'name=somecookie' },
57
- { :short => '-d', :long => '--data', :params => '"data for post"'},
58
- { :short => '-D', :long => '--dump-header', :params => '"somefile.out"' },
59
- { :short => '-e', :long => '--referer', :params => '"http://google.com"' },
60
- { :short => '-H', :long => '--header', :params => 'some_header' },
61
- { :short => '-s', :long => '--status', :params => '500', :return_type => Integer },
62
- { :short => '-T', :long => '--timeout', :params => '750', :return_type => Integer },
63
- { :short => '-u', :long => '--user', :params => 'foo:bar' },
64
- { :short => '-X', :long => '--request', :params => 'GET' },
65
- { :short => '-V', :long => '--verbose' },
66
- { :short => '-1', :long => '--tlsv1' },
67
- { :short => '-2', :long => '--sslv2' },
68
- { :short => '-3', :long => '--sslv3' },
69
- ]
70
- @command_args.each do |test|
71
- test_name = /--(.*)/.match(test[:long])[1]
72
- describe "#{test_name}" do
73
- [ :short, :long ].each do |flag|
74
- argv = []
75
- argv << test[flag]
76
- argv << test[:params] if test[:params]
77
- argv << "#{TEST_URL}"
78
- it "#{test[flag]} should not raise an error and populate the hash properly" do
79
- lambda { curl.__send__ :parse_cli, argv.dup }.should_not raise_error
80
- parsed_args = curl.__send__ :parse_cli, argv
81
- # special checks for cookies and headers, as their structure in the return data is different
82
- if test_name == 'cookie' || test_name == 'header'
83
- return_key = "#{test_name}s"
84
- parsed_args[return_key].should be_an(Array)
85
- parsed_args[return_key][0].should == test[:params]
86
- # special checks for data, as its structure in the return data is different
87
- elsif test_name == 'data'
88
- parsed_args['content'].should be_a(Hash)
89
- parsed_args['content']['data'].should be_an(Array)
90
- parsed_args['content']['data'][0].should == test[:params]
91
- # special checks for ssl params
92
- elsif test_name.match(/^ssl|tls/)
93
- parsed_args['ssl'].should == test_name
94
- # for integer params, make sure the test returns correct quoting
95
- elsif test[:return_type] == Integer
96
- parsed_args[test_name].should == test[:params].to_i
97
- elsif test[:params].is_a?(String)
98
- parsed_args[test_name].should == test[:params]
99
- end
100
- end
101
- end
11
+ end
12
+
13
+ context "url" do
14
+ it "should check that the args are not empty" do
15
+ lambda { curl.parse %w[] }.should raise_error(ArgumentError, /no URL specified!/)
16
+ end
17
+
18
+ it "should not check for URL when --help is specified" do
19
+ %w[-h --help].each do |h|
20
+ hash = curl.parse [h]
21
+ hash.should include 'help'
102
22
  end
103
23
  end
24
+
25
+ it "should succeed when a URL is given" do
26
+ hash = curl.parse %w[blitz.io]
27
+ hash.should include 'steps'
28
+ hash['steps'].should be_a(Array)
29
+ hash['steps'].size.should == 1
30
+ hash['steps'].first.should include 'url'
31
+ hash['steps'].first['url'].should == 'blitz.io'
32
+ end
33
+
34
+ it "should succeed when multiple URLs are given" do
35
+ hash = curl.parse %w[blitz.io docs.blitz.io]
36
+ hash.should include 'steps'
37
+ hash['steps'].should be_a(Array)
38
+ hash['steps'].size.should == 2
39
+ hash['steps'][0].should include 'url'
40
+ hash['steps'][0]['url'].should == 'blitz.io'
41
+ hash['steps'][1].should include 'url'
42
+ hash['steps'][1]['url'].should == 'docs.blitz.io'
43
+ end
104
44
  end
105
-
106
- describe "help" do
107
- @args = {
108
- "expanded parameters" => [ '--help' ],
109
- "short parameters" => [ '-h' ]
110
- }
111
- @args.each do |name, argv|
112
- it "should return boolean help flag in hash for #{name}" do
113
- parsed_args = curl.__send__ :parse_cli, argv
114
- parsed_args.should be_a(Hash)
115
- parsed_args['help'].should be_true
116
- end
45
+
46
+ context "user-agent" do
47
+ it "should check that a user-agent is given" do
48
+ lambda { curl.parse %w[--user-agent] }.should raise_error(MiniTest::Assertion, /missing value/)
49
+ end
50
+
51
+ it "should support one user-agent for each step" do
52
+ hash = curl.parse %w[-A foo blitz.io -A bar /faq]
53
+ hash.should include 'steps'
54
+ hash['steps'].size.should == 2
55
+ hash['steps'][0]['user-agent'] == 'foo'
56
+ hash['steps'][1]['user-agent'] == 'bar'
117
57
  end
118
58
  end
119
-
120
- describe "Usage errors" do
121
- describe "no arguments" do
122
- it "should throw an error when no arguments are given" do
123
- lambda { curl.__send__ :parse_cli }.should raise_error(ArgumentError, /wrong number of arg/)
124
- end
59
+
60
+ context "cookie" do
61
+ it "should check that a cookie is given" do
62
+ lambda { curl.parse %w[--cookie] }.should raise_error(MiniTest::Assertion, /missing value/)
125
63
  end
126
- describe "no URL" do
127
- @args = {
128
- "expanded parameters" => [ '--pattern', '1-250:60', "--variable:#{VAR}", "udid", "--region", "#{REGION}" ],
129
- "short parameters" => [ '-p', '1-250:60', "-v:#{VAR}", "u", "-r", "#{REGION}" ]
130
- }
131
- @args.each do |name, argv|
132
- it "should throw an error when no URL is given for #{name}" do
133
- lambda { curl.__send__ :parse_cli, argv}.should raise_error(ArgumentError, /URL/)
134
- end
135
- end
64
+
65
+ it "should be an array of cookies" do
66
+ hash = curl.parse %w[--cookie foo=bar --cookie hello=world blitz.io]
67
+ hash['steps'].size.should == 1
68
+ step = hash['steps'].first
69
+ step['cookies'].should be_a(Array)
70
+ step['cookies'].should == [ 'foo=bar', 'hello=world' ]
136
71
  end
137
- describe "bad arguments" do
138
- @args = {
139
- "double dash on short param" => [ '--p', '1-250:60', "--variable:#{VAR}", "udid", "--region", "#{REGION}", "#{TEST_URL}" ],
140
- "single dash on long param" => [ '-pattern', '1-250:60', "-v:#{VAR}", "u", "-r", "#{REGION}", "#{TEST_URL}" ],
141
- "unsupported option, short format" => [ '-z', "#{TEST_URL}" ],
142
- "unsupported option, long format" => [ '--foobar', "#{TEST_URL}" ]
143
- }
144
- @args.each do |name, argv|
145
- it "should throw an error when bad arguments are passed for #{name}" do
146
- lambda { curl.__send__ :parse_cli, argv}.should raise_error(ArgumentError, /Unknown option/)
147
- end
148
- end
72
+
73
+ it "should support one cookie for each step" do
74
+ hash = curl.parse %w[-b foo=bar blitz.io -b hello=world /faq]
75
+ hash.should include 'steps'
76
+ hash['steps'].size.should == 2
77
+ hash['steps'][0]['cookies'] == [ 'foo=bar' ]
78
+ hash['steps'][1]['cookies'] == [ 'hello=world' ]
149
79
  end
150
80
  end
151
-
152
- describe "variable support" do
153
- describe "number and alpha" do
154
- @args = {
155
- "number, expanded parameters, no values given" =>
156
- [ '--pattern', '1-250:60', "--variable:#{VAR}", "number", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
157
- "number, short parameters, no values given" =>
158
- [ '-p', '1-250:60', "-v:#{VAR}", "n", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
159
- "number, expanded parameters, no count given" =>
160
- [ '--pattern', '1-250:60', "--variable:#{VAR}", "number[#{MIN},#{MAX}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
161
- "number, short parameters, no count given" =>
162
- [ '-p', '1-250:60', "-v:#{VAR}", "n[#{MIN},#{MAX}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
163
- "number, expanded parameters, count given" =>
164
- [ '--pattern', '1-250:60', "--variable:#{VAR}", "number[#{MIN},#{MAX},#{COUNT}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
165
- "number, short parameters, count given" =>
166
- [ '-p', '1-250:60', "-v:#{VAR}", "n[#{MIN},#{MAX},#{COUNT}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
167
- "alpha, expanded parameters, no values given" =>
168
- [ '--pattern', '1-250:60', "--variable:#{VAR}", "alpha", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
169
- "alpha, short parameters, no values given" =>
170
- [ '-p', '1-250:60', "-v:#{VAR}", "a", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
171
- "alpha, expanded parameters, no count given" =>
172
- [ '--pattern', '1-250:60', "--variable:#{VAR}", "alpha[#{MIN},#{MAX}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
173
- "alpha, short parameters, no count given" =>
174
- [ '-p', '1-250:60', "-v:#{VAR}", "a[#{MIN},#{MAX}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
175
- "alpha, expanded parameters, count given" =>
176
- [ '--pattern', '1-250:60', "--variable:#{VAR}", "alpha[#{MIN},#{MAX},#{COUNT}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ],
177
- "alpha, short parameters, count given" =>
178
- [ '-p', '1-250:60', "-v:#{VAR}", "a[#{MIN},#{MAX},#{COUNT}]", "--region", "#{REGION}", "#{TEST_VAR_URL}" ]
179
- }
180
-
181
- @args.each do |name, argv|
182
- parsed_args = curl.__send__ :parse_cli, argv
183
- it "should work with #{name}" do
184
- parsed_args['variables'].should be_a(Hash)
185
- parsed_args['variables'][VAR].should be_a(Hash)
186
-
187
- if name.match(/^number/)
188
- parsed_args['variables'][VAR]['type'].should == "number"
189
- elsif name.match(/^alpha/)
190
- parsed_args['variables'][VAR]['type'].should == "alpha"
191
- end
192
-
193
- if name.match(/no values given/)
194
- parsed_args['variables'][VAR]['min'].should be_nil
195
- parsed_args['variables'][VAR]['max'].should be_nil
196
- parsed_args['variables'][VAR]['count'].should be_nil
197
- elsif name.match(/no count given/)
198
- parsed_args['variables'][VAR]['min'].should be_an(Integer)
199
- parsed_args['variables'][VAR]['min'].should == MIN
200
- parsed_args['variables'][VAR]['max'].should be_an(Integer)
201
- parsed_args['variables'][VAR]['max'].should == MAX
202
- parsed_args['variables'][VAR]['count'].should be_an(Integer)
203
- parsed_args['variables'][VAR]['count'].should == COUNT_DEFAULT
204
- else
205
- parsed_args['variables'][VAR]['min'].should be_an(Integer)
206
- parsed_args['variables'][VAR]['min'].should == MIN
207
- parsed_args['variables'][VAR]['max'].should be_an(Integer)
208
- parsed_args['variables'][VAR]['max'].should == MAX
209
- parsed_args['variables'][VAR]['count'].should be_an(Integer)
210
- parsed_args['variables'][VAR]['count'].should == COUNT
211
- end
212
-
213
- end
214
- end
81
+
82
+ context "data" do
83
+ it "should check that a data is given" do
84
+ lambda { curl.parse %w[--data] }.should raise_error(MiniTest::Assertion, /missing value/)
215
85
  end
216
-
217
- describe "list parameter" do
218
- @args = {
219
- "expanded parameters" => [ '--pattern', '1-250:60', "--variable:#{VAR}", "list#{LIST_AS_STRING}", "--region", "#{REGION}", "#{TEST_URL}" ],
220
- "short parameters" => [ '-p', '1-250:60', "-v:#{VAR}", "#{LIST_AS_STRING}", "-r", "#{REGION}", "#{TEST_URL}" ]
221
- }
222
- @args.each do |name, argv|
223
- it "should allow lists to be sent as a variable type for #{name}" do
224
- parsed_args = curl.__send__ :parse_cli, argv
225
- parsed_args['variables'][VAR].should be_a(Hash)
226
- parsed_args['variables'][VAR]['type'].should == 'list'
227
- parsed_args['variables'][VAR]['entries'].should be_an(Array)
228
- parsed_args['variables'][VAR]['entries'].should == LIST
229
- end
230
- end
86
+
87
+ it "should be an array of data" do
88
+ hash = curl.parse %w[--data foo=bar --data hello=world blitz.io]
89
+ hash['steps'].size.should == 1
90
+ step = hash['steps'].first
91
+ step['content'].should be_a(Hash)
92
+ step['content']['data'].should be_a(Array)
93
+ step['content']['data'].should == [ 'foo=bar', 'hello=world' ]
94
+ end
95
+
96
+ it "should support one data for each step" do
97
+ hash = curl.parse %w[-d foo=bar blitz.io -d hello=world /faq]
98
+ hash.should include 'steps'
99
+ hash['steps'].size.should == 2
100
+ hash['steps'][0]['content']['data'] == [ 'foo=bar' ]
101
+ hash['steps'][1]['content']['data'] == [ 'hello=world' ]
102
+ end
103
+ end
104
+
105
+ context "referer" do
106
+ it "should check that a referer is given" do
107
+ lambda { curl.parse %w[--referer] }.should raise_error(MiniTest::Assertion, /missing value/)
108
+ end
109
+
110
+ it "should support one referer for each step" do
111
+ hash = curl.parse %w[-e foo blitz.io -e bar /faq]
112
+ hash.should include 'steps'
113
+ hash['steps'].size.should == 2
114
+ hash['steps'][0]['referer'] == 'foo'
115
+ hash['steps'][1]['referer'] == 'bar'
116
+ end
117
+ end
118
+
119
+ context "headers" do
120
+ it "should check that a header is given" do
121
+ lambda { curl.parse %w[--header] }.should raise_error(MiniTest::Assertion, /missing value/)
122
+ end
123
+
124
+ it "should be an array of headers" do
125
+ hash = curl.parse %w[-H foo=bar -H hello=world blitz.io]
126
+ hash['steps'].size.should == 1
127
+ step = hash['steps'].first
128
+ step['headers'].should be_a(Array)
129
+ step['headers'].should == [ 'foo=bar', 'hello=world' ]
130
+ end
131
+
132
+ it "should support one header for each step" do
133
+ hash = curl.parse %w[-H foo=bar blitz.io -H hello=world /faq]
134
+ hash.should include 'steps'
135
+ hash['steps'].size.should == 2
136
+ hash['steps'][0]['headers'] == [ 'foo=bar' ]
137
+ hash['steps'][1]['headers'] == [ 'hello=world' ]
231
138
  end
232
-
233
- describe "udid parameter" do
234
- @args = {
235
- "expanded parameters" => [ '--pattern', '1-250:60', "--variable:#{VAR}", "udid", "--region", "#{REGION}", "#{TEST_URL}" ],
236
- "short parameters" => [ '-p', '1-250:60', "-v:#{VAR}", "u", "-r", "#{REGION}", "#{TEST_URL}" ]
237
- }
238
- @args.each do |name, argv|
239
- parsed_args = curl.__send__ :parse_cli, argv
240
- it "should allow udid to be sent as a variable type" do
241
- parsed_args['variables'][VAR].should be_a(Hash)
242
- parsed_args['variables'][VAR]['type'].should == 'udid'
243
- end
139
+ end
140
+
141
+ context "pattern" do
142
+ it "should check that a pattern is given" do
143
+ lambda { curl.parse %w[--pattern] }.should raise_error(MiniTest::Assertion, /missing value/)
144
+ end
145
+
146
+ it "should add the pattern to the hash" do
147
+ hash = curl.parse %w[-p 1-250:60 blitz.io]
148
+ hash['pattern'].should be_a(Hash)
149
+ hash['pattern']['iterations'].should == 1
150
+ hash['pattern']['intervals'].should be_an(Array)
151
+ hash['pattern']['intervals'].size.should == 1
152
+ hash['pattern']['intervals'].first['iterations'].should == 1
153
+ hash['pattern']['intervals'].first['start'].should == 1
154
+ hash['pattern']['intervals'].first['end'].should == 250
155
+ hash['pattern']['intervals'].first['duration'].should == 60
156
+ end
157
+
158
+ it "should parse multiple intervals in the pattern" do
159
+ hash = curl.parse %w[-p 1-250:60,500-500:10 blitz.io]
160
+ hash['pattern'].should be_a(Hash)
161
+ hash['pattern']['iterations'].should == 1
162
+ hash['pattern']['intervals'].should be_an(Array)
163
+ hash['pattern']['intervals'].size.should == 2
164
+ hash['pattern']['intervals'].first['iterations'].should == 1
165
+ hash['pattern']['intervals'].first['start'].should == 1
166
+ hash['pattern']['intervals'].first['end'].should == 250
167
+ hash['pattern']['intervals'].first['duration'].should == 60
168
+ hash['pattern']['intervals'].last['iterations'].should == 1
169
+ hash['pattern']['intervals'].last['start'].should == 500
170
+ hash['pattern']['intervals'].last['end'].should == 500
171
+ hash['pattern']['intervals'].last['duration'].should == 10
172
+ end
173
+ end
174
+
175
+ context "region" do
176
+ it "should check that a region is given" do
177
+ lambda { curl.parse %w[--region] }.should raise_error(MiniTest::Assertion, /missing value/)
178
+ end
179
+
180
+ it "should verify that it's a valid region" do
181
+ [ 'california', 'virginia', 'ireland', 'singapore', 'japan' ].each do |r|
182
+ lambda { curl.parse ['-r', r, 'blitz.io' ] }.should_not raise_error
244
183
  end
184
+
185
+ lambda { curl.parse %w[-r a ] }.should raise_error(MiniTest::Assertion, /must be one of/)
186
+ end
187
+ end
188
+
189
+ context "status" do
190
+ it "should check that a status is given" do
191
+ lambda { curl.parse %w[--status] }.should raise_error(MiniTest::Assertion, /missing value/)
192
+ end
193
+
194
+ it "should support one status for each step" do
195
+ hash = curl.parse %w[-s 302 blitz.io -s 200 /faq]
196
+ hash.should include 'steps'
197
+ hash['steps'].size.should == 2
198
+ hash['steps'][0]['status'] == 302
199
+ hash['steps'][1]['status'] == 200
200
+ end
201
+ end
202
+
203
+ context "timeout" do
204
+ it "should check that a timeout is given" do
205
+ lambda { curl.parse %w[--timeout] }.should raise_error(MiniTest::Assertion, /missing value/)
206
+ end
207
+
208
+ it "should support one timeout for each step" do
209
+ hash = curl.parse %w[-T 100 blitz.io -T 200 /faq]
210
+ hash.should include 'steps'
211
+ hash['steps'].size.should == 2
212
+ hash['steps'][0]['timeout'] == 100
213
+ hash['steps'][1]['timeout'] == 200
214
+ end
215
+ end
216
+
217
+ context "user" do
218
+ it "should check that a user is given" do
219
+ lambda { curl.parse %w[--user] }.should raise_error(MiniTest::Assertion, /missing value/)
220
+ end
221
+
222
+ it "should support one user for each step" do
223
+ hash = curl.parse %w[-u foo:bar blitz.io -u hello:world /faq]
224
+ hash.should include 'steps'
225
+ hash['steps'].size.should == 2
226
+ hash['steps'][0]['user'] == 'foo:bar'
227
+ hash['steps'][1]['user'] == 'hello:world'
228
+ end
229
+ end
230
+
231
+ context "request" do
232
+ it "should check that a request is given" do
233
+ lambda { curl.parse %w[--request] }.should raise_error(MiniTest::Assertion, /missing value/)
234
+ end
235
+
236
+ it "should support one request for each step" do
237
+ hash = curl.parse %w[-X GET blitz.io -X POST /faq]
238
+ hash.should include 'steps'
239
+ hash['steps'].size.should == 2
240
+ hash['steps'][0]['request'] == 'GET'
241
+ hash['steps'][1]['request'] == 'POST'
245
242
  end
246
243
  end
247
- end
248
-
244
+ end