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.
- data/.gitignore +2 -0
- data/CHANGES.md +3 -0
- data/Gemfile +13 -0
- data/LICENSE +177 -0
- data/NOTICE +2 -0
- data/README.md +16 -0
- data/aws-codedeploy-agent.gemspec +39 -0
- data/bin/codedeploy-agent +78 -0
- data/bin/codedeploy-install +15 -0
- data/bin/codedeploy-uninstall +13 -0
- data/certs/host-agent-deployment-signer-ca-chain.pem +76 -0
- data/conf/codedeployagent.yml +9 -0
- data/init.d/codedeploy-agent +61 -0
- data/lib/core_ext.rb +71 -0
- data/lib/instance_agent.rb +35 -0
- data/lib/instance_agent/agent/base.rb +34 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/ace_info.rb +133 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/acl_info.rb +163 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/application_specification.rb +142 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/context_info.rb +23 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/file_info.rb +23 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/linux_permission_info.rb +121 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/mode_info.rb +66 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/range_info.rb +134 -0
- data/lib/instance_agent/codedeploy_plugin/application_specification/script_info.rb +27 -0
- data/lib/instance_agent/codedeploy_plugin/codedeploy_control.rb +72 -0
- data/lib/instance_agent/codedeploy_plugin/command_executor.rb +357 -0
- data/lib/instance_agent/codedeploy_plugin/command_poller.rb +146 -0
- data/lib/instance_agent/codedeploy_plugin/deployment_specification.rb +150 -0
- data/lib/instance_agent/codedeploy_plugin/hook_executor.rb +206 -0
- data/lib/instance_agent/codedeploy_plugin/install_instruction.rb +374 -0
- data/lib/instance_agent/codedeploy_plugin/installer.rb +143 -0
- data/lib/instance_agent/codedeploy_plugin/request_helper.rb +28 -0
- data/lib/instance_agent/config.rb +43 -0
- data/lib/instance_agent/log.rb +3 -0
- data/lib/instance_agent/platform.rb +17 -0
- data/lib/instance_agent/platform/linux_util.rb +57 -0
- data/lib/instance_agent/runner/child.rb +57 -0
- data/lib/instance_agent/runner/master.rb +103 -0
- data/lib/instance_metadata.rb +47 -0
- data/test/certificate_helper.rb +120 -0
- data/test/helpers/instance_agent_helper.rb +25 -0
- data/test/instance_agent/agent/base_test.rb +49 -0
- data/test/instance_agent/codedeploy_plugin/application_specification_test.rb +1710 -0
- data/test/instance_agent/codedeploy_plugin/codedeploy_control_test.rb +51 -0
- data/test/instance_agent/codedeploy_plugin/command_executor_test.rb +513 -0
- data/test/instance_agent/codedeploy_plugin/command_poller_test.rb +459 -0
- data/test/instance_agent/codedeploy_plugin/deployment_specification_test.rb +335 -0
- data/test/instance_agent/codedeploy_plugin/hook_executor_test.rb +250 -0
- data/test/instance_agent/codedeploy_plugin/install_instruction_test.rb +566 -0
- data/test/instance_agent/codedeploy_plugin/installer_test.rb +519 -0
- data/test/instance_agent/codedeploy_plugin/request_helper_test.rb +37 -0
- data/test/instance_agent/config_test.rb +64 -0
- data/test/instance_agent/runner/child_test.rb +87 -0
- data/test/instance_metadata_test.rb +97 -0
- data/test/test_helper.rb +16 -0
- data/vendor/gems/.codedeploy-commands-1.0.0.created.rid +1 -0
- data/vendor/gems/codedeploy-commands/apis/CodeDeployCommand.api.json +372 -0
- data/vendor/gems/codedeploy-commands/codedeploy-commands-1.0.0.gemspec +28 -0
- data/vendor/gems/codedeploy-commands/lib/aws/codedeploy_commands.rb +18 -0
- data/vendor/gems/codedeploy-commands/lib/aws/plugins/certificate_authority.rb +12 -0
- data/vendor/gems/codedeploy-commands/lib/aws/plugins/deploy_control_endpoint.rb +22 -0
- data/vendor/gems/process_manager/README.md +1 -0
- data/vendor/gems/process_manager/lib/blank.rb +153 -0
- data/vendor/gems/process_manager/lib/core_ext.rb +73 -0
- data/vendor/gems/process_manager/lib/process_manager.rb +49 -0
- data/vendor/gems/process_manager/lib/process_manager/child.rb +119 -0
- data/vendor/gems/process_manager/lib/process_manager/config.rb +112 -0
- data/vendor/gems/process_manager/lib/process_manager/log.rb +107 -0
- data/vendor/gems/process_manager/lib/process_manager/master.rb +322 -0
- data/vendor/gems/process_manager/process_manager-0.0.13.gemspec +42 -0
- data/vendor/specifications/aws-sdk-core-2.0.5.gemspec +39 -0
- data/vendor/specifications/builder-3.2.2.gemspec +29 -0
- data/vendor/specifications/codedeploy-commands-1.0.0.gemspec +28 -0
- data/vendor/specifications/gli-2.5.6.gemspec +51 -0
- data/vendor/specifications/jamespath-0.5.1.gemspec +35 -0
- data/vendor/specifications/little-plugger-1.1.3.gemspec +32 -0
- data/vendor/specifications/logging-1.8.1.gemspec +44 -0
- data/vendor/specifications/multi_json-1.7.7.gemspec +30 -0
- data/vendor/specifications/multi_json-1.8.4.gemspec +30 -0
- data/vendor/specifications/multi_xml-0.5.5.gemspec +30 -0
- data/vendor/specifications/process_manager-0.0.13.gemspec +42 -0
- data/vendor/specifications/simple_pid-0.2.1.gemspec +28 -0
- 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
|