bosh_cli 1.0.3 → 1.5.0.pre.1113

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/bin/bosh +0 -9
  2. data/lib/cli.rb +69 -64
  3. data/lib/cli/backup_destination_path.rb +33 -0
  4. data/lib/cli/base_command.rb +57 -56
  5. data/lib/cli/blob_manager.rb +12 -12
  6. data/lib/cli/changeset_helper.rb +6 -7
  7. data/lib/cli/client/director.rb +724 -0
  8. data/lib/cli/command_handler.rb +6 -7
  9. data/lib/cli/commands/backup.rb +39 -0
  10. data/lib/cli/commands/biff.rb +42 -21
  11. data/lib/cli/commands/blob_management.rb +1 -1
  12. data/lib/cli/commands/cloudcheck.rb +11 -13
  13. data/lib/cli/commands/deployment.rb +53 -37
  14. data/lib/cli/commands/help.rb +3 -2
  15. data/lib/cli/commands/job_management.rb +67 -103
  16. data/lib/cli/commands/job_rename.rb +6 -8
  17. data/lib/cli/commands/log_management.rb +78 -55
  18. data/lib/cli/commands/maintenance.rb +36 -30
  19. data/lib/cli/commands/misc.rb +72 -51
  20. data/lib/cli/commands/package.rb +2 -2
  21. data/lib/cli/commands/property_management.rb +10 -12
  22. data/lib/cli/commands/release.rb +236 -133
  23. data/lib/cli/commands/snapshot.rb +93 -0
  24. data/lib/cli/commands/ssh.rb +216 -213
  25. data/lib/cli/commands/stemcell.rb +46 -34
  26. data/lib/cli/commands/task.rb +2 -2
  27. data/lib/cli/commands/user.rb +27 -3
  28. data/lib/cli/commands/vm.rb +28 -0
  29. data/lib/cli/commands/vms.rb +81 -23
  30. data/lib/cli/config.rb +6 -2
  31. data/lib/cli/core_ext.rb +31 -30
  32. data/lib/cli/deployment_helper.rb +134 -159
  33. data/lib/cli/deployment_manifest.rb +66 -0
  34. data/lib/cli/deployment_manifest_compiler.rb +0 -3
  35. data/lib/cli/event_log_renderer.rb +10 -10
  36. data/lib/cli/file_with_progress_bar.rb +52 -0
  37. data/lib/cli/job_builder.rb +1 -1
  38. data/lib/cli/job_command_args.rb +23 -0
  39. data/lib/cli/job_property_collection.rb +4 -7
  40. data/lib/cli/job_property_validator.rb +22 -12
  41. data/lib/cli/job_state.rb +54 -0
  42. data/lib/cli/line_wrap.rb +54 -0
  43. data/lib/cli/packaging_helper.rb +10 -10
  44. data/lib/cli/release.rb +18 -15
  45. data/lib/cli/release_builder.rb +9 -4
  46. data/lib/cli/release_compiler.rb +9 -9
  47. data/lib/cli/release_tarball.rb +3 -6
  48. data/lib/cli/resurrection.rb +31 -0
  49. data/lib/cli/runner.rb +56 -30
  50. data/lib/cli/stemcell.rb +25 -10
  51. data/lib/cli/task_log_renderer.rb +1 -1
  52. data/lib/cli/task_tracker.rb +10 -9
  53. data/lib/cli/validation.rb +3 -1
  54. data/lib/cli/version.rb +1 -1
  55. data/lib/cli/version_calc.rb +5 -18
  56. data/lib/cli/versions_index.rb +1 -1
  57. data/lib/cli/vm_state.rb +43 -0
  58. data/lib/cli/yaml_helper.rb +26 -35
  59. metadata +75 -208
  60. data/Rakefile +0 -56
  61. data/lib/cli/director.rb +0 -628
  62. data/spec/assets/biff/bad_gateway_config.yml +0 -28
  63. data/spec/assets/biff/good_simple_config.yml +0 -63
  64. data/spec/assets/biff/good_simple_golden_config.yml +0 -63
  65. data/spec/assets/biff/good_simple_template.erb +0 -69
  66. data/spec/assets/biff/ip_out_of_range.yml +0 -63
  67. data/spec/assets/biff/multiple_subnets_config.yml +0 -40
  68. data/spec/assets/biff/network_only_template.erb +0 -34
  69. data/spec/assets/biff/no_cc_config.yml +0 -27
  70. data/spec/assets/biff/no_range_config.yml +0 -27
  71. data/spec/assets/biff/no_subnet_config.yml +0 -16
  72. data/spec/assets/biff/ok_network_config.yml +0 -30
  73. data/spec/assets/biff/properties_template.erb +0 -6
  74. data/spec/assets/config/atmos/config/final.yml +0 -6
  75. data/spec/assets/config/atmos/config/private.yml +0 -4
  76. data/spec/assets/config/bad-providers/config/final.yml +0 -5
  77. data/spec/assets/config/bad-providers/config/private.yml +0 -4
  78. data/spec/assets/config/deprecation/config/final.yml +0 -5
  79. data/spec/assets/config/deprecation/config/private.yml +0 -2
  80. data/spec/assets/config/local/config/final.yml +0 -5
  81. data/spec/assets/config/local/config/private.yml +0 -1
  82. data/spec/assets/config/s3/config/final.yml +0 -5
  83. data/spec/assets/config/s3/config/private.yml +0 -5
  84. data/spec/assets/config/swift-hp/config/final.yml +0 -6
  85. data/spec/assets/config/swift-hp/config/private.yml +0 -7
  86. data/spec/assets/config/swift-rackspace/config/final.yml +0 -6
  87. data/spec/assets/config/swift-rackspace/config/private.yml +0 -6
  88. data/spec/assets/deployment.MF +0 -0
  89. data/spec/assets/plugins/bosh/cli/commands/echo.rb +0 -43
  90. data/spec/assets/plugins/bosh/cli/commands/ruby.rb +0 -24
  91. data/spec/assets/release/jobs/cacher.tgz +0 -0
  92. data/spec/assets/release/jobs/cacher/config/file1.conf +0 -0
  93. data/spec/assets/release/jobs/cacher/config/file2.conf +0 -0
  94. data/spec/assets/release/jobs/cacher/job.MF +0 -6
  95. data/spec/assets/release/jobs/cacher/monit +0 -1
  96. data/spec/assets/release/jobs/cleaner.tgz +0 -0
  97. data/spec/assets/release/jobs/cleaner/job.MF +0 -4
  98. data/spec/assets/release/jobs/cleaner/monit +0 -1
  99. data/spec/assets/release/jobs/sweeper.tgz +0 -0
  100. data/spec/assets/release/jobs/sweeper/config/test.conf +0 -1
  101. data/spec/assets/release/jobs/sweeper/job.MF +0 -5
  102. data/spec/assets/release/jobs/sweeper/monit +0 -1
  103. data/spec/assets/release/packages/mutator.tar.gz +0 -0
  104. data/spec/assets/release/packages/stuff.tgz +0 -0
  105. data/spec/assets/release/release.MF +0 -17
  106. data/spec/assets/release_invalid_checksum.tgz +0 -0
  107. data/spec/assets/release_invalid_jobs.tgz +0 -0
  108. data/spec/assets/release_no_name.tgz +0 -0
  109. data/spec/assets/release_no_version.tgz +0 -0
  110. data/spec/assets/stemcell/image +0 -1
  111. data/spec/assets/stemcell/stemcell.MF +0 -6
  112. data/spec/assets/stemcell_invalid_mf.tgz +0 -0
  113. data/spec/assets/stemcell_no_image.tgz +0 -0
  114. data/spec/assets/valid_release.tgz +0 -0
  115. data/spec/assets/valid_stemcell.tgz +0 -0
  116. data/spec/spec_helper.rb +0 -28
  117. data/spec/unit/base_command_spec.rb +0 -87
  118. data/spec/unit/biff_spec.rb +0 -172
  119. data/spec/unit/blob_manager_spec.rb +0 -288
  120. data/spec/unit/cache_spec.rb +0 -36
  121. data/spec/unit/cli_commands_spec.rb +0 -356
  122. data/spec/unit/config_spec.rb +0 -125
  123. data/spec/unit/core_ext_spec.rb +0 -81
  124. data/spec/unit/dependency_helper_spec.rb +0 -52
  125. data/spec/unit/deployment_manifest_compiler_spec.rb +0 -63
  126. data/spec/unit/deployment_manifest_spec.rb +0 -153
  127. data/spec/unit/director_spec.rb +0 -471
  128. data/spec/unit/director_task_spec.rb +0 -48
  129. data/spec/unit/event_log_renderer_spec.rb +0 -171
  130. data/spec/unit/hash_changeset_spec.rb +0 -73
  131. data/spec/unit/job_builder_spec.rb +0 -455
  132. data/spec/unit/job_property_collection_spec.rb +0 -111
  133. data/spec/unit/job_property_validator_spec.rb +0 -7
  134. data/spec/unit/job_rename_spec.rb +0 -200
  135. data/spec/unit/package_builder_spec.rb +0 -593
  136. data/spec/unit/release_builder_spec.rb +0 -120
  137. data/spec/unit/release_spec.rb +0 -173
  138. data/spec/unit/release_tarball_spec.rb +0 -29
  139. data/spec/unit/runner_spec.rb +0 -7
  140. data/spec/unit/ssh_spec.rb +0 -84
  141. data/spec/unit/stemcell_spec.rb +0 -17
  142. data/spec/unit/task_tracker_spec.rb +0 -131
  143. data/spec/unit/version_calc_spec.rb +0 -27
  144. data/spec/unit/versions_index_spec.rb +0 -144
@@ -1,471 +0,0 @@
1
- # Copyright (c) 2009-2012 VMware, Inc.
2
-
3
- require "spec_helper"
4
-
5
- describe Bosh::Cli::Director do
6
-
7
- DUMMY_TARGET = "http://target"
8
-
9
- before do
10
- @director = Bosh::Cli::Director.new(DUMMY_TARGET, "user", "pass")
11
- end
12
-
13
- describe "fetching status" do
14
- it "tells if user is authenticated" do
15
- @director.should_receive(:get).with("/info", "application/json").
16
- and_return([200, JSON.generate("user" => "adam")])
17
- @director.authenticated?.should == true
18
- end
19
-
20
- it "tells if user not authenticated" do
21
- @director.should_receive(:get).with("/info", "application/json").
22
- and_return([403, "Forbidden"])
23
- @director.authenticated?.should == false
24
-
25
- @director.should_receive(:get).with("/info", "application/json").
26
- and_return([500, "Error"])
27
- @director.authenticated?.should == false
28
-
29
- @director.should_receive(:get).with("/info", "application/json").
30
- and_return([404, "Not Found"])
31
- @director.authenticated?.should == false
32
-
33
- @director.should_receive(:get).with("/info", "application/json").
34
- and_return([200, JSON.generate("user" => nil, "version" => 1)])
35
- @director.authenticated?.should == false
36
-
37
- # Backward compatibility
38
- @director.should_receive(:get).with("/info", "application/json").
39
- and_return([200, JSON.generate("status" => "ZB")])
40
- @director.authenticated?.should == true
41
- end
42
- end
43
-
44
- describe "interface REST API" do
45
- it "has helper methods for HTTP verbs which delegate to generic request" do
46
- [:get, :put, :post, :delete].each do |verb|
47
- @director.should_receive(:request).with(verb, :arg1, :arg2)
48
- @director.send(verb, :arg1, :arg2)
49
- end
50
- end
51
- end
52
-
53
- describe "API calls" do
54
- it "creates user" do
55
- @director.should_receive(:post).
56
- with("/users", "application/json",
57
- JSON.generate("username" => "joe", "password" => "pass")).
58
- and_return(true)
59
- @director.create_user("joe", "pass")
60
- end
61
-
62
- it "uploads stemcell" do
63
- @director.should_receive(:upload_and_track).
64
- with(:post, "/stemcells", "/path",
65
- {:content_type => "application/x-compressed"}).
66
- and_return(true)
67
- @director.upload_stemcell("/path")
68
- end
69
-
70
- it "lists stemcells" do
71
- @director.should_receive(:get).with("/stemcells", "application/json").
72
- and_return([200, JSON.generate([]), {}])
73
- @director.list_stemcells
74
- end
75
-
76
- it "lists releases" do
77
- @director.should_receive(:get).with("/releases", "application/json").
78
- and_return([200, JSON.generate([]), {}])
79
- @director.list_releases
80
- end
81
-
82
- it "lists deployments" do
83
- @director.should_receive(:get).with("/deployments", "application/json").
84
- and_return([200, JSON.generate([]), {}])
85
- @director.list_deployments
86
- end
87
-
88
- it "lists currently running tasks (director version < 0.3.5)" do
89
- @director.should_receive(:get).with("/info", "application/json").
90
- and_return([200, JSON.generate({ :version => "0.3.2"})])
91
- @director.should_receive(:get).
92
- with("/tasks?state=processing", "application/json").
93
- and_return([200, JSON.generate([]), {}])
94
- @director.list_running_tasks
95
- end
96
-
97
- it "lists currently running tasks (director version >= 0.3.5)" do
98
- @director.should_receive(:get).
99
- with("/info", "application/json").
100
- and_return([200, JSON.generate({ :version => "0.3.5"})])
101
- @director.should_receive(:get).
102
- with("/tasks?state=processing,cancelling,queued&verbose=1",
103
- "application/json").
104
- and_return([200, JSON.generate([]), {}])
105
- @director.list_running_tasks
106
- end
107
-
108
- it "lists recent tasks" do
109
- @director.should_receive(:get).
110
- with("/tasks?limit=30&verbose=1", "application/json").
111
- and_return([200, JSON.generate([]), {}])
112
- @director.list_recent_tasks
113
-
114
- @director.should_receive(:get).
115
- with("/tasks?limit=100000&verbose=1", "application/json").
116
- and_return([200, JSON.generate([]), {}])
117
- @director.list_recent_tasks(100000)
118
-
119
- @director.should_receive(:get).
120
- with("/tasks?limit=50&verbose=2", "application/json").
121
- and_return([200, JSON.generate([]), {}])
122
- @director.list_recent_tasks(50, 2)
123
- end
124
-
125
- it "uploads release" do
126
- @director.should_receive(:upload_and_track).
127
- with(:post, "/releases", "/path",
128
- {:content_type => "application/x-compressed"}).
129
- and_return(true)
130
- @director.upload_release("/path")
131
- end
132
-
133
- it "uploads release (with rebase)" do
134
- @director.should_receive(:upload_and_track).
135
- with(:post, "/releases?rebase=true", "/path",
136
- {:content_type => "application/x-compressed"}).
137
- and_return(true)
138
- @director.rebase_release("/path")
139
- end
140
-
141
- it "gets release info" do
142
- @director.should_receive(:get).
143
- with("/releases/foo", "application/json").
144
- and_return([200, JSON.generate([]), { }])
145
- @director.get_release("foo")
146
- end
147
-
148
- it "gets deployment info" do
149
- @director.should_receive(:get).
150
- with("/deployments/foo", "application/json").
151
- and_return([200, JSON.generate([]), { }])
152
- @director.get_deployment("foo")
153
- end
154
-
155
- it "deletes stemcell" do
156
- @director.should_receive(:request_and_track).
157
- with(:delete, "/stemcells/ubuntu/123", {}).and_return(true)
158
- @director.delete_stemcell("ubuntu", "123")
159
- end
160
-
161
- it "deletes deployment" do
162
- @director.should_receive(:request_and_track).
163
- with(:delete, "/deployments/foo", {}).and_return(true)
164
- @director.delete_deployment("foo")
165
- end
166
-
167
- it "deletes release (non-force)" do
168
- @director.should_receive(:request_and_track).
169
- with(:delete, "/releases/za", {}).and_return(true)
170
- @director.delete_release("za")
171
- end
172
-
173
- it "deletes release (force)" do
174
- @director.should_receive(:request_and_track).
175
- with(:delete, "/releases/zb?force=true", {}).and_return(true)
176
- @director.delete_release("zb", :force => true)
177
- end
178
-
179
- it "deploys" do
180
- @director.should_receive(:request_and_track).
181
- with(:post, "/deployments",
182
- {:content_type => "text/yaml", :payload => "manifest"}).
183
- and_return(true)
184
- @director.deploy("manifest")
185
- end
186
-
187
- it "changes job state" do
188
- @director.should_receive(:request_and_track).
189
- with(:put, "/deployments/foo/jobs/dea?state=stopped",
190
- {:content_type => "text/yaml", :payload =>"manifest"}).
191
- and_return(true)
192
- @director.change_job_state("foo", "manifest", "dea", nil, "stopped")
193
- end
194
-
195
- it "changes job instance state" do
196
- @director.should_receive(:request_and_track).
197
- with(:put, "/deployments/foo/jobs/dea/0?state=detached",
198
- {:content_type => "text/yaml", :payload => "manifest"}).
199
- and_return(true)
200
- @director.change_job_state("foo", "manifest", "dea", 0, "detached")
201
- end
202
-
203
- it "gets task state" do
204
- @director.should_receive(:get).
205
- with("/tasks/232").
206
- and_return([200, JSON.generate({ "state" => "done" })])
207
- @director.get_task_state(232).should == "done"
208
- end
209
-
210
- it "whines on missing task" do
211
- @director.should_receive(:get).
212
- with("/tasks/232").
213
- and_return([404, "Not Found"])
214
- lambda {
215
- @director.get_task_state(232).should
216
- }.should raise_error(Bosh::Cli::MissingTask)
217
- end
218
-
219
- it "gets task output" do
220
- @director.should_receive(:get).
221
- with("/tasks/232/output", nil,
222
- nil, { "Range" => "bytes=42-" }).
223
- and_return([206, "test", { :content_range => "bytes 42-56/100" }])
224
- @director.get_task_output(232, 42).should == ["test", 57]
225
- end
226
-
227
- it "doesn't set task output new offset if it wasn't a partial response" do
228
- @director.should_receive(:get).
229
- with("/tasks/232/output", nil, nil,
230
- { "Range" => "bytes=42-" }).
231
- and_return([200, "test"])
232
- @director.get_task_output(232, 42).should == ["test", nil]
233
- end
234
-
235
- it "know how to find time difference with director" do
236
- now = Time.now
237
- server_time = now - 100
238
- Time.stub!(:now).and_return(now)
239
-
240
- @director.should_receive(:get).with("/info").
241
- and_return([200, JSON.generate("version" => 1),
242
- { :date => server_time.rfc822 }])
243
- @director.get_time_difference.to_i.should == 100
244
- end
245
-
246
- end
247
-
248
- describe "checking status" do
249
- it "considers target valid if it responds with 401 (for compatibility)" do
250
- @director.stub(:get).
251
- with("/info", "application/json").
252
- and_return([401, "Not authorized"])
253
- @director.exists?.should be_true
254
- end
255
-
256
- it "considers target valid if it responds with 200" do
257
- @director.stub(:get).
258
- with("/info", "application/json").
259
- and_return([200, JSON.generate("name" => "Director is your friend")])
260
- @director.exists?.should be_true
261
- end
262
- end
263
-
264
- describe "tracking request" do
265
- it "starts polling task if request responded with a redirect to task URL" do
266
- options = { :arg1 => 1, :arg2 => 2 }
267
-
268
- @director.should_receive(:request).
269
- with(:get, "/stuff", "text/plain", "abc").
270
- and_return([302, "body", { :location => "/tasks/502" }])
271
-
272
- tracker = mock("tracker", :track => "polling result", :output => "foo")
273
-
274
- Bosh::Cli::TaskTracker.should_receive(:new).
275
- with(@director, "502", options).
276
- and_return(tracker)
277
-
278
- @director.request_and_track(:get, "/stuff",
279
- {:content_type => "text/plain",
280
- :payload => "abc",
281
- :arg1 => 1, :arg2 => 2
282
- }).
283
- should == ["polling result", "502"]
284
- end
285
-
286
- describe "not tracking trackable requests" do
287
- it "returns without tracking/polling task if request responded with a redirect to task URL" do
288
- options = { :arg1 => 1, :arg2 => 2 }
289
-
290
- @director = Bosh::Cli::Director.new(DUMMY_TARGET, "user", "pass", :no_track => true)
291
-
292
- @director.should_receive(:request).
293
- with(:get, "/stuff", "text/plain", "abc").
294
- and_return([302, "body", { :location => "/tasks/502" }])
295
-
296
- tracker = mock("tracker", :track => "polling result", :output => "foo")
297
-
298
- Bosh::Cli::TaskTracker.should_receive(:new).
299
- with(@director, "502", options).
300
- never
301
-
302
- @director.request_and_track(:get, "/stuff",
303
- {:content_type => "text/plain",
304
- :payload => "abc",
305
- :arg1 => 1, :arg2 => 2
306
- }).
307
- should == [:running, "502"]
308
- end
309
- end
310
-
311
- it "considers all responses but 302 a failure" do
312
- [200, 404, 403].each do |code|
313
- @director.should_receive(:request).
314
- with(:get, "/stuff", "text/plain", "abc").
315
- and_return([code, "body", {}])
316
- @director.request_and_track(:get, "/stuff",
317
- {:content_type => "text/plain",
318
- :payload => "abc",
319
- :arg1 => 1, :arg2 => 2
320
- }).
321
- should == [:failed, nil]
322
- end
323
- end
324
-
325
- it "reports task as non-trackable if its URL is unfamiliar" do
326
- @director.should_receive(:request).
327
- with(:get, "/stuff", "text/plain", "abc").
328
- and_return([302, "body", { :location => "/track-task/502" }])
329
- @director.request_and_track(:get, "/stuff",
330
- {:content_type => "text/plain",
331
- :payload => "abc",
332
- :arg1 => 1, :arg2 => 2
333
- }).
334
- should == [:non_trackable, nil]
335
- end
336
-
337
- it "supports uploading with progress bar" do
338
- file = spec_asset("valid_release.tgz")
339
- f = Bosh::Cli::FileWithProgressBar.open(file, "r")
340
-
341
- Bosh::Cli::FileWithProgressBar.stub!(:open).with(file, "r").and_return(f)
342
- @director.should_receive(:request_and_track).
343
- with(:put, "/stuff", {:content_type => "application/x-compressed",
344
- :payload => f})
345
- @director.upload_and_track(:put, "/stuff", file,
346
- :content_type => "application/x-compressed")
347
- f.progress_bar.finished?.should be_true
348
- end
349
- end
350
-
351
- describe "performing HTTP requests" do
352
- it "delegates to HTTPClient" do
353
- headers = { "Content-Type" => "app/zb", "a" => "b", "c" => "d"}
354
- user = "user"
355
- password = "pass"
356
- auth = "Basic " + Base64.encode64("#{user}:#{password}").strip
357
-
358
- client = mock("httpclient")
359
- client.should_receive(:send_timeout=).
360
- with(Bosh::Cli::Director::API_TIMEOUT)
361
- client.should_receive(:receive_timeout=).
362
- with(Bosh::Cli::Director::API_TIMEOUT)
363
- client.should_receive(:connect_timeout=).
364
- with(Bosh::Cli::Director::CONNECT_TIMEOUT)
365
- HTTPClient.stub!(:new).and_return(client)
366
-
367
- client.should_receive(:request).
368
- with(:get, "http://target/stuff", :body => "payload",
369
- :header => headers.merge("Authorization" => auth))
370
- @director.send(:perform_http_request, :get,
371
- "http://target/stuff", "payload", headers)
372
- end
373
- end
374
-
375
- describe "talking to REST API" do
376
- it "performs HTTP request" do
377
- mock_response = mock("response", :code => 200,
378
- :body => "test", :headers => {})
379
-
380
- @director.should_receive(:perform_http_request).
381
- with(:get, "http://target/stuff", "payload", "h1" => "a",
382
- "h2" => "b", "Content-Type" => "app/zb").
383
- and_return(mock_response)
384
-
385
- @director.request(:get, "/stuff", "app/zb", "payload",
386
- { "h1" => "a", "h2" => "b"}).
387
- should == [200, "test", {}]
388
- end
389
-
390
- it "nicely wraps director error response" do
391
- [400, 403, 500].each do |code|
392
- lambda {
393
- # Familiar JSON
394
- body = JSON.generate("code" => "40422",
395
- "description" => "Weird stuff happened")
396
-
397
- mock_response = mock("response",
398
- :code => code,
399
- :body => body,
400
- :headers => {})
401
-
402
- @director.should_receive(:perform_http_request).
403
- and_return(mock_response)
404
- @director.request(:get, "/stuff", "application/octet-stream",
405
- "payload", { :hdr1 => "a", :hdr2 => "b"})
406
- }.should raise_error(Bosh::Cli::DirectorError,
407
- "Error 40422: Weird stuff happened")
408
-
409
- lambda {
410
- # Not JSON
411
- mock_response = mock("response", :code => code,
412
- :body => "error message goes here",
413
- :headers => {})
414
- @director.should_receive(:perform_http_request).
415
- and_return(mock_response)
416
- @director.request(:get, "/stuff", "application/octet-stream",
417
- "payload", { :hdr1 => "a", :hdr2 => "b"})
418
- }.should raise_error(Bosh::Cli::DirectorError,
419
- "HTTP #{code}: " +
420
- "error message goes here")
421
-
422
- lambda {
423
- # JSON but weird
424
- mock_response = mock("response", :code => code,
425
- :body => '{"c":"d","a":"b"}',
426
- :headers => {})
427
- @director.should_receive(:perform_http_request).
428
- and_return(mock_response)
429
- @director.request(:get, "/stuff", "application/octet-stream",
430
- "payload", { :hdr1 => "a", :hdr2 => "b"})
431
- }.should raise_error(Bosh::Cli::DirectorError,
432
- "HTTP #{code}: " +
433
- %Q[{"c":"d","a":"b"}])
434
- end
435
- end
436
-
437
- it "wraps director access exceptions" do
438
- [URI::Error, SocketError, Errno::ECONNREFUSED].each do |err|
439
- @director.should_receive(:perform_http_request).
440
- and_raise(err.new("err message"))
441
- lambda {
442
- @director.request(:get, "/stuff", "app/zb", "payload", { })
443
- }.should raise_error(Bosh::Cli::DirectorInaccessible)
444
- end
445
-
446
- @director.should_receive(:perform_http_request).
447
- and_raise(SystemCallError.new("err message", 22))
448
-
449
- lambda {
450
- @director.request(:get, "/stuff", "app/zb", "payload", { })
451
- }.should raise_error Bosh::Cli::DirectorError
452
- end
453
-
454
- it "streams file" do
455
- mock_response = mock("response", :code => 200,
456
- :body => "test body", :headers => { })
457
- @director.should_receive(:perform_http_request).
458
- and_yield("test body").and_return(mock_response)
459
-
460
- code, filename, headers =
461
- @director.request(:get,
462
- "/files/foo", nil, nil,
463
- { }, { :file => true })
464
-
465
- code.should == 200
466
- File.read(filename).should == "test body"
467
- headers.should == { }
468
- end
469
- end
470
-
471
- end