aws-codedeploy-agent 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGES.md +3 -0
  3. data/Gemfile +13 -0
  4. data/LICENSE +177 -0
  5. data/NOTICE +2 -0
  6. data/README.md +16 -0
  7. data/aws-codedeploy-agent.gemspec +39 -0
  8. data/bin/codedeploy-agent +78 -0
  9. data/bin/codedeploy-install +15 -0
  10. data/bin/codedeploy-uninstall +13 -0
  11. data/certs/host-agent-deployment-signer-ca-chain.pem +76 -0
  12. data/conf/codedeployagent.yml +9 -0
  13. data/init.d/codedeploy-agent +61 -0
  14. data/lib/core_ext.rb +71 -0
  15. data/lib/instance_agent.rb +35 -0
  16. data/lib/instance_agent/agent/base.rb +34 -0
  17. data/lib/instance_agent/codedeploy_plugin/application_specification/ace_info.rb +133 -0
  18. data/lib/instance_agent/codedeploy_plugin/application_specification/acl_info.rb +163 -0
  19. data/lib/instance_agent/codedeploy_plugin/application_specification/application_specification.rb +142 -0
  20. data/lib/instance_agent/codedeploy_plugin/application_specification/context_info.rb +23 -0
  21. data/lib/instance_agent/codedeploy_plugin/application_specification/file_info.rb +23 -0
  22. data/lib/instance_agent/codedeploy_plugin/application_specification/linux_permission_info.rb +121 -0
  23. data/lib/instance_agent/codedeploy_plugin/application_specification/mode_info.rb +66 -0
  24. data/lib/instance_agent/codedeploy_plugin/application_specification/range_info.rb +134 -0
  25. data/lib/instance_agent/codedeploy_plugin/application_specification/script_info.rb +27 -0
  26. data/lib/instance_agent/codedeploy_plugin/codedeploy_control.rb +72 -0
  27. data/lib/instance_agent/codedeploy_plugin/command_executor.rb +357 -0
  28. data/lib/instance_agent/codedeploy_plugin/command_poller.rb +146 -0
  29. data/lib/instance_agent/codedeploy_plugin/deployment_specification.rb +150 -0
  30. data/lib/instance_agent/codedeploy_plugin/hook_executor.rb +206 -0
  31. data/lib/instance_agent/codedeploy_plugin/install_instruction.rb +374 -0
  32. data/lib/instance_agent/codedeploy_plugin/installer.rb +143 -0
  33. data/lib/instance_agent/codedeploy_plugin/request_helper.rb +28 -0
  34. data/lib/instance_agent/config.rb +43 -0
  35. data/lib/instance_agent/log.rb +3 -0
  36. data/lib/instance_agent/platform.rb +17 -0
  37. data/lib/instance_agent/platform/linux_util.rb +57 -0
  38. data/lib/instance_agent/runner/child.rb +57 -0
  39. data/lib/instance_agent/runner/master.rb +103 -0
  40. data/lib/instance_metadata.rb +47 -0
  41. data/test/certificate_helper.rb +120 -0
  42. data/test/helpers/instance_agent_helper.rb +25 -0
  43. data/test/instance_agent/agent/base_test.rb +49 -0
  44. data/test/instance_agent/codedeploy_plugin/application_specification_test.rb +1710 -0
  45. data/test/instance_agent/codedeploy_plugin/codedeploy_control_test.rb +51 -0
  46. data/test/instance_agent/codedeploy_plugin/command_executor_test.rb +513 -0
  47. data/test/instance_agent/codedeploy_plugin/command_poller_test.rb +459 -0
  48. data/test/instance_agent/codedeploy_plugin/deployment_specification_test.rb +335 -0
  49. data/test/instance_agent/codedeploy_plugin/hook_executor_test.rb +250 -0
  50. data/test/instance_agent/codedeploy_plugin/install_instruction_test.rb +566 -0
  51. data/test/instance_agent/codedeploy_plugin/installer_test.rb +519 -0
  52. data/test/instance_agent/codedeploy_plugin/request_helper_test.rb +37 -0
  53. data/test/instance_agent/config_test.rb +64 -0
  54. data/test/instance_agent/runner/child_test.rb +87 -0
  55. data/test/instance_metadata_test.rb +97 -0
  56. data/test/test_helper.rb +16 -0
  57. data/vendor/gems/.codedeploy-commands-1.0.0.created.rid +1 -0
  58. data/vendor/gems/codedeploy-commands/apis/CodeDeployCommand.api.json +372 -0
  59. data/vendor/gems/codedeploy-commands/codedeploy-commands-1.0.0.gemspec +28 -0
  60. data/vendor/gems/codedeploy-commands/lib/aws/codedeploy_commands.rb +18 -0
  61. data/vendor/gems/codedeploy-commands/lib/aws/plugins/certificate_authority.rb +12 -0
  62. data/vendor/gems/codedeploy-commands/lib/aws/plugins/deploy_control_endpoint.rb +22 -0
  63. data/vendor/gems/process_manager/README.md +1 -0
  64. data/vendor/gems/process_manager/lib/blank.rb +153 -0
  65. data/vendor/gems/process_manager/lib/core_ext.rb +73 -0
  66. data/vendor/gems/process_manager/lib/process_manager.rb +49 -0
  67. data/vendor/gems/process_manager/lib/process_manager/child.rb +119 -0
  68. data/vendor/gems/process_manager/lib/process_manager/config.rb +112 -0
  69. data/vendor/gems/process_manager/lib/process_manager/log.rb +107 -0
  70. data/vendor/gems/process_manager/lib/process_manager/master.rb +322 -0
  71. data/vendor/gems/process_manager/process_manager-0.0.13.gemspec +42 -0
  72. data/vendor/specifications/aws-sdk-core-2.0.5.gemspec +39 -0
  73. data/vendor/specifications/builder-3.2.2.gemspec +29 -0
  74. data/vendor/specifications/codedeploy-commands-1.0.0.gemspec +28 -0
  75. data/vendor/specifications/gli-2.5.6.gemspec +51 -0
  76. data/vendor/specifications/jamespath-0.5.1.gemspec +35 -0
  77. data/vendor/specifications/little-plugger-1.1.3.gemspec +32 -0
  78. data/vendor/specifications/logging-1.8.1.gemspec +44 -0
  79. data/vendor/specifications/multi_json-1.7.7.gemspec +30 -0
  80. data/vendor/specifications/multi_json-1.8.4.gemspec +30 -0
  81. data/vendor/specifications/multi_xml-0.5.5.gemspec +30 -0
  82. data/vendor/specifications/process_manager-0.0.13.gemspec +42 -0
  83. data/vendor/specifications/simple_pid-0.2.1.gemspec +28 -0
  84. metadata +377 -0
@@ -0,0 +1,519 @@
1
+ require 'test_helper'
2
+ require 'instance_agent/codedeploy_plugin/installer'
3
+
4
+ class CodeDeployPluginInstallerTest < InstanceAgentTestCase
5
+
6
+ include InstanceAgent::CodeDeployPlugin
7
+
8
+ context "The CodeDeploy Plugin's file installer" do
9
+
10
+ setup do
11
+ @app_spec = mock("app spec")
12
+ @deployment_archive_dir = "deploy-archive-dir"
13
+ @deployment_instructions_dir = "deploy-instructions-dir"
14
+ @deployment_group_id = "ig1"
15
+ @installer =
16
+ Installer.new(:deployment_archive_dir => @deployment_archive_dir,
17
+ :deployment_instructions_dir => @deployment_instructions_dir)
18
+ end
19
+
20
+ context "when initializing" do
21
+
22
+ should "require a deployment archive directory" do
23
+ assert_raise { Installer.new(:deployment_instructions_dir => "otherdir") }
24
+ end
25
+
26
+ should "require a deployment instructions directory" do
27
+ assert_raise { Installer.new(:deployment_archive_dir => "somedir") }
28
+ end
29
+
30
+ end
31
+
32
+ context "deployment archive directory getter" do
33
+ should "return the deployment archive directory from the initializer" do
34
+ assert_equal(@deployment_archive_dir, @installer.deployment_archive_dir)
35
+ end
36
+ end
37
+
38
+ context "deployment instructions directory getter" do
39
+ should "return the deployment instructions directory from the initializer" do
40
+ assert_equal(@deployment_instructions_dir, @installer.deployment_instructions_dir)
41
+ end
42
+ end
43
+
44
+ context "installing" do
45
+
46
+ setup do
47
+ @instruction_builder = mock("instruction builder")
48
+
49
+ InstallInstruction
50
+ .stubs(:generate_instructions)
51
+ .yields(@instruction_builder)
52
+ .returns([])
53
+
54
+ File.stubs(:exists?).returns(false)
55
+ File.stubs(:exists?).with("deploy-instructions-dir/ig1-cleanup").returns(false)
56
+
57
+ @app_spec.stubs(:permissions).returns([])
58
+ @app_spec.stubs(:files).returns([])
59
+
60
+ File.stubs(:open)
61
+ end
62
+
63
+ context "with an existing cleanup file" do
64
+
65
+ setup do
66
+ File.stubs(:exists?).with("deploy-instructions-dir/ig1-cleanup").returns(true)
67
+ end
68
+
69
+ should "parse the file, execute the commands and remove the file before generating new install instructions" do
70
+ File.stubs(:read).with("deploy-instructions-dir/ig1-cleanup").returns("CLEANUP!")
71
+
72
+ call_sequence = sequence("call sequence")
73
+ cleanup_commands = [mock("first"),
74
+ mock("second")]
75
+ InstallInstruction
76
+ .stubs(:parse_remove_commands)
77
+ .with("CLEANUP!")
78
+ .returns(cleanup_commands)
79
+
80
+ cleanup_commands.each do |cmd|
81
+ cmd.expects(:execute).in_sequence(call_sequence)
82
+ end
83
+
84
+ FileUtils
85
+ .expects(:rm)
86
+ .with("deploy-instructions-dir/ig1-cleanup")
87
+ .in_sequence(call_sequence)
88
+
89
+ InstallInstruction
90
+ .expects(:generate_instructions)
91
+ .returns([])
92
+ .in_sequence(call_sequence)
93
+
94
+ @installer.install(@deployment_group_id, @app_spec)
95
+ end
96
+
97
+ end
98
+
99
+ context "no files to install" do
100
+
101
+ should "generate an empty install instructions file" do
102
+ @app_spec.stubs(:files).returns([])
103
+ @instruction_builder.expects(:copy).never
104
+ @instruction_builder.expects(:mkdir).never
105
+
106
+ @installer.install(@deployment_group_id, @app_spec)
107
+ end
108
+
109
+ end
110
+
111
+ context "files to install" do
112
+
113
+ context "regular files" do
114
+
115
+ setup do
116
+ @app_spec
117
+ .stubs(:files)
118
+ .returns([stub(:source => "src1",
119
+ :destination => "dst1"),
120
+ stub(:source => "src2",
121
+ :destination => "dst2")])
122
+
123
+ File.stubs(:directory?).returns(false)
124
+ File.stubs(:exists?).returns(false)
125
+ File.stubs(:exists?).with(any_of("dst1", "dst2")).returns(true)
126
+ @instruction_builder.stubs(:copy)
127
+ end
128
+
129
+ should "generate an entry for each file" do
130
+ @instruction_builder
131
+ .expects(:copy)
132
+ .with("deploy-archive-dir/src1", "dst1/src1")
133
+ @instruction_builder
134
+ .expects(:copy)
135
+ .with("deploy-archive-dir/src2", "dst2/src2")
136
+
137
+ @installer.install(@deployment_group_id, @app_spec)
138
+ end
139
+
140
+ should "raise an error if the file already exists" do
141
+ File.stubs(:exists?).with("dst2/src2").returns(true)
142
+
143
+ assert_raised_with_message("File already exists at location dst2/src2") do
144
+ @installer.install(@deployment_group_id, @app_spec)
145
+ end
146
+ end
147
+
148
+ should "generate a mkdir command if the destination directory does not exist" do
149
+ @app_spec
150
+ .stubs(:files)
151
+ .returns([stub(:source => "src1",
152
+ :destination => "dst1")])
153
+ File.stubs(:exists?).with("dst1").returns(false)
154
+
155
+ command_sequence = sequence("command sequence")
156
+ @instruction_builder
157
+ .expects(:mkdir)
158
+ .with("dst1")
159
+ .in_sequence(command_sequence)
160
+ @instruction_builder
161
+ .expects(:copy)
162
+ .with("deploy-archive-dir/src1", "dst1/src1")
163
+ .in_sequence(command_sequence)
164
+
165
+ @installer.install(@deployment_group_id, @app_spec)
166
+ end
167
+
168
+ should "generate a mkdir command if the destination directory does not exist (absolute path)" do
169
+ @app_spec
170
+ .stubs(:files)
171
+ .returns([stub(:source => "src1",
172
+ :destination => "/dst1")])
173
+
174
+ command_sequence = sequence("command sequence")
175
+ @instruction_builder
176
+ .expects(:mkdir)
177
+ .with("/dst1")
178
+ .in_sequence(command_sequence)
179
+ @instruction_builder
180
+ .expects(:copy)
181
+ .with("deploy-archive-dir/src1", "/dst1/src1")
182
+ .in_sequence(command_sequence)
183
+
184
+ @installer.install(@deployment_group_id, @app_spec)
185
+ end
186
+
187
+ should "generate mkdir commands for multiple levels of missing directories" do
188
+ @app_spec
189
+ .stubs(:files)
190
+ .returns([stub(:source => "src1",
191
+ :destination => "dst1/foo/bar")])
192
+ File.stubs(:exists?).with("dst1").returns(true)
193
+
194
+ command_sequence = sequence("command sequence")
195
+ @instruction_builder
196
+ .expects(:mkdir)
197
+ .with("dst1/foo")
198
+ .in_sequence(command_sequence)
199
+ @instruction_builder
200
+ .expects(:mkdir)
201
+ .with("dst1/foo/bar")
202
+ .in_sequence(command_sequence)
203
+ @instruction_builder
204
+ .expects(:copy)
205
+ .with("deploy-archive-dir/src1", "dst1/foo/bar/src1")
206
+ .in_sequence(command_sequence)
207
+
208
+ @installer.install(@deployment_group_id, @app_spec)
209
+ end
210
+
211
+ end # "regular files"
212
+
213
+ context "directories" do
214
+
215
+ setup do
216
+ @app_spec
217
+ .stubs(:files)
218
+ .returns([stub(:source => "src1",
219
+ :destination => "dst1")])
220
+
221
+ File.stubs(:directory?).returns(false)
222
+ File.stubs(:directory?).with("deploy-archive-dir/src1").returns(true)
223
+ Dir.stubs(:entries)
224
+ .with("deploy-archive-dir/src1")
225
+ .returns([".", ".."])
226
+ @command_sequence = sequence("commands")
227
+ end
228
+
229
+ should "generate a mkdir if the destination doesn't exist" do
230
+ @instruction_builder
231
+ .expects(:mkdir)
232
+ .with("dst1")
233
+
234
+ @installer.install(@deployment_group_id, @app_spec)
235
+ end
236
+
237
+ should "generate mkdirs multiple levels of missing parent directories (absolute path)" do
238
+ @app_spec
239
+ .stubs(:files)
240
+ .returns([stub(:source => "src1",
241
+ :destination => "/dst1/foo/bar")])
242
+
243
+ File.stubs(:exists?).with("/dst1").returns(true)
244
+
245
+ command_sequence = sequence("command sequence")
246
+ @instruction_builder
247
+ .expects(:mkdir)
248
+ .with("/dst1/foo")
249
+ .in_sequence(command_sequence)
250
+ @instruction_builder
251
+ .expects(:mkdir)
252
+ .with("/dst1/foo/bar")
253
+ .in_sequence(command_sequence)
254
+
255
+ @installer.install(@deployment_group_id, @app_spec)
256
+ end
257
+
258
+ should "not generate a mkdir if the destination exists" do
259
+ File.stubs(:directory?).with("dst1").returns(true)
260
+ @instruction_builder.expects(:mkdir).never
261
+ @installer.install(@deployment_group_id, @app_spec)
262
+ end
263
+
264
+ should "generate a copy after the mkdir for each entry in the directory" do
265
+ Dir.stubs(:entries)
266
+ .with("deploy-archive-dir/src1")
267
+ .returns([".", "..", "foo", "bar"])
268
+
269
+ @instruction_builder.expects(:mkdir).with("dst1").in_sequence(@command_sequence)
270
+ @instruction_builder
271
+ .expects(:copy)
272
+ .with("deploy-archive-dir/src1/foo", "dst1/foo")
273
+ .in_sequence(@command_sequence)
274
+ @instruction_builder
275
+ .expects(:copy)
276
+ .with("deploy-archive-dir/src1/bar", "dst1/bar")
277
+ .in_sequence(@command_sequence)
278
+
279
+ @installer.install(@deployment_group_id, @app_spec)
280
+ end
281
+
282
+ should "raise an error if an entry already exists" do
283
+ Dir.stubs(:entries)
284
+ .with("deploy-archive-dir/src1")
285
+ .returns([".", "..", "foo", "bar"])
286
+ File.stubs(:exists?).with("dst1/bar").returns(true)
287
+ @instruction_builder.stubs(:mkdir)
288
+ @instruction_builder.stubs(:copy)
289
+
290
+ assert_raised_with_message("File already exists at location dst1/bar") do
291
+ @installer.install(@deployment_group_id, @app_spec)
292
+ end
293
+ end
294
+
295
+ context "with subdirectories" do
296
+
297
+ setup do
298
+ File.stubs(:directory?).with("deploy-archive-dir/src1/foo").returns(true)
299
+ File.stubs(:directory?).with("dst1").returns(true)
300
+ Dir.stubs(:entries)
301
+ .with("deploy-archive-dir/src1")
302
+ .returns([".", "..", "foo"])
303
+ Dir.stubs(:entries)
304
+ .with("deploy-archive-dir/src1/foo")
305
+ .returns([".", ".."])
306
+ end
307
+
308
+ should "generate a mkdir for the subdirectory if it doesn't exist" do
309
+ @instruction_builder
310
+ .expects(:mkdir)
311
+ .with("dst1/foo")
312
+
313
+ @installer.install(@deployment_group_id, @app_spec)
314
+ end
315
+
316
+ should "not generate a mkdir for the subdirectory if it exists" do
317
+ File.stubs(:directory?).with("dst1/foo").returns(true)
318
+
319
+ @instruction_builder
320
+ .expects(:mkdir)
321
+ .with("dst1/foo")
322
+ .never
323
+
324
+ @installer.install(@deployment_group_id, @app_spec)
325
+ end
326
+
327
+ should "generate a copy for each entry in the subdirectory" do
328
+ Dir.stubs(:entries)
329
+ .with("deploy-archive-dir/src1")
330
+ .returns([".", "..", "foo"])
331
+ Dir.stubs(:entries)
332
+ .with("deploy-archive-dir/src1/foo")
333
+ .returns([".", "..", "bar"])
334
+
335
+ @instruction_builder
336
+ .expects(:mkdir)
337
+ .with("dst1/foo")
338
+ .in_sequence(@command_sequence)
339
+ @instruction_builder
340
+ .expects(:copy)
341
+ .with("deploy-archive-dir/src1/foo/bar", "dst1/foo/bar")
342
+ .in_sequence(@command_sequence)
343
+
344
+ @installer.install(@deployment_group_id, @app_spec)
345
+ end
346
+
347
+ should "raise an error if the entry already exists" do
348
+ File.stubs(:exists?).with("dst1/foo/bar").returns(true)
349
+ Dir.stubs(:entries)
350
+ .with("deploy-archive-dir/src1")
351
+ .returns([".", "..", "foo"])
352
+ Dir.stubs(:entries)
353
+ .with("deploy-archive-dir/src1/foo")
354
+ .returns([".", "..", "bar"])
355
+ @instruction_builder.stubs(:mkdir)
356
+ @instruction_builder.stubs(:copy)
357
+
358
+ assert_raised_with_message("File already exists at location dst1/foo/bar") do
359
+ @installer.install(@deployment_group_id, @app_spec)
360
+ end
361
+ end
362
+
363
+ end # "with subdirectories"
364
+
365
+ end # "directories"
366
+
367
+ context "with permissions" do
368
+ setup do
369
+ @permissions = [InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("dst1/src1",
370
+ {:type => ["file"]}),
371
+ InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/",
372
+ {:type => ["directory"],
373
+ :pattern => "dst*",
374
+ :except => []}),
375
+ InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("dst3/",
376
+ {:type => ["file","directory"],
377
+ :pattern => "file*",
378
+ :except => [*2]})]
379
+ @app_spec
380
+ .stubs(:files)
381
+ .returns([stub(:source => "src1",
382
+ :destination => "dst1"),
383
+ stub(:source => "src2",
384
+ :destination => "dst2"),
385
+ stub(:source => "src3",
386
+ :destination => "dst3")])
387
+ @app_spec
388
+ .stubs(:permissions)
389
+ .returns(@permissions)
390
+
391
+ File.stubs(:directory?).returns(false)
392
+ File.stubs(:directory?).with("deploy-archive-dir/src2").returns(true)
393
+ File.stubs(:directory?).with("deploy-archive-dir/src3").returns(true)
394
+ File.stubs(:directory?).with("deploy-archive-dir/src3/dir1").returns(true)
395
+ File.stubs(:directory?).with("/").returns(true)
396
+ Dir.stubs(:entries)
397
+ .with("deploy-archive-dir/src2")
398
+ .returns([".", ".."])
399
+ Dir.stubs(:entries)
400
+ .with("deploy-archive-dir/src3")
401
+ .returns(["file1", "file2", "dir1", ".", ".."])
402
+ Dir.stubs(:entries)
403
+ .with("deploy-archive-dir/src3/dir1")
404
+ .returns(["file1", ".", ".."])
405
+ File.stubs(:exists?).returns(false)
406
+ File.stubs(:exists?).with(any_of("dst1","dst3")).returns(true)
407
+ @instruction_builder.stubs(:copying_file?).returns(false)
408
+ @instruction_builder.stubs(:copying_file?).with("dst1/src1").returns(true)
409
+ @instruction_builder.stubs(:making_directory?).returns(false)
410
+ @instruction_builder.stubs(:making_directory?).with("dst3/").returns(true)
411
+ @instruction_builder.stubs(:find_matches).returns([])
412
+ @instruction_builder.stubs(:find_matches).with(@permissions[1]).returns(["dst2", "dst3"])
413
+ @instruction_builder.stubs(:find_matches).with(@permissions[2]).returns(["dst3/file1"])
414
+ end
415
+
416
+ should "set the permissions" do
417
+ command_sequence = sequence("command sequence")
418
+
419
+ @instruction_builder
420
+ .expects(:copy)
421
+ .with("deploy-archive-dir/src1", "dst1/src1")
422
+ .in_sequence(command_sequence)
423
+ @instruction_builder
424
+ .expects(:mkdir)
425
+ .with("dst2")
426
+ .in_sequence(command_sequence)
427
+ @instruction_builder
428
+ .expects(:mkdir)
429
+ .with("dst3")
430
+ .in_sequence(command_sequence)
431
+ @instruction_builder
432
+ .expects(:copy)
433
+ .with("deploy-archive-dir/src3/file1", "dst3/file1")
434
+ .in_sequence(command_sequence)
435
+ @instruction_builder
436
+ .expects(:copy)
437
+ .with("deploy-archive-dir/src3/file2", "dst3/file2")
438
+ .in_sequence(command_sequence)
439
+ @instruction_builder
440
+ .expects(:mkdir)
441
+ .with("dst3/dir1")
442
+ .in_sequence(command_sequence)
443
+ @instruction_builder
444
+ .expects(:copy)
445
+ .with("deploy-archive-dir/src3/dir1/file1", "dst3/dir1/file1")
446
+ .in_sequence(command_sequence)
447
+ @instruction_builder
448
+ .expects(:set_permissions)
449
+ .with("dst1/src1", @permissions[0])
450
+ .in_sequence(command_sequence)
451
+ @instruction_builder
452
+ .expects(:set_permissions)
453
+ .with("dst2", @permissions[1])
454
+ .in_sequence(command_sequence)
455
+ @instruction_builder
456
+ .expects(:set_permissions)
457
+ .with("dst3", @permissions[1])
458
+ .in_sequence(command_sequence)
459
+ @instruction_builder
460
+ .expects(:set_permissions)
461
+ .with("dst3/file1", @permissions[2])
462
+ .in_sequence(command_sequence)
463
+
464
+ @installer.install(@deployment_group_id, @app_spec)
465
+ end
466
+ end
467
+
468
+ end # "files to install"
469
+
470
+ context "after generating instructions" do
471
+
472
+ setup do
473
+ @command_list = [stub("a command", :execute => nil),
474
+ stub("a second command", :execute => nil)]
475
+ InstallInstruction.stubs(:generate_instructions).returns(@command_list)
476
+ @command_list.stubs(:to_json).returns("INSTALL!")
477
+ end
478
+
479
+ should "write them to disk" do
480
+ install_file = mock("install file")
481
+ File
482
+ .expects(:open)
483
+ .with("deploy-instructions-dir/ig1-install.json", "w")
484
+ .yields(install_file)
485
+ install_file.expects(:write).with("INSTALL!")
486
+
487
+ @installer.install(@deployment_group_id, @app_spec)
488
+ end
489
+
490
+ should "execute them after writing to disk" do
491
+ call_sequence = sequence("call sequence")
492
+ File
493
+ .expects(:open)
494
+ .with("deploy-instructions-dir/ig1-install.json", "w")
495
+ .in_sequence(call_sequence)
496
+
497
+ cleanup_file = stub("cleanup file")
498
+ File
499
+ .stubs(:open)
500
+ .with("deploy-instructions-dir/ig1-cleanup", "w")
501
+ .yields(cleanup_file)
502
+
503
+ @command_list.each do |cmd|
504
+ cmd
505
+ .expects(:execute)
506
+ .with(cleanup_file)
507
+ .in_sequence(call_sequence)
508
+ end
509
+
510
+ @installer.install(@deployment_group_id, @app_spec)
511
+ end
512
+
513
+ end # "after generating instructions"
514
+
515
+ end # "installing"
516
+
517
+ end
518
+
519
+ end