aws-codedeploy-agent 0.0.1

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