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