bosh_cli 1.0.3 → 1.5.0.pre.1113

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.
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