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,566 @@
1
+ require 'test_helper'
2
+ require 'json'
3
+ require 'fileutils'
4
+
5
+ module InstanceAgent
6
+ module CodeDeployPlugin
7
+ class InstallInstructionTest < InstanceAgentTestCase
8
+ context "parsing an install file" do
9
+ context "a single mapped file" do
10
+ setup do
11
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "copy", "source" => "test_source", "destination" => "test_destination"}]}
12
+ @parse_string = JSON.dump(install_instructions)
13
+ @mock_file = mock
14
+ @mock_file.stubs(:puts)
15
+ @mock_file.stubs(:size).returns(0)
16
+ @mock_file.stubs(:close)
17
+ File.stubs(:open).returns(@mock_file)
18
+ end
19
+
20
+ should "return a collection containing a single CopyCommand which copies from test_source to test_destination" do
21
+ commands = InstallInstruction.parse_install_commands(@parse_string)
22
+ FileUtils.expects(:copy).with("test_source","test_destination", :preserve => true)
23
+ assert_not_equal nil, commands
24
+ commands.each do |command|
25
+ command.execute(@mock_file)
26
+ end
27
+ end
28
+ end
29
+
30
+ context "multiple mapped files" do
31
+ setup do
32
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "copy", "source" => "test_source", "destination" => "test_destination"}, {"type" => "copy", "source" => "source_2", "destination"=>"destination_2"}]}
33
+ @parse_string = JSON.dump(install_instructions)
34
+ @mock_file = mock
35
+ @mock_file.stubs(:puts)
36
+ @mock_file.stubs(:size).returns(0)
37
+ @mock_file.stubs(:close)
38
+ File.stubs(:open).returns(@mock_file)
39
+ end
40
+
41
+ should "return a collection containing multiple copy commands" do
42
+ commands = InstallInstruction.parse_install_commands(@parse_string)
43
+ FileUtils.expects(:copy).with("test_source","test_destination", :preserve => true)
44
+ FileUtils.expects(:copy).with("source_2","destination_2", :preserve => true)
45
+ assert_not_equal nil, commands
46
+ commands.each do |command|
47
+ command.execute(@mock_file)
48
+ end
49
+ end
50
+ end
51
+
52
+ context "contains a mkdir command" do
53
+ setup do
54
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "copy", "source" => "test_source", "destination" => "test_destination"}, {"type" => "mkdir", "directory"=>"directory"}]}
55
+ @parse_string = JSON.dump(install_instructions)
56
+ @mock_file = mock
57
+ @mock_file.stubs(:puts)
58
+ @mock_file.stubs(:size).returns(0)
59
+ @mock_file.stubs(:close)
60
+ @mock_file.stubs(:exist?).returns(false)
61
+ File.stubs(:open).returns(@mock_file)
62
+ File.stubs(:exists?).returns(false)
63
+ end
64
+
65
+ should "return a collection containing a copy command and a mkdir command" do
66
+ commands = InstallInstruction.parse_install_commands(@parse_string)
67
+ FileUtils.expects(:copy).with("test_source","test_destination", :preserve => true)
68
+ FileUtils.expects(:mkdir).with("directory")
69
+ assert_not_equal nil, commands
70
+ commands.each do |command|
71
+ command.execute(@mock_file)
72
+ end
73
+ end
74
+
75
+ should "raise an error if a file exists at the mkdir location" do
76
+ commands = InstallInstruction.parse_install_commands(@parse_string)
77
+ File.stubs(:exists?).with("directory").returns(true)
78
+ FileUtils.stubs(:copy)
79
+
80
+ assert_raised_with_message("File already exists at directory") do
81
+ commands.each do |command|
82
+ command.execute(@mock_file)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ context "correctly determines method from file type" do
89
+ setup do
90
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "copy", "source" => "test_source", "destination" => "test_destination"}, {"type" => "copy", "source" => "source_2", "destination"=>"destination_2"}]}
91
+ @parse_string = JSON.dump(install_instructions)
92
+ @instruction_file = mock
93
+ @instruction_file.stubs(:read).returns(@parse_string)
94
+ @instruction_file.stubs(:path).returns("test/123-install.json")
95
+ @instruction_file.stubs(:close)
96
+ File.stubs(:open).with("test/123-install.json", 'r').returns(@instruction_file)
97
+ end
98
+
99
+ should "call parse_install_commands" do
100
+ InstallInstruction.expects(:parse_install_commands).with(@parse_string)
101
+ commands = InstallInstruction.generate_commands_from_file(@instruction_file)
102
+ end
103
+ end
104
+
105
+ context "contains a chmod command" do
106
+ setup do
107
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "chmod", "mode" => "0740", "file" => "testfile.txt"}]}
108
+ @parse_string = JSON.dump(install_instructions)
109
+ @mock_file = mock
110
+ File.stubs(:chmod)
111
+ end
112
+
113
+ should "set the mode of the object" do
114
+ commands = InstallInstruction.parse_install_commands(@parse_string)
115
+ File.expects(:chmod).with("740".to_i(8), "testfile.txt")
116
+ assert_not_equal nil, commands
117
+ commands.each do |command|
118
+ command.execute(@mock_file)
119
+ end
120
+ end
121
+ end
122
+
123
+ context "contains a chown command" do
124
+ setup do
125
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "chown", "owner" => "bob", "group" => "dev", "file" => "testfile.txt"}]}
126
+ @parse_string = JSON.dump(install_instructions)
127
+ @mock_etc = mock
128
+ @mock_etc.stubs(:gid).returns(222)
129
+ @mock_etc.stubs(:uid).returns(111)
130
+ @mock_file = mock
131
+ Etc.stubs(:getpwnam).with("bob").returns(@mock_etc)
132
+ Etc.stubs(:getgrnam).with("dev").returns(@mock_etc)
133
+ File.stubs(:chchown)
134
+ end
135
+
136
+ should "set the owner of the object" do
137
+ commands = InstallInstruction.parse_install_commands(@parse_string)
138
+ File.expects(:chown).with(111, 222, "testfile.txt")
139
+ assert_not_equal nil, commands
140
+ commands.each do |command|
141
+ command.execute(@mock_file)
142
+ end
143
+ end
144
+ end
145
+
146
+ context "contains a setfacl command" do
147
+ setup do
148
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "setfacl", "acl" => ["user:bob:rwx","default:user:bob:rwx"], "file" => "testfile.txt"}]}
149
+ @parse_string = JSON.dump(install_instructions)
150
+ @mock_file = mock
151
+ @mock_stat = mock
152
+ @mock_stat.stubs(:mode).returns("100421".to_i(8))
153
+ ChangeAclCommand.any_instance.stubs(:system).returns(false)
154
+ @full_acl = "user:bob:rwx,default:user:bob:rwx,user::r--,group::-w-,other::--x,mask::-w-,default:user::r--,default:group::-w-,default:other::--x,default:mask::-w-"
155
+ File.stubs(:stat).returns(@mock_stat)
156
+ end
157
+
158
+ should "set the acl of the object" do
159
+ commands = InstallInstruction.parse_install_commands(@parse_string)
160
+ ChangeAclCommand.any_instance.expects(:system).with("setfacl --set #{@full_acl} testfile.txt").returns(true)
161
+ assert_not_equal nil, commands
162
+ commands.each do |command|
163
+ command.execute(@mock_file)
164
+ end
165
+ end
166
+
167
+ should "throw if system call fails" do
168
+ commands = InstallInstruction.parse_install_commands(@parse_string)
169
+ ChangeAclCommand.any_instance.expects(:system).with("setfacl --set #{@full_acl} testfile.txt").returns(false)
170
+ assert_not_equal nil, commands
171
+ assert_raise(RuntimeError) do
172
+ commands.each do |command|
173
+ command.execute(@mock_file)
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ context "contains a semanage command" do
180
+
181
+ context "with a role" do
182
+ setup do
183
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "semanage", "context" => {"name" => "name", "role" => "role", "type" => "type", "range" => "s0" }, "file" => "testfile.txt"}]}
184
+ @parse_string = JSON.dump(install_instructions)
185
+ ChangeContextCommand.any_instance.stubs(:system).returns(true)
186
+ @mock_file = mock
187
+ end
188
+
189
+ should "raise an exception" do
190
+ assert_raise(RuntimeError) do
191
+ commands = InstallInstruction.parse_install_commands(@parse_string)
192
+ end
193
+ end
194
+ end
195
+
196
+ context "which is valid" do
197
+ setup do
198
+ install_instructions = { "revisionId" => "foo" , "instructions" => [{"type" => "semanage", "context" => {"name" => "name", "role" => nil, "type" => "type", "range" => "s0" }, "file" => "testfile.txt"}]}
199
+ @parse_string = JSON.dump(install_instructions)
200
+ @mock_file = mock
201
+ ChangeContextCommand.any_instance.stubs(:system).returns(false)
202
+ File.stubs(:realpath).returns("testfile.txt")
203
+ end
204
+
205
+ should "set the context of the object" do
206
+ commands = InstallInstruction.parse_install_commands(@parse_string)
207
+ ChangeContextCommand.any_instance.expects(:system).with("semanage fcontext -a -s name -t type -r s0 testfile.txt").returns(true)
208
+ ChangeContextCommand.any_instance.expects(:system).with("restorecon -v testfile.txt").returns(true)
209
+ @mock_file.expects(:puts).with("semanage\0testfile.txt")
210
+ assert_not_equal nil, commands
211
+ commands.each do |command|
212
+ command.execute(@mock_file)
213
+ end
214
+ end
215
+
216
+ should "throw if semanage system call fails" do
217
+ commands = InstallInstruction.parse_install_commands(@parse_string)
218
+ ChangeContextCommand.any_instance.expects(:system).with("semanage fcontext -a -s name -t type -r s0 testfile.txt").returns(false)
219
+ assert_not_equal nil, commands
220
+ assert_raise(RuntimeError) do
221
+ commands.each do |command|
222
+ command.execute(@mock_file)
223
+ end
224
+ end
225
+ end
226
+
227
+ should "throw if system call fails" do
228
+ commands = InstallInstruction.parse_install_commands(@parse_string)
229
+ ChangeContextCommand.any_instance.expects(:system).with("semanage fcontext -a -s name -t type -r s0 testfile.txt").returns(true)
230
+ ChangeContextCommand.any_instance.expects(:system).with("restorecon -v testfile.txt").returns(false)
231
+ assert_not_equal nil, commands
232
+ assert_raise(RuntimeError) do
233
+ commands.each do |command|
234
+ command.execute(@mock_file)
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
241
+
242
+ context "Parsing a delete file" do
243
+ context "an empty delete file" do
244
+ setup do
245
+ @parse_string = <<-END
246
+ END
247
+ end
248
+
249
+ should "return an empty command collection" do
250
+ commands = InstallInstruction.parse_remove_commands(@parse_string)
251
+ assert_equal 0, commands.length
252
+ end
253
+ end
254
+
255
+ context "a single file to delete" do
256
+ setup do
257
+ @parse_string = <<-END
258
+ test_delete_path
259
+ END
260
+ File.stubs(:exist?).with("test_delete_path").returns(true)
261
+ end
262
+
263
+ should "produce a command that deletes test_delete_path" do
264
+ commands = InstallInstruction.parse_remove_commands(@parse_string)
265
+ FileUtils.expects(:rm).with("test_delete_path")
266
+ assert_not_equal nil, commands
267
+ commands.each do |command|
268
+ command.execute
269
+ end
270
+ end
271
+ end
272
+
273
+ context "multiple files to delete" do
274
+ setup do
275
+ @parse_string = <<-END
276
+ test_delete_path
277
+ another_delete_path
278
+ END
279
+ File.stubs(:directory?).returns(false)
280
+ File.stubs(:exist?).with("test_delete_path").returns(true)
281
+ File.stubs(:exist?).with("another_delete_path").returns(true)
282
+ end
283
+
284
+ should "produce a command that deletes test_delete_path" do
285
+ commands = InstallInstruction.parse_remove_commands(@parse_string)
286
+ FileUtils.expects(:rm).with("test_delete_path")
287
+ FileUtils.expects(:rm).with("another_delete_path")
288
+ assert_not_equal nil, commands
289
+ commands.each do |command|
290
+ command.execute
291
+ end
292
+ end
293
+
294
+ should "use rmdir for directories" do
295
+ File.stubs(:directory?).with("test_delete_path").returns(true)
296
+
297
+ commands = InstallInstruction.parse_remove_commands(@parse_string)
298
+ FileUtils.expects(:rmdir).with("test_delete_path")
299
+ FileUtils.expects(:rm).with("another_delete_path")
300
+
301
+ commands.each do |command|
302
+ command.execute
303
+ end
304
+ end
305
+ end
306
+
307
+ context "removes mangled line at the end" do
308
+ setup do
309
+ @parse_string = <<-END
310
+ test_delete_path
311
+ another_delete_path
312
+ END
313
+ @parse_string << "mangled"
314
+ File.stubs(:exist?).with("test_delete_path").returns(true)
315
+ File.stubs(:exist?).with("another_delete_path").returns(true)
316
+ end
317
+
318
+ should "produce a command that deletes test_delete_path" do
319
+ commands = InstallInstruction.parse_remove_commands(@parse_string)
320
+ FileUtils.expects(:rm).with("test_delete_path")
321
+ FileUtils.expects(:rm).with("another_delete_path")
322
+ FileUtils.expects(:rm).with("mangled").never
323
+ assert_not_equal nil, commands
324
+ commands.each do |command|
325
+ command.execute
326
+ end
327
+ end
328
+ end
329
+
330
+ context "correctly determines method from file type" do
331
+ setup do
332
+ @parse_string = 'foo'
333
+ @instruction_file = mock
334
+ @instruction_file.stubs(:path).returns("test/123-cleanup")
335
+ File.stubs(:open).with("test/123-cleanup", 'r').returns(@instruction_file)
336
+ @instruction_file.stubs(:read).returns(@parse_string)
337
+ @instruction_file.stubs(:close)
338
+ end
339
+
340
+ should "call parse_remove_commands" do
341
+ InstallInstruction.expects(:parse_remove_commands).with(@parse_string)
342
+ commands = InstallInstruction.generate_commands_from_file(@instruction_file)
343
+ end
344
+ end
345
+
346
+ context "with a semanage command" do
347
+ setup do
348
+ @parse_string = "semanage\0testfile.txt\n"
349
+ RemoveContextCommand.any_instance.stubs(:system)
350
+ end
351
+
352
+ should "remove the context of the object" do
353
+ commands = InstallInstruction.parse_remove_commands(@parse_string)
354
+ RemoveContextCommand.any_instance.expects(:system).with("semanage fcontext -d testfile.txt")
355
+ assert_not_equal nil, commands
356
+ commands.each do |command|
357
+ command.execute
358
+ end
359
+ end
360
+ end
361
+ end
362
+
363
+ context "Testing the command builder" do
364
+ setup do
365
+ @command_builder = CommandBuilder.new()
366
+ Dir.chdir "/tmp"
367
+ end
368
+
369
+ should "Have an empty command array" do
370
+ assert_equal @command_builder.command_array, []
371
+ end
372
+
373
+ context "with a single copy command" do
374
+ setup do
375
+ @command_builder = CommandBuilder.new()
376
+ @command_builder.copy("source", "destination")
377
+ @expected_json = {"instructions"=>[{"type"=>"copy","source"=>"source","destination"=>"/tmp/destination"}]}.to_json
378
+ end
379
+
380
+ should "have a single copy in the returned JSON" do
381
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
382
+ end
383
+
384
+ should "raise a duplicate exception when a copy collides with another copy" do
385
+ assert_raised_with_message("Duplicate copy instruction to /tmp/destination from source and source") do
386
+ @command_builder.copy("source", "destination")
387
+ end
388
+ end
389
+ end
390
+
391
+ context "with a single mkdir command" do
392
+ setup do
393
+ @command_builder = CommandBuilder.new()
394
+ @command_builder.mkdir("directory")
395
+ @expected_json = {"instructions"=>[{"type"=>"mkdir","directory"=>"/tmp/directory"}]}.to_json
396
+ end
397
+
398
+ should "have a single mkdir in the returned JSON" do
399
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
400
+ end
401
+
402
+ should "raise a duplicate exception when trying to create a directory collides with a copy" do
403
+ @command_builder.copy("source", "directory/dir1")
404
+ assert_raised_with_message("Duplicate mkdir instruction for /tmp/directory/dir1 which is already being copied from source") do
405
+ @command_builder.mkdir("directory/dir1")
406
+ end
407
+ end
408
+ end
409
+
410
+ context "with one of each command (copy and mkdir)" do
411
+ setup do
412
+ @command_builder = CommandBuilder.new()
413
+ @command_builder.mkdir("directory/target")
414
+ @command_builder.copy( "file_target", "directory/target/file_target")
415
+ end
416
+
417
+ should "raise a duplicate exception when trying to make a copy collides with a mkdir" do
418
+ assert_raised_with_message("Duplicate copy instruction to /tmp/directory/target from target which is already being installed as a directory") do
419
+ @command_builder.copy( "target", "directory/target")
420
+ end
421
+ end
422
+
423
+ should "say it is copying the appropriate file" do
424
+ assert @command_builder.copying_file?("/tmp/directory/target/file_target")
425
+ assert !@command_builder.copying_file?("/tmp/directory/target")
426
+ end
427
+
428
+ should "say it is making the appropriate directory" do
429
+ assert !@command_builder.making_directory?("/tmp/directory/target/file_target")
430
+ assert @command_builder.making_directory?("/tmp/directory/target")
431
+ end
432
+
433
+ should "match the file when appropriate" do
434
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/target", {
435
+ :type => ["file"],
436
+ :pattern => "file*",
437
+ :except => []})
438
+ assert @command_builder.find_matches(permission).include?("/tmp/directory/target/file_target")
439
+
440
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/target", {
441
+ :type => ["directory"],
442
+ :pattern => "file*",
443
+ :except => []})
444
+ assert !@command_builder.find_matches(permission).include?("/tmp/directory/target/file_target")
445
+
446
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/target", {
447
+ :type => ["file"],
448
+ :pattern => "filefile*",
449
+ :except => []})
450
+ assert !@command_builder.find_matches(permission).include?("/tmp/directory/target/file_target")
451
+
452
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/target", {
453
+ :type => ["file"],
454
+ :pattern => "file*",
455
+ :except => ["*target"]})
456
+ assert !@command_builder.find_matches(permission).include?("/tmp/directory/target/file_target")
457
+ end
458
+
459
+ should "match the directory when appropriate" do
460
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/", {
461
+ :type => ["directory"],
462
+ :pattern => "tar*",
463
+ :except => []})
464
+ assert @command_builder.find_matches(permission).include?("/tmp/directory/target")
465
+
466
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/", {
467
+ :type => ["file"],
468
+ :pattern => "tar*",
469
+ :except => []})
470
+ assert !@command_builder.find_matches(permission).include?("/tmp/directory/target")
471
+
472
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/", {
473
+ :type => ["directory"],
474
+ :pattern => "tarr*",
475
+ :except => []})
476
+ assert !@command_builder.find_matches(permission).include?("/tmp/directory/target")
477
+
478
+ permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("/tmp/directory/", {
479
+ :type => ["directory"],
480
+ :pattern => "tar*",
481
+ :except => ["*et"]})
482
+ assert !@command_builder.find_matches(permission).include?("/tmp/directory/target")
483
+ end
484
+ end
485
+
486
+ context "two mkdirs to the same place" do
487
+ setup do
488
+ @command_builder = CommandBuilder.new()
489
+ @command_builder.mkdir("directory")
490
+ @command_builder.mkdir("directory")
491
+ @expected_json = {"instructions"=>[{"type"=>"mkdir","directory"=>"/tmp/directory"}]}.to_json
492
+ end
493
+
494
+ should "have a single mkdir in the returned JSON" do
495
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
496
+ end
497
+ end
498
+
499
+ context "two mkdirs to the same place one has a trailing /" do
500
+ setup do
501
+ @command_builder = CommandBuilder.new()
502
+ @command_builder.mkdir("directory")
503
+ @command_builder.mkdir("directory/")
504
+ @expected_json = {"instructions"=>[{"type"=>"mkdir","directory"=>"/tmp/directory"}]}.to_json
505
+ end
506
+
507
+ should "have a single mkdir in the returned JSON" do
508
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
509
+ end
510
+ end
511
+
512
+ context "setting permissions" do
513
+ should "raise a duplicate exception when trying to set permissions twice" do
514
+ @permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("testfile.txt")
515
+ @command_builder = CommandBuilder.new()
516
+ @command_builder.set_permissions("testfile.txt", @permission)
517
+ assert_raised_with_message("Duplicate permission setting instructions for /tmp/testfile.txt") do
518
+ @command_builder.set_permissions("testfile.txt", @permission)
519
+ end
520
+ end
521
+
522
+ should "not add any commands for empty permissions" do
523
+ @permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("testfile.txt")
524
+ @command_builder = CommandBuilder.new()
525
+ @command_builder.set_permissions("testfile.txt", @permission)
526
+ @expected_json = {"instructions"=>[]}.to_json
527
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
528
+ end
529
+
530
+ should "add commands for each part of permisssions" do
531
+ @permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("testfile.txt", {
532
+ :mode=>InstanceAgent::CodeDeployPlugin::ApplicationSpecification::ModeInfo.new(744),
533
+ :acls=>InstanceAgent::CodeDeployPlugin::ApplicationSpecification::AclInfo.new(["u:bob:7","d:g:dev:4"]),
534
+ :context=>InstanceAgent::CodeDeployPlugin::ApplicationSpecification::ContextInfo.new({"name"=>"name","type"=>"type","range"=>"s2-s3:c0,c2.c4,c6"}),
535
+ :owner=>"bob",
536
+ :group=>"dev"})
537
+ @command_builder = CommandBuilder.new()
538
+ @command_builder.set_permissions("testfile.txt", @permission)
539
+ @expected_json = {"instructions"=>[{"type"=>"chmod","mode"=>"744","file"=>"/tmp/testfile.txt"},
540
+ {"type"=>"setfacl","acl"=>["user:bob:rwx","default:group:dev:r--"],"file"=>"/tmp/testfile.txt"},
541
+ {"type"=>"semanage","context"=>{"user"=>"name","role"=>nil,"type"=>"type","range"=>"s2-s3:c0,c2.c4,c6"},"file"=>"/tmp/testfile.txt"},
542
+ {"type"=>"chown","owner"=>"bob","group"=>"dev","file"=>"/tmp/testfile.txt"}
543
+ ]}.to_json
544
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
545
+ end
546
+
547
+ should "add chown command with just owner" do
548
+ @permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("testfile.txt", {:owner=>"bob"})
549
+ @command_builder = CommandBuilder.new()
550
+ @command_builder.set_permissions("testfile.txt", @permission)
551
+ @expected_json = {"instructions"=>[{"type"=>"chown","owner"=>"bob","group"=>nil,"file"=>"/tmp/testfile.txt"}]}.to_json
552
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
553
+ end
554
+
555
+ should "add chown command with just group" do
556
+ @permission = InstanceAgent::CodeDeployPlugin::ApplicationSpecification::LinuxPermissionInfo.new("testfile.txt", {:group=>"dev"})
557
+ @command_builder = CommandBuilder.new()
558
+ @command_builder.set_permissions("testfile.txt", @permission)
559
+ @expected_json = {"instructions"=>[{"type"=>"chown","owner"=>nil,"group"=>"dev","file"=>"/tmp/testfile.txt"}]}.to_json
560
+ assert_equal JSON.parse(@expected_json), JSON.parse(@command_builder.to_json)
561
+ end
562
+ end
563
+ end
564
+ end
565
+ end
566
+ end