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.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/Rakefile +0 -7
- data/blitz.gemspec +5 -2
- data/lib/blitz.rb +2 -1
- data/lib/blitz/command/curl.rb +232 -217
- data/lib/blitz/curl/error.rb +24 -7
- data/lib/blitz/curl/rush.rb +32 -0
- data/lib/blitz/curl/sprint.rb +28 -12
- data/spec/command/curl_spec.rb +228 -232
- metadata +44 -86
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -26,6 +26,7 @@ GEM
|
|
26
26
|
rspec-expectations (2.6.0)
|
27
27
|
diff-lcs (~> 1.1.2)
|
28
28
|
rspec-mocks (2.6.0)
|
29
|
+
term-ansicolor (1.0.5)
|
29
30
|
|
30
31
|
PLATFORMS
|
31
32
|
ruby
|
@@ -40,3 +41,4 @@ DEPENDENCIES
|
|
40
41
|
rest-client (~> 1.6.1)
|
41
42
|
rspec (= 2.6.0)
|
42
43
|
rspec-core (= 2.6.4)
|
44
|
+
term-ansicolor (= 1.0.5)
|
data/Rakefile
CHANGED
@@ -32,13 +32,6 @@ Jeweler::Tasks.new do |gem|
|
|
32
32
|
end
|
33
33
|
Jeweler::RubygemsDotOrgTasks.new
|
34
34
|
|
35
|
-
require 'rake/testtask'
|
36
|
-
Rake::TestTask.new(:test) do |test|
|
37
|
-
test.libs << 'lib' << 'test'
|
38
|
-
test.pattern = 'test/**/test_*.rb'
|
39
|
-
test.verbose = true
|
40
|
-
end
|
41
|
-
|
42
35
|
desc "Run all the specs"
|
43
36
|
task :spec do
|
44
37
|
require 'rspec/core'
|
data/blitz.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{blitz}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["pcapr"]
|
12
|
-
s.date = %q{2011-10-
|
12
|
+
s.date = %q{2011-10-11}
|
13
13
|
s.default_executable = %q{blitz}
|
14
14
|
s.description = %q{Make load and performance testing a fun sport}
|
15
15
|
s.email = %q{support@blitz.io}
|
@@ -64,6 +64,7 @@ Gem::Specification.new do |s|
|
|
64
64
|
s.add_runtime_dependency(%q<hexy>, ["~> 0.1.1"])
|
65
65
|
s.add_runtime_dependency(%q<rspec>, ["= 2.6.0"])
|
66
66
|
s.add_runtime_dependency(%q<rspec-core>, ["= 2.6.4"])
|
67
|
+
s.add_runtime_dependency(%q<term-ansicolor>, ["= 1.0.5"])
|
67
68
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
68
69
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
69
70
|
else
|
@@ -74,6 +75,7 @@ Gem::Specification.new do |s|
|
|
74
75
|
s.add_dependency(%q<hexy>, ["~> 0.1.1"])
|
75
76
|
s.add_dependency(%q<rspec>, ["= 2.6.0"])
|
76
77
|
s.add_dependency(%q<rspec-core>, ["= 2.6.4"])
|
78
|
+
s.add_dependency(%q<term-ansicolor>, ["= 1.0.5"])
|
77
79
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
78
80
|
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
79
81
|
end
|
@@ -85,6 +87,7 @@ Gem::Specification.new do |s|
|
|
85
87
|
s.add_dependency(%q<hexy>, ["~> 0.1.1"])
|
86
88
|
s.add_dependency(%q<rspec>, ["= 2.6.0"])
|
87
89
|
s.add_dependency(%q<rspec-core>, ["= 2.6.4"])
|
90
|
+
s.add_dependency(%q<term-ansicolor>, ["= 1.0.5"])
|
88
91
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
89
92
|
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
90
93
|
end
|
data/lib/blitz.rb
CHANGED
data/lib/blitz/command/curl.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
class Blitz
|
2
2
|
class Command
|
3
3
|
class Curl < Command # :nodoc:
|
4
|
+
include Term::ANSIColor
|
5
|
+
|
4
6
|
def cmd_help argv
|
5
7
|
help
|
6
8
|
end
|
@@ -38,17 +40,17 @@ class Curl < Command # :nodoc:
|
|
38
40
|
if check['bytes']
|
39
41
|
bytes = '| ' + check['bytes']
|
40
42
|
end
|
41
|
-
error "#{check['code']} | #{check['url']} #{bytes}"
|
43
|
+
error "#{bold(red(check['code']))} | #{cyan(check['url'])} #{bytes}"
|
42
44
|
end
|
43
45
|
error ''
|
44
46
|
end
|
45
47
|
error "If your app is RESTfully built with sinatra or rails, simply add this route:"
|
46
48
|
error ""
|
47
|
-
error "get '/#{e.uuid}' do"
|
49
|
+
error "get '/#{cyan(e.uuid)}' do"
|
48
50
|
error " '42'"
|
49
51
|
error "end"
|
50
52
|
error ""
|
51
|
-
error "Once this is done, you can blitz #{e.host} all you want."
|
53
|
+
error "Once this is done, you can blitz #{cyan(e.host)} all you want."
|
52
54
|
puts
|
53
55
|
end
|
54
56
|
|
@@ -59,128 +61,137 @@ class Curl < Command # :nodoc:
|
|
59
61
|
print_sprint_result args, result
|
60
62
|
rescue ::Blitz::Curl::Error::Authorize => e
|
61
63
|
authorize_error e
|
64
|
+
rescue ::Blitz::Curl::Error::Step => e
|
65
|
+
error "#{yellow(e.region)}: #{red(e.message)} in step #{e.step}"
|
66
|
+
puts
|
67
|
+
print_sprint_result args, e
|
62
68
|
rescue ::Blitz::Curl::Error::Region => e
|
63
|
-
error "#{e.region}: #{e.message}"
|
69
|
+
error = "#{yellow(e.region)}: #{red(e.message)}"
|
64
70
|
rescue ::Blitz::Curl::Error => e
|
65
|
-
error e.message
|
71
|
+
error red(e.message)
|
66
72
|
end
|
67
73
|
end
|
68
|
-
|
69
|
-
def
|
70
|
-
rtt =
|
74
|
+
|
75
|
+
def pretty_print_duration duration
|
76
|
+
rtt = duration
|
71
77
|
if rtt < 1.0
|
72
78
|
rtt = (rtt * 1000).floor.to_s + ' ms';
|
73
79
|
else
|
74
80
|
rtt = ("%.2f" % rtt) + ' sec';
|
75
81
|
end
|
82
|
+
end
|
76
83
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
msg "
|
81
|
-
end
|
82
|
-
puts "-" * 70
|
83
|
-
puts
|
84
|
-
|
85
|
-
if args['dump-header'] or args['verbose']
|
86
|
-
puts "> " + result.request.line
|
87
|
-
result.request.headers.each_pair { |k, v| puts "> #{k}: #{v}\r\n" }
|
84
|
+
def print_sprint_result args, result
|
85
|
+
if result.respond_to? :duration
|
86
|
+
rtt = pretty_print_duration result.duration
|
87
|
+
msg "#{yellow(result.region)}: Transaction time #{green(rtt)}"
|
88
88
|
puts
|
89
|
+
end
|
89
90
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
result.steps.each do |step|
|
92
|
+
req, res = step.request, step.response
|
93
|
+
if args['dump-header'] or args['verbose']
|
94
|
+
puts "> " + req.line
|
95
|
+
req.headers.each_pair { |k, v| puts "> #{k}: #{v}\r\n" }
|
96
|
+
puts
|
97
|
+
|
98
|
+
content = req.content
|
99
|
+
if not content.empty?
|
100
|
+
if /^[[:print:]]+$/ =~ content
|
101
|
+
puts content
|
102
|
+
else
|
103
|
+
puts Hexy.new(content).to_s
|
104
|
+
end
|
105
|
+
puts
|
96
106
|
end
|
107
|
+
|
108
|
+
puts "< " + res.line
|
109
|
+
res.headers.each_pair { |k, v| puts "< #{k}: #{v}\r\n" }
|
97
110
|
puts
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
if not content.empty?
|
107
|
-
if /^[[:print:]]+$/ =~ content
|
108
|
-
puts content
|
111
|
+
content = res.content
|
112
|
+
if not content.empty?
|
113
|
+
if /^[[:print:]]+$/ =~ content
|
114
|
+
puts content
|
115
|
+
else
|
116
|
+
puts Hexy.new(content).to_s
|
117
|
+
end
|
118
|
+
end
|
109
119
|
else
|
110
|
-
puts
|
120
|
+
puts "> " + req.method + ' ' + req.url
|
121
|
+
if res
|
122
|
+
text = "< " + res.status.to_s + ' ' + res.message
|
123
|
+
if step.duration
|
124
|
+
text << ' in ' + green(pretty_print_duration(step.duration))
|
125
|
+
end
|
126
|
+
puts text
|
127
|
+
end
|
128
|
+
puts
|
111
129
|
end
|
112
130
|
end
|
113
131
|
end
|
114
132
|
|
115
133
|
def rush args
|
116
134
|
continue = true
|
135
|
+
last_index = nil
|
117
136
|
begin
|
118
137
|
[ 'INT', 'STOP', 'HUP' ].each do |s|
|
119
138
|
trap(s) { continue = false }
|
120
139
|
end
|
121
140
|
job = ::Blitz::Curl::Rush.queue args
|
122
|
-
|
123
|
-
|
124
|
-
header = true
|
141
|
+
msg "rushing from #{yellow(job.region)}..."
|
142
|
+
puts
|
125
143
|
job.result do |result|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
msg "| time (s) | users | hits/sec | kbytes/sec | latency (ms) | errors | timeouts |\n"
|
130
|
-
msg border
|
144
|
+
print_rush_result args, result, last_index
|
145
|
+
if not result.timeline.empty?
|
146
|
+
last_index = result.timeline.size
|
131
147
|
end
|
132
|
-
|
133
|
-
sleep 1.0 if not continue
|
148
|
+
sleep 2.0 if not continue
|
134
149
|
continue
|
135
150
|
end
|
136
|
-
msg border
|
137
151
|
puts
|
138
|
-
msg "[aborted]" if not continue
|
152
|
+
msg "[#{red('aborted')}]" if not continue
|
139
153
|
rescue ::Blitz::Curl::Error::Authorize => e
|
140
154
|
authorize_error e
|
141
155
|
rescue ::Blitz::Curl::Error::Region => e
|
142
|
-
error "#{e.region}: #{e.message}"
|
156
|
+
error "#{yellow(e.region)}: #{red(e.message)}"
|
143
157
|
rescue ::Blitz::Curl::Error => e
|
144
|
-
error e.message
|
158
|
+
error red(e.message)
|
145
159
|
end
|
146
160
|
end
|
147
161
|
|
148
|
-
def print_rush_result result
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
hits_per_second = recent.hits/recent.timestamp
|
159
|
-
kilobytes_per_second = ( ( recent.rxbytes + recent.txbytes )/recent.timestamp ) / 1024
|
162
|
+
def print_rush_result args, result, last_index
|
163
|
+
if last_index.nil?
|
164
|
+
print yellow("%6s " % "Time")
|
165
|
+
print "%6s " % "Users"
|
166
|
+
print green("%8s " % "Hits")
|
167
|
+
print magenta("%8s " % "Timeouts")
|
168
|
+
print red("%8s " % "Errors")
|
169
|
+
print green("%8s " % "Hits/s")
|
170
|
+
print "%s" % "Mbps"
|
171
|
+
puts
|
160
172
|
end
|
161
173
|
|
162
|
-
|
163
|
-
|
164
|
-
output << "%9u " % recent.volume
|
165
|
-
output << "%9u " % hits_per_second
|
166
|
-
output << "%11u " % kilobytes_per_second
|
167
|
-
|
168
|
-
duration = recent.duration * 1000
|
169
|
-
if duration >= 0
|
170
|
-
output << "%13u " % duration
|
171
|
-
else
|
172
|
-
output << "%13s " % 'no data'
|
174
|
+
if last_index and result.timeline.size == last_index
|
175
|
+
return
|
173
176
|
end
|
174
177
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
178
|
+
last = result.timeline[-2]
|
179
|
+
curr = result.timeline[-1]
|
180
|
+
print yellow("%5.1fs " % curr.timestamp)
|
181
|
+
print "%6d " % curr.volume
|
182
|
+
print green("%8d " % curr.hits)
|
183
|
+
print magenta("%8d " % curr.timeouts)
|
184
|
+
print red("%8d " % curr.errors)
|
185
|
+
|
186
|
+
if last
|
187
|
+
elapsed = curr.timestamp - last.timestamp
|
188
|
+
mbps = ((curr.txbytes + curr.rxbytes) - (last.txbytes + last.rxbytes))/elapsed/1024.0/1024.0
|
189
|
+
htps = (curr.hits - last.hits)/elapsed
|
190
|
+
print green(" %7.2f " % htps)
|
191
|
+
print "%.2f" % mbps
|
182
192
|
end
|
183
|
-
|
193
|
+
|
194
|
+
print "\n"
|
184
195
|
end
|
185
196
|
|
186
197
|
def help
|
@@ -217,169 +228,173 @@ class Curl < Command # :nodoc:
|
|
217
228
|
end
|
218
229
|
|
219
230
|
def parse_cli argv
|
220
|
-
hash =
|
221
|
-
|
222
|
-
|
231
|
+
hash = { 'steps' => [] }
|
232
|
+
|
223
233
|
while not argv.empty?
|
224
|
-
|
234
|
+
hash['steps'] << Hash.new
|
235
|
+
step = hash['steps'].last
|
236
|
+
|
237
|
+
while not argv.empty?
|
238
|
+
break if argv.first[0,1] != '-'
|
225
239
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
240
|
+
k = argv.shift
|
241
|
+
if [ '-A', '--user-agent' ].member? k
|
242
|
+
step['user-agent'] = shift(k, argv)
|
243
|
+
next
|
244
|
+
end
|
231
245
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
end
|
246
|
+
if [ '-b', '--cookie' ].member? k
|
247
|
+
step['cookies'] ||= []
|
248
|
+
step['cookies'] << shift(k, argv)
|
249
|
+
next
|
250
|
+
end
|
238
251
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
252
|
+
if [ '-d', '--data' ].member? k
|
253
|
+
step['content'] ||= Hash.new
|
254
|
+
step['content']['data'] ||= []
|
255
|
+
v = shift(k, argv)
|
256
|
+
v = File.read v[1..-1] if v =~ /^@/
|
257
|
+
step['content']['data'] << v
|
258
|
+
next
|
259
|
+
end
|
247
260
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
261
|
+
if [ '-D', '--dump-header' ].member? k
|
262
|
+
hash['dump-header'] = shift(k, argv)
|
263
|
+
next
|
264
|
+
end
|
252
265
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
266
|
+
if [ '-e', '--referer'].member? k
|
267
|
+
step['referer'] = shift(k, argv)
|
268
|
+
next
|
269
|
+
end
|
257
270
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
271
|
+
if [ '-h', '--help' ].member? k
|
272
|
+
hash['help'] = true
|
273
|
+
next
|
274
|
+
end
|
262
275
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
276
|
+
if [ '-H', '--header' ].member? k
|
277
|
+
step['headers'] ||= []
|
278
|
+
step['headers'].push shift(k, argv)
|
279
|
+
next
|
280
|
+
end
|
268
281
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
282
|
+
if [ '-p', '--pattern' ].member? k
|
283
|
+
v = shift(k, argv)
|
284
|
+
v.split(',').each do |vt|
|
285
|
+
unless /^(\d+)-(\d+):(\d+)$/ =~ vt
|
286
|
+
raise Test::Unit::AssertionFailedError, "invalid ramp pattern"
|
287
|
+
end
|
288
|
+
hash['pattern'] ||= { 'iterations' => 1, 'intervals' => [] }
|
289
|
+
hash['pattern']['intervals'] << {
|
290
|
+
'iterations' => 1,
|
291
|
+
'start' => $1.to_i,
|
292
|
+
'end' => $2.to_i,
|
293
|
+
'duration' => $3.to_i
|
294
|
+
}
|
295
|
+
end
|
296
|
+
next
|
273
297
|
end
|
274
|
-
hash['pattern'] = {
|
275
|
-
'iterations' => 1,
|
276
|
-
'intervals' => [{
|
277
|
-
'iterations' => 1,
|
278
|
-
'start' => $1.to_i,
|
279
|
-
'end' => $2.to_i,
|
280
|
-
'duration' => $3.to_i
|
281
|
-
}]
|
282
|
-
}
|
283
|
-
next
|
284
|
-
end
|
285
298
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
299
|
+
if [ '-r', '--region' ].member? k
|
300
|
+
v = shift(k, argv)
|
301
|
+
assert_match(/^california|virginia|singapore|ireland|japan$/, v, 'region must be one of california, virginia, singapore, japan or ireland')
|
302
|
+
hash['region'] = v
|
303
|
+
next
|
304
|
+
end
|
292
305
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
306
|
+
if [ '-s', '--status' ].member? k
|
307
|
+
step['status'] = shift(k, argv).to_i
|
308
|
+
next
|
309
|
+
end
|
297
310
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
311
|
+
if [ '-T', '--timeout' ].member? k
|
312
|
+
step['timeout'] = shift(k, argv).to_i
|
313
|
+
next
|
314
|
+
end
|
302
315
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
316
|
+
if [ '-u', '--user' ].member? k
|
317
|
+
step['user'] = shift(k, argv)
|
318
|
+
next
|
319
|
+
end
|
307
320
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
321
|
+
if [ '-X', '--request' ].member? k
|
322
|
+
step['request'] = shift(k, argv)
|
323
|
+
next
|
324
|
+
end
|
312
325
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
326
|
+
if /-v:(\S+)/ =~ k or /--variable:(\S+)/ =~ k
|
327
|
+
vname = $1
|
328
|
+
vargs = shift(k, argv)
|
329
|
+
|
330
|
+
assert_match /^[a-zA-Z][a-zA-Z0-9]*$/, vname, "variable name must be alphanumeric: #{vname}"
|
331
|
+
|
332
|
+
step['variables'] ||= Hash.new
|
333
|
+
vhash = step['variables'][vname] = Hash.new
|
334
|
+
if vargs.match /^(list)?\[([^\]]+)\]$/
|
335
|
+
vhash['type'] = 'list'
|
336
|
+
vhash['entries'] = $2.split(',')
|
337
|
+
elsif vargs.match /^(a|alpha)$/
|
338
|
+
vhash['type'] = 'alpha'
|
339
|
+
elsif vargs.match /^(a|alpha)\[(\d+),(\d+)(,(\d+))??\]$/
|
340
|
+
vhash['type'] = 'alpha'
|
341
|
+
vhash['min'] = $2.to_i
|
342
|
+
vhash['max'] = $3.to_i
|
343
|
+
vhash['count'] = $5 ? $5.to_i : 1000
|
344
|
+
elsif vargs.match /^(n|number)$/
|
345
|
+
vhash['type'] = 'number'
|
346
|
+
elsif vargs.match /^(n|number)\[(-?\d+),(-?\d+)(,(\d+))?\]$/
|
347
|
+
vhash['type'] = 'number'
|
348
|
+
vhash['min'] = $2.to_i
|
349
|
+
vhash['max'] = $3.to_i
|
350
|
+
vhash['count'] = $5 ? $5.to_i : 1000
|
351
|
+
elsif vargs.match /^(u|udid)$/
|
352
|
+
vhash['type'] = 'udid'
|
353
|
+
else
|
354
|
+
raise ArgumentError, "Invalid variable args for #{vname}: #{vargs}"
|
355
|
+
end
|
356
|
+
next
|
343
357
|
end
|
344
358
|
|
345
|
-
|
346
|
-
|
347
|
-
|
359
|
+
if [ '-V', '--verbose' ].member? k
|
360
|
+
hash['verbose'] = true
|
361
|
+
next
|
362
|
+
end
|
348
363
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
364
|
+
if [ '-1', '--tlsv1' ].member? k
|
365
|
+
step['ssl'] = 'tlsv1'
|
366
|
+
next
|
367
|
+
end
|
353
368
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
369
|
+
if [ '-2', '--sslv2' ].member? k
|
370
|
+
step['ssl'] = 'sslv2'
|
371
|
+
next
|
372
|
+
end
|
358
373
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
374
|
+
if [ '-3', '--sslv3' ].member? k
|
375
|
+
step['ssl'] = 'sslv3'
|
376
|
+
next
|
377
|
+
end
|
363
378
|
|
364
|
-
|
365
|
-
hash['ssl'] = 'sslv3'
|
366
|
-
next
|
379
|
+
raise ArgumentError, "Unknown option #{k}"
|
367
380
|
end
|
368
381
|
|
369
|
-
|
382
|
+
if step.member? 'content'
|
383
|
+
data_size = step['content']['data'].inject(0) { |m, v| m + v.size }
|
384
|
+
assert(data_size < 10*1024, "POST content must be < 10K")
|
385
|
+
end
|
386
|
+
|
387
|
+
break if hash['help']
|
388
|
+
|
389
|
+
url = argv.shift
|
390
|
+
raise ArgumentError, "no URL specified!" if not url
|
391
|
+
step['url'] = url
|
370
392
|
end
|
371
|
-
|
393
|
+
|
372
394
|
if not hash['help']
|
373
|
-
|
374
|
-
if not url
|
395
|
+
if hash['steps'].empty?
|
375
396
|
raise ArgumentError, "no URL specified!"
|
376
397
|
end
|
377
|
-
hash['url'] = url
|
378
|
-
end
|
379
|
-
|
380
|
-
if hash.member? 'content'
|
381
|
-
data_size = hash['content']['data'].inject(0) { |m, v| m + v.size }
|
382
|
-
assert(data_size < 10*1024, "POST content must be < 10K")
|
383
398
|
end
|
384
399
|
|
385
400
|
hash
|