bosh_cli 0.19.1 → 0.19.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/cli/commands/base.rb +37 -0
- data/lib/cli/commands/cloudcheck.rb +13 -29
- data/lib/cli/commands/deployment.rb +6 -27
- data/lib/cli/commands/job_management.rb +12 -17
- data/lib/cli/commands/job_rename.rb +29 -34
- data/lib/cli/commands/log_management.rb +1 -0
- data/lib/cli/commands/maintenance.rb +2 -2
- data/lib/cli/commands/misc.rb +6 -6
- data/lib/cli/commands/release.rb +33 -34
- data/lib/cli/commands/ssh.rb +4 -3
- data/lib/cli/commands/stemcell.rb +9 -29
- data/lib/cli/config.rb +2 -2
- data/lib/cli/core_ext.rb +4 -1
- data/lib/cli/deployment_helper.rb +1 -1
- data/lib/cli/director.rb +159 -73
- data/lib/cli/event_log_renderer.rb +49 -13
- data/lib/cli/release_compiler.rb +6 -9
- data/lib/cli/release_tarball.rb +10 -5
- data/lib/cli/runner.rb +36 -1
- data/lib/cli/task_log_renderer.rb +1 -1
- data/lib/cli/task_tracker.rb +13 -6
- data/lib/cli/version.rb +1 -1
- data/spec/unit/core_ext_spec.rb +5 -1
- data/spec/unit/director_spec.rb +40 -23
- data/spec/unit/job_rename_spec.rb +4 -0
- data/spec/unit/release_tarball_spec.rb +3 -1
- data/spec/unit/runner_spec.rb +20 -0
- data/spec/unit/task_tracker_spec.rb +0 -27
- metadata +4 -4
@@ -14,6 +14,8 @@ module Bosh::Cli
|
|
14
14
|
def initialize(name)
|
15
15
|
@name = name
|
16
16
|
@progress = 0
|
17
|
+
@start_time = nil
|
18
|
+
@finish_time = nil
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
@@ -28,7 +30,7 @@ module Bosh::Cli
|
|
28
30
|
@out = Bosh::Cli::Config.output || $stdout
|
29
31
|
@out.sync = true
|
30
32
|
@buffer = StringIO.new
|
31
|
-
@progress_bars = {
|
33
|
+
@progress_bars = {}
|
32
34
|
@pos = 0
|
33
35
|
@time_adjustment = 0
|
34
36
|
end
|
@@ -39,10 +41,17 @@ module Bosh::Cli
|
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
42
|
-
def add_event(
|
43
|
-
event = parse_event(
|
44
|
+
def add_event(event_line)
|
45
|
+
event = parse_event(event_line)
|
44
46
|
|
45
47
|
@lock.synchronize do
|
48
|
+
# Handling the special "error" event
|
49
|
+
if event["error"]
|
50
|
+
done_with_stage if @current_stage
|
51
|
+
add_error(event)
|
52
|
+
return
|
53
|
+
end
|
54
|
+
|
46
55
|
# One way to handle old stages is to prevent them
|
47
56
|
# from appearing on screen altogether. That means
|
48
57
|
# that we can always render the current stage only
|
@@ -53,6 +62,7 @@ module Bosh::Cli
|
|
53
62
|
|
54
63
|
tags = event["tags"].is_a?(Array) ? event["tags"] : []
|
55
64
|
stage_header = event["stage"]
|
65
|
+
|
56
66
|
if tags.size > 0
|
57
67
|
stage_header += " " + tags.sort.join(", ").green
|
58
68
|
end
|
@@ -82,6 +92,7 @@ module Bosh::Cli
|
|
82
92
|
@done_tasks = []
|
83
93
|
|
84
94
|
@eta = nil
|
95
|
+
@stage_has_error = false # Error flag
|
85
96
|
# Tracks max_in_flight best guess
|
86
97
|
@tasks_batch_size = 0
|
87
98
|
@batches_count = 0
|
@@ -102,6 +113,19 @@ module Bosh::Cli
|
|
102
113
|
end
|
103
114
|
end
|
104
115
|
|
116
|
+
def add_error(event)
|
117
|
+
error = event["error"] || {}
|
118
|
+
code = error["code"]
|
119
|
+
message = error["message"]
|
120
|
+
|
121
|
+
error = "Error"
|
122
|
+
error += " #{code}" if code
|
123
|
+
error += ": #{message}" if message
|
124
|
+
|
125
|
+
# TODO: add KB article link and maybe cck reference?
|
126
|
+
@buffer.puts("\n" + error.red)
|
127
|
+
end
|
128
|
+
|
105
129
|
def refresh
|
106
130
|
# This is primarily used to refresh timer
|
107
131
|
# without advancing rendering buffer
|
@@ -139,13 +163,19 @@ module Bosh::Cli
|
|
139
163
|
@buffer.print "\n#{@current_stage}\n"
|
140
164
|
end
|
141
165
|
|
142
|
-
def done_with_stage(state =
|
166
|
+
def done_with_stage(state = nil)
|
167
|
+
return unless @in_progress
|
168
|
+
|
143
169
|
if @last_event
|
144
170
|
completion_time = Time.at(@last_event["time"]) rescue Time.now
|
145
171
|
else
|
146
172
|
completion_time = Time.now
|
147
173
|
end
|
148
174
|
|
175
|
+
if state.nil?
|
176
|
+
state = @stage_has_error ? "error" : "done"
|
177
|
+
end
|
178
|
+
|
149
179
|
case state.to_s
|
150
180
|
when "done"
|
151
181
|
progress_bar.title = "Done".green
|
@@ -170,6 +200,8 @@ module Bosh::Cli
|
|
170
200
|
# We have to trust the first event in each stage
|
171
201
|
# to have correct "total" and "current" fields.
|
172
202
|
def append_event(event)
|
203
|
+
validate_event(event)
|
204
|
+
|
173
205
|
progress = 0
|
174
206
|
total = event["total"].to_i
|
175
207
|
|
@@ -242,6 +274,7 @@ module Bosh::Cli
|
|
242
274
|
if event["state"] == "failed"
|
243
275
|
# TODO: truncate?
|
244
276
|
status = [task_name.red, event_data["error"]].compact.join(": ")
|
277
|
+
@stage_has_error = true
|
245
278
|
else
|
246
279
|
status = task_name.yellow
|
247
280
|
end
|
@@ -259,7 +292,7 @@ module Bosh::Cli
|
|
259
292
|
task.progress = progress
|
260
293
|
|
261
294
|
progress_bar.total = total
|
262
|
-
progress_bar.title = @tasks.values.map {|t| t.name }.sort.join(", ")
|
295
|
+
progress_bar.title = @tasks.values.map { |t| t.name }.sort.join(", ")
|
263
296
|
|
264
297
|
progress_bar.current += progress_bar_gain
|
265
298
|
progress_bar.refresh
|
@@ -269,19 +302,22 @@ module Bosh::Cli
|
|
269
302
|
|
270
303
|
def parse_event(event_line)
|
271
304
|
event = JSON.parse(event_line)
|
272
|
-
|
273
|
-
|
274
|
-
event["index"] && event["total"] && event["state"]
|
275
|
-
event
|
276
|
-
else
|
277
|
-
raise InvalidEvent, "Invalid event structure: stage, time, task, " +
|
278
|
-
"index, total, state are all required"
|
305
|
+
unless event.kind_of?(Hash)
|
306
|
+
raise InvalidEvent, "Hash expected, #{event.class} given"
|
279
307
|
end
|
280
|
-
|
308
|
+
event
|
281
309
|
rescue JSON::JSONError
|
282
310
|
raise InvalidEvent, "Cannot parse event, invalid JSON"
|
283
311
|
end
|
284
312
|
|
313
|
+
def validate_event(event)
|
314
|
+
unless event["time"] && event["stage"] && event["task"] &&
|
315
|
+
event["index"] && event["total"] && event["state"]
|
316
|
+
raise InvalidEvent, "Invalid event structure: stage, time, task, " +
|
317
|
+
"index, total, state are all required"
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
285
321
|
# Expects time and eta to be adjusted
|
286
322
|
def time_with_eta(time, eta)
|
287
323
|
time_fmt = format_time(time)
|
data/lib/cli/release_compiler.rb
CHANGED
@@ -10,13 +10,14 @@ module Bosh::Cli
|
|
10
10
|
new(manifest_file, blobstore).compile
|
11
11
|
end
|
12
12
|
|
13
|
-
def initialize(manifest_file, blobstore,
|
14
|
-
|
13
|
+
def initialize(manifest_file, blobstore, remote_jobs = nil,
|
14
|
+
remote_packages_sha1 = [], release_dir = nil)
|
15
15
|
@build_dir = Dir.mktmpdir
|
16
16
|
@jobs_dir = File.join(@build_dir, "jobs")
|
17
17
|
@packages_dir = File.join(@build_dir, "packages")
|
18
18
|
@blobstore = blobstore
|
19
19
|
@release_dir = release_dir || Dir.pwd
|
20
|
+
@remote_packages_sha1 = remote_packages_sha1
|
20
21
|
|
21
22
|
at_exit { FileUtils.rm_rf(@build_dir) }
|
22
23
|
|
@@ -26,15 +27,11 @@ module Bosh::Cli
|
|
26
27
|
@manifest_file = File.expand_path(manifest_file, @release_dir)
|
27
28
|
@manifest = load_yaml_file(manifest_file)
|
28
29
|
|
29
|
-
if
|
30
|
-
@
|
31
|
-
OpenStruct.new(pkg)
|
32
|
-
end
|
33
|
-
@remote_jobs = remote_release["jobs"].map do |job|
|
30
|
+
if remote_jobs
|
31
|
+
@remote_jobs = remote_jobs.map do |job|
|
34
32
|
OpenStruct.new(job)
|
35
33
|
end
|
36
34
|
else
|
37
|
-
@remote_packages = []
|
38
35
|
@remote_jobs = []
|
39
36
|
end
|
40
37
|
|
@@ -56,7 +53,7 @@ module Bosh::Cli
|
|
56
53
|
header("Copying packages")
|
57
54
|
@packages.each do |package|
|
58
55
|
say("#{package.name} (#{package.version})".ljust(30), " ")
|
59
|
-
if
|
56
|
+
if @remote_packages_sha1.any? { |sha1| sha1 == package.sha1 }
|
60
57
|
say("SKIP".yellow)
|
61
58
|
next
|
62
59
|
end
|
data/lib/cli/release_tarball.rb
CHANGED
@@ -24,11 +24,19 @@ module Bosh::Cli
|
|
24
24
|
File.exists?(@tarball_path) && File.readable?(@tarball_path)
|
25
25
|
end
|
26
26
|
|
27
|
+
def manifest
|
28
|
+
return nil unless valid?
|
29
|
+
unpack
|
30
|
+
File.read(File.join(@unpack_dir, "release.MF"))
|
31
|
+
end
|
32
|
+
|
27
33
|
# Repacks tarball according to the structure of remote release
|
28
34
|
# Return path to repackaged tarball or nil if repack has failed
|
29
|
-
def repack(
|
35
|
+
def repack(remote_jobs = nil, remote_packages_sha1 = nil)
|
30
36
|
return nil unless valid?
|
31
37
|
unpack
|
38
|
+
remote_jobs ||= []
|
39
|
+
remote_packages_sha1 ||= []
|
32
40
|
|
33
41
|
tmpdir = Dir.mktmpdir
|
34
42
|
repacked_path = File.join(tmpdir, "release-repack.tgz")
|
@@ -39,16 +47,13 @@ module Bosh::Cli
|
|
39
47
|
|
40
48
|
local_packages = manifest["packages"]
|
41
49
|
local_jobs = manifest["jobs"]
|
42
|
-
remote_packages = remote_release["packages"]
|
43
|
-
remote_jobs = remote_release["jobs"]
|
44
50
|
|
45
51
|
@skipped = 0
|
46
52
|
|
47
53
|
Dir.chdir(@unpack_dir) do
|
48
54
|
local_packages.each do |package|
|
49
55
|
say("#{package['name']} (#{package['version']})".ljust(30), " ")
|
50
|
-
if
|
51
|
-
package["version"].to_s == rp["version"].to_s }
|
56
|
+
if remote_packages_sha1.any? { |sha1| sha1 == package["sha1"] }
|
52
57
|
say("SKIP".green)
|
53
58
|
@skipped += 1
|
54
59
|
FileUtils.rm_rf(File.join("packages", "#{package['name']}.tgz"))
|
data/lib/cli/runner.rb
CHANGED
@@ -25,7 +25,6 @@ module Bosh::Cli
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def initialize(args)
|
28
|
-
define_commands
|
29
28
|
@args = args
|
30
29
|
@options = {
|
31
30
|
:director_checks => true,
|
@@ -68,9 +67,18 @@ module Bosh::Cli
|
|
68
67
|
end
|
69
68
|
|
70
69
|
runner.send(@action.to_sym, *@args)
|
70
|
+
exit(runner.exit_code)
|
71
71
|
elsif @args.empty? || @args == %w(help)
|
72
72
|
say(help_message)
|
73
73
|
say(plugin_help_message) if @plugins
|
74
|
+
elsif @args[0] == "complete"
|
75
|
+
unless ENV.has_key?('COMP_LINE')
|
76
|
+
$stderr.puts "COMP_LINE must be set when calling bosh complete"
|
77
|
+
exit(1)
|
78
|
+
end
|
79
|
+
line = ENV['COMP_LINE'].gsub(/^\S*bosh\s*/, '')
|
80
|
+
puts complete(line).join("\n")
|
81
|
+
exit(0)
|
74
82
|
elsif @args[0] == "help"
|
75
83
|
cmd_args = @args[1..-1]
|
76
84
|
suggestions = command_suggestions(cmd_args).map do |cmd|
|
@@ -116,6 +124,33 @@ module Bosh::Cli
|
|
116
124
|
end
|
117
125
|
end
|
118
126
|
|
127
|
+
# looks for command completion in the parse tree
|
128
|
+
def parse_tree_completion(node, words, index)
|
129
|
+
word = words[index]
|
130
|
+
|
131
|
+
# exact match and not on the last word
|
132
|
+
if node[word] && words.length != index
|
133
|
+
parse_tree_completion(node[word], words, index + 1)
|
134
|
+
|
135
|
+
# exact match at the last word
|
136
|
+
elsif node[word]
|
137
|
+
node[word].values
|
138
|
+
|
139
|
+
# find all partial matches
|
140
|
+
else
|
141
|
+
node.keys.grep(/^#{word}/)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# for use with:
|
146
|
+
# complete -C 'bosh complete' bosh
|
147
|
+
# @param [String] command line (minus "bosh")
|
148
|
+
# @return [Array]
|
149
|
+
def complete(line)
|
150
|
+
words = line.split(/\s+/)
|
151
|
+
parse_tree_completion(@parse_tree, words, 0)
|
152
|
+
end
|
153
|
+
|
119
154
|
def command(name, &block)
|
120
155
|
cmd_def = CommandDefinition.new
|
121
156
|
cmd_def.instance_eval(&block)
|
@@ -6,7 +6,7 @@ module Bosh::Cli
|
|
6
6
|
def self.create_for_log_type(log_type)
|
7
7
|
if log_type == "event"
|
8
8
|
EventLogRenderer.new
|
9
|
-
elsif log_type == "result"
|
9
|
+
elsif log_type == "result" || log_type == "none"
|
10
10
|
# Null renderer doesn't output anything to screen, so it fits well
|
11
11
|
# in case we need to fetch task result log only, without rendering it
|
12
12
|
NullRenderer.new
|
data/lib/cli/task_tracker.rb
CHANGED
@@ -18,7 +18,10 @@ module Bosh
|
|
18
18
|
@task_id = task_id
|
19
19
|
@options = options
|
20
20
|
|
21
|
-
@
|
21
|
+
@quiet = !!options[:quiet]
|
22
|
+
default_log_type = @quiet ? "none" : "event"
|
23
|
+
|
24
|
+
@log_type = options[:log_type] || default_log_type
|
22
25
|
@use_cache = options.key?(:use_cache) ? @options[:use_cache] : true
|
23
26
|
|
24
27
|
@output = nil
|
@@ -51,11 +54,7 @@ module Bosh
|
|
51
54
|
task_status = poll
|
52
55
|
end
|
53
56
|
|
54
|
-
|
55
|
-
prompt_for_debug_log
|
56
|
-
else
|
57
|
-
print_task_summary(task_status)
|
58
|
-
end
|
57
|
+
print_task_summary(task_status)
|
59
58
|
|
60
59
|
save_task_output unless cached_output
|
61
60
|
task_status
|
@@ -133,6 +132,14 @@ module Bosh
|
|
133
132
|
|
134
133
|
private
|
135
134
|
|
135
|
+
def nl
|
136
|
+
super unless @quiet
|
137
|
+
end
|
138
|
+
|
139
|
+
def say(*args)
|
140
|
+
super unless @quiet
|
141
|
+
end
|
142
|
+
|
136
143
|
# @param [String] output Output received from director task
|
137
144
|
def output_received(output)
|
138
145
|
return if output.nil?
|
data/lib/cli/version.rb
CHANGED
data/spec/unit/core_ext_spec.rb
CHANGED
@@ -24,7 +24,7 @@ describe String do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
it "has colorization helpers" do
|
27
|
+
it "has colorization helpers (but only if tty)" do
|
28
28
|
Bosh::Cli::Config.colorize = false
|
29
29
|
"string".red.should == "string"
|
30
30
|
"string".green.should == "string"
|
@@ -32,10 +32,14 @@ describe String do
|
|
32
32
|
"string".colorize(:green).should == "string"
|
33
33
|
|
34
34
|
Bosh::Cli::Config.colorize = true
|
35
|
+
Bosh::Cli::Config.output.stub(:tty?).and_return(true)
|
35
36
|
"string".red.should == "\e[0m\e[31mstring\e[0m"
|
36
37
|
"string".green.should == "\e[0m\e[32mstring\e[0m"
|
37
38
|
"string".colorize("a").should == "string"
|
38
39
|
"string".colorize(:green).should == "\e[0m\e[32mstring\e[0m"
|
40
|
+
|
41
|
+
Bosh::Cli::Config.output.stub(:tty?).and_return(false)
|
42
|
+
"string".green.should == "string"
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
data/spec/unit/director_spec.rb
CHANGED
@@ -61,7 +61,8 @@ describe Bosh::Cli::Director do
|
|
61
61
|
|
62
62
|
it "uploads stemcell" do
|
63
63
|
@director.should_receive(:upload_and_track).
|
64
|
-
with(
|
64
|
+
with(:post, "/stemcells", "/path",
|
65
|
+
{:content_type => "application/x-compressed"}).
|
65
66
|
and_return(true)
|
66
67
|
@director.upload_stemcell("/path")
|
67
68
|
end
|
@@ -117,7 +118,8 @@ describe Bosh::Cli::Director do
|
|
117
118
|
|
118
119
|
it "uploads release" do
|
119
120
|
@director.should_receive(:upload_and_track).
|
120
|
-
with(
|
121
|
+
with(:post, "/releases", "/path",
|
122
|
+
{:content_type => "application/x-compressed"}).
|
121
123
|
and_return(true)
|
122
124
|
@director.upload_release("/path")
|
123
125
|
end
|
@@ -138,45 +140,49 @@ describe Bosh::Cli::Director do
|
|
138
140
|
|
139
141
|
it "deletes stemcell" do
|
140
142
|
@director.should_receive(:request_and_track).
|
141
|
-
with(:delete, "/stemcells/ubuntu/123").and_return(true)
|
143
|
+
with(:delete, "/stemcells/ubuntu/123", {}).and_return(true)
|
142
144
|
@director.delete_stemcell("ubuntu", "123")
|
143
145
|
end
|
144
146
|
|
145
147
|
it "deletes deployment" do
|
146
148
|
@director.should_receive(:request_and_track).
|
147
|
-
with(:delete, "/deployments/foo").and_return(true)
|
149
|
+
with(:delete, "/deployments/foo", {}).and_return(true)
|
148
150
|
@director.delete_deployment("foo")
|
149
151
|
end
|
150
152
|
|
151
153
|
it "deletes release (non-force)" do
|
152
154
|
@director.should_receive(:request_and_track).
|
153
|
-
with(:delete, "/releases/za").and_return(true)
|
155
|
+
with(:delete, "/releases/za", {}).and_return(true)
|
154
156
|
@director.delete_release("za")
|
155
157
|
end
|
156
158
|
|
157
159
|
it "deletes release (force)" do
|
158
160
|
@director.should_receive(:request_and_track).
|
159
|
-
with(:delete, "/releases/zb?force=true").and_return(true)
|
161
|
+
with(:delete, "/releases/zb?force=true", {}).and_return(true)
|
160
162
|
@director.delete_release("zb", :force => true)
|
161
163
|
end
|
162
164
|
|
163
165
|
it "deploys" do
|
164
166
|
@director.should_receive(:request_and_track).
|
165
|
-
with(:post, "/deployments",
|
167
|
+
with(:post, "/deployments",
|
168
|
+
{:content_type => "text/yaml", :payload => "manifest"}).
|
169
|
+
and_return(true)
|
166
170
|
@director.deploy("manifest")
|
167
171
|
end
|
168
172
|
|
169
173
|
it "changes job state" do
|
170
174
|
@director.should_receive(:request_and_track).
|
171
175
|
with(:put, "/deployments/foo/jobs/dea?state=stopped",
|
172
|
-
"text/yaml", "manifest").
|
176
|
+
{:content_type => "text/yaml", :payload =>"manifest"}).
|
177
|
+
and_return(true)
|
173
178
|
@director.change_job_state("foo", "manifest", "dea", nil, "stopped")
|
174
179
|
end
|
175
180
|
|
176
181
|
it "changes job instance state" do
|
177
182
|
@director.should_receive(:request_and_track).
|
178
183
|
with(:put, "/deployments/foo/jobs/dea/0?state=detached",
|
179
|
-
"text/yaml", "manifest").
|
184
|
+
{:content_type => "text/yaml", :payload => "manifest"}).
|
185
|
+
and_return(true)
|
180
186
|
@director.change_job_state("foo", "manifest", "dea", 0, "detached")
|
181
187
|
end
|
182
188
|
|
@@ -255,9 +261,12 @@ describe Bosh::Cli::Director do
|
|
255
261
|
with(@director, "502", options).
|
256
262
|
and_return(tracker)
|
257
263
|
|
258
|
-
@director.request_and_track(:get, "/stuff",
|
259
|
-
"
|
260
|
-
|
264
|
+
@director.request_and_track(:get, "/stuff",
|
265
|
+
{:content_type => "text/plain",
|
266
|
+
:payload => "abc",
|
267
|
+
:arg1 => 1, :arg2 => 2
|
268
|
+
}).
|
269
|
+
should == ["polling result", "502"]
|
261
270
|
end
|
262
271
|
|
263
272
|
it "considers all responses but 302 a failure" do
|
@@ -265,9 +274,12 @@ describe Bosh::Cli::Director do
|
|
265
274
|
@director.should_receive(:request).
|
266
275
|
with(:get, "/stuff", "text/plain", "abc").
|
267
276
|
and_return([code, "body", {}])
|
268
|
-
@director.request_and_track(:get, "/stuff",
|
269
|
-
|
270
|
-
|
277
|
+
@director.request_and_track(:get, "/stuff",
|
278
|
+
{:content_type => "text/plain",
|
279
|
+
:payload => "abc",
|
280
|
+
:arg1 => 1, :arg2 => 2
|
281
|
+
}).
|
282
|
+
should == [:failed, nil]
|
271
283
|
end
|
272
284
|
end
|
273
285
|
|
@@ -275,9 +287,12 @@ describe Bosh::Cli::Director do
|
|
275
287
|
@director.should_receive(:request).
|
276
288
|
with(:get, "/stuff", "text/plain", "abc").
|
277
289
|
and_return([302, "body", { :location => "/track-task/502" }])
|
278
|
-
@director.request_and_track(:get, "/stuff",
|
279
|
-
|
280
|
-
|
290
|
+
@director.request_and_track(:get, "/stuff",
|
291
|
+
{:content_type => "text/plain",
|
292
|
+
:payload => "abc",
|
293
|
+
:arg1 => 1, :arg2 => 2
|
294
|
+
}).
|
295
|
+
should == [:non_trackable, nil]
|
281
296
|
end
|
282
297
|
|
283
298
|
it "supports uploading with progress bar" do
|
@@ -286,8 +301,10 @@ describe Bosh::Cli::Director do
|
|
286
301
|
|
287
302
|
Bosh::Cli::FileWithProgressBar.stub!(:open).with(file, "r").and_return(f)
|
288
303
|
@director.should_receive(:request_and_track).
|
289
|
-
with(:
|
290
|
-
|
304
|
+
with(:put, "/stuff", {:content_type => "application/x-compressed",
|
305
|
+
:payload => f})
|
306
|
+
@director.upload_and_track(:put, "/stuff", file,
|
307
|
+
:content_type => "application/x-compressed")
|
291
308
|
f.progress_bar.finished?.should be_true
|
292
309
|
end
|
293
310
|
end
|
@@ -348,7 +365,7 @@ describe Bosh::Cli::Director do
|
|
348
365
|
@director.request(:get, "/stuff", "application/octet-stream",
|
349
366
|
"payload", { :hdr1 => "a", :hdr2 => "b"})
|
350
367
|
}.should raise_error(Bosh::Cli::DirectorError,
|
351
|
-
"
|
368
|
+
"Error 40422: Weird stuff happened")
|
352
369
|
|
353
370
|
lambda {
|
354
371
|
# Not JSON
|
@@ -360,7 +377,7 @@ describe Bosh::Cli::Director do
|
|
360
377
|
@director.request(:get, "/stuff", "application/octet-stream",
|
361
378
|
"payload", { :hdr1 => "a", :hdr2 => "b"})
|
362
379
|
}.should raise_error(Bosh::Cli::DirectorError,
|
363
|
-
"
|
380
|
+
"HTTP #{code}: " +
|
364
381
|
"error message goes here")
|
365
382
|
|
366
383
|
lambda {
|
@@ -373,7 +390,7 @@ describe Bosh::Cli::Director do
|
|
373
390
|
@director.request(:get, "/stuff", "application/octet-stream",
|
374
391
|
"payload", { :hdr1 => "a", :hdr2 => "b"})
|
375
392
|
}.should raise_error(Bosh::Cli::DirectorError,
|
376
|
-
"
|
393
|
+
"HTTP #{code}: " +
|
377
394
|
%Q[{"c":"d","a":"b"}])
|
378
395
|
end
|
379
396
|
end
|