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,335 @@
1
+ require 'test_helper'
2
+ require 'ostruct'
3
+ require 'certificate_helper'
4
+
5
+ class DeploymentSpecificationTest < InstanceAgentTestCase
6
+ context 'The Deployment Specification' do
7
+ def generate_signed_message_for(map)
8
+ message = @cert_helper.sign_message(map.to_json)
9
+ spec = OpenStruct.new({ :payload => message })
10
+ spec.format = "PKCS7/JSON"
11
+
12
+ return spec
13
+ end
14
+
15
+ setup do
16
+ @cert_helper = CertificateHelper.new
17
+ @deployment_id = SecureRandom.uuid.to_s
18
+ @deployment_group_id = SecureRandom.uuid.to_s
19
+ @s3Revision = {
20
+ "Bucket" => "mybucket",
21
+ "Key" => "mykey",
22
+ "BundleType" => "tar"
23
+ }
24
+ @revision = {
25
+ "RevisionType" => "S3",
26
+ "S3Revision" => @s3Revision
27
+ }
28
+ @deployment_spec = {
29
+ "DeploymentId" => @deployment_id,
30
+ "DeploymentGroupId" => @deployment_group_id,
31
+ "Revision" => @revision
32
+ }
33
+ @packed_message = generate_signed_message_for(@deployment_spec)
34
+ InstanceAgent::Config.init
35
+ end
36
+
37
+ context "with JSON format" do
38
+ should "populate the deployment id" do
39
+ parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
40
+ assert_equal @deployment_id, parsed_deployment_spec.deployment_id
41
+ assert_equal @s3Revision, parsed_deployment_spec.revision
42
+ end
43
+ end
44
+
45
+ context "with arn deployment id" do
46
+ setup do
47
+ @deployment_spec = {
48
+ "DeploymentId" => "arn:aws:codedeploy:region:account:deployment/#{@deployment_id}",
49
+ "DeploymentGroupId" => @deployment_group_id,
50
+ "Revision" => @revision
51
+ }
52
+ @packed_message = generate_signed_message_for(@deployment_spec)
53
+ end
54
+
55
+ should "populate the Bundle" do
56
+ parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
57
+ assert_equal @deployment_id, parsed_deployment_spec.deployment_id
58
+ assert_equal @deployment_group_id, parsed_deployment_spec.deployment_group_id
59
+ assert_equal @s3Revision, parsed_deployment_spec.revision
60
+ end
61
+ end
62
+
63
+ context "with an unsupported format" do
64
+ setup do
65
+ @packed_message.format = "XML"
66
+ end
67
+
68
+ should "raise an exception" do
69
+ assert_raised_with_message("Unsupported DeploymentSpecification format: XML") do
70
+ parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
71
+ end
72
+ end
73
+ end
74
+
75
+ context "with additional data" do
76
+ setup do
77
+ @deployment_spec["AdditionalData"] = "test"
78
+ @packed_message = generate_signed_message_for(@deployment_spec)
79
+ end
80
+
81
+ should "populate the Bundle" do
82
+ parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
83
+ assert_equal @deployment_id, parsed_deployment_spec.deployment_id
84
+ assert_equal @deployment_group_id, parsed_deployment_spec.deployment_group_id
85
+ assert_equal @s3Revision, parsed_deployment_spec.revision
86
+ end
87
+ end
88
+
89
+ context "with a nil format" do
90
+ setup do
91
+ @packed_message.format = nil
92
+ end
93
+
94
+ should "raise an exception" do
95
+ assert_raised_with_message("Unsupported DeploymentSpecification format: ") do
96
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
97
+ end
98
+ end
99
+ end
100
+
101
+ context "is nil" do
102
+ setup do
103
+ @packed_message = nil
104
+ end
105
+
106
+ should "raise a runtime exception" do
107
+ assert_raised_with_message("Provided deployment spec was nil") do
108
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
109
+ end
110
+ end
111
+ end
112
+
113
+ context "with no deployment id" do
114
+ setup do
115
+ @deployment_spec.delete("DeploymentId")
116
+ @packed_message = generate_signed_message_for(@deployment_spec)
117
+ end
118
+
119
+ should "raise a runtime exception" do
120
+ assert_raised_with_message("Deployment Spec has no DeploymentId") do
121
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
122
+ end
123
+ end
124
+ end
125
+
126
+ context "with null deployment id" do
127
+ setup do
128
+ @deployment_spec["DeploymentId"] = nil
129
+ @packed_message = generate_signed_message_for(@deployment_spec)
130
+ end
131
+
132
+ should "raise a runtime exception" do
133
+ assert_raised_with_message("Deployment Spec has no DeploymentId") do
134
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
135
+ end
136
+ end
137
+ end
138
+
139
+ context "with empty deployment id" do
140
+ setup do
141
+ @deployment_spec["DeploymentId"] = ""
142
+ @packed_message = generate_signed_message_for(@deployment_spec)
143
+ end
144
+
145
+ should "raise a runtime exception" do
146
+ assert_raised_with_message("Deployment Spec has no DeploymentId") do
147
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
148
+ end
149
+ end
150
+ end
151
+
152
+ context "with no instance group id" do
153
+ setup do
154
+ @deployment_spec.delete("DeploymentGroupId")
155
+ @packed_message = generate_signed_message_for(@deployment_spec)
156
+ end
157
+
158
+ should "raise a runtime exception" do
159
+ assert_raised_with_message("Deployment Spec has no DeploymentGroupId") do
160
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
161
+ end
162
+ end
163
+ end
164
+
165
+ context "with null instance group id" do
166
+ setup do
167
+ @deployment_spec["DeploymentGroupId"] = nil
168
+ @packed_message = generate_signed_message_for(@deployment_spec)
169
+ end
170
+
171
+ should "raise a runtime exception" do
172
+ assert_raised_with_message("Deployment Spec has no DeploymentGroupId") do
173
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
174
+ end
175
+ end
176
+ end
177
+
178
+ context "with empty instance group id" do
179
+ setup do
180
+ @deployment_spec["DeploymentGroupId"] = ""
181
+ @packed_message = generate_signed_message_for(@deployment_spec)
182
+ end
183
+
184
+ should "raise a runtime exception" do
185
+ assert_raised_with_message("Deployment Spec has no DeploymentGroupId") do
186
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
187
+ end
188
+ end
189
+ end
190
+
191
+ context "with no target revision" do
192
+ setup do
193
+ @deployment_spec.delete("Revision")
194
+ @packed_message = generate_signed_message_for(@deployment_spec)
195
+ end
196
+
197
+ should "raise a runtime exception" do
198
+ assert_raised_with_message('Must specify a revison') do
199
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
200
+ end
201
+ end
202
+ end
203
+
204
+ context "with null target revision" do
205
+ setup do
206
+ @deployment_spec["Revision"] = nil
207
+ @packed_message = generate_signed_message_for(@deployment_spec)
208
+ end
209
+
210
+ should "raise a runtime exception" do
211
+ assert_raised_with_message('Must specify a revison') do
212
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
213
+ end
214
+ end
215
+ end
216
+
217
+ context "with empty target revision" do
218
+ setup do
219
+ @deployment_spec["Revision"] = ""
220
+ @packed_message = generate_signed_message_for(@deployment_spec)
221
+ end
222
+
223
+ should "raise a runtime exception" do
224
+ assert_raised_with_message("Must specify a revision source") do
225
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
226
+ end
227
+ end
228
+ end
229
+
230
+ context "with S3 Revision" do
231
+ should "parse correctly" do
232
+ parsed_deployment_spec = InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
233
+ assert_equal @s3Revision, parsed_deployment_spec.revision
234
+ end
235
+
236
+ should "raise when Bucket is missing" do
237
+ @s3Revision = {
238
+ "Key" => "mykey",
239
+ "BundleType" => "tar"
240
+ }
241
+ @revision = {
242
+ "RevisionType" => "S3",
243
+ "S3Revision" => @s3Revision
244
+ }
245
+ @deployment_spec = {
246
+ "DeploymentId" => @deployment_id,
247
+ "DeploymentGroupId" => @deployment_group_id,
248
+ "Revision" => @revision
249
+ }
250
+ @packed_message = generate_signed_message_for(@deployment_spec)
251
+
252
+ assert_raised_with_message("S3Revision in Deployment Spec must specify Bucket, Key and BundleType") do
253
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
254
+ end
255
+ end
256
+
257
+ should "raise when Key is missing" do
258
+ @s3Revision = {
259
+ "Bucket" => "mybucket",
260
+ "BundleType" => "tar"
261
+ }
262
+ @revision = {
263
+ "RevisionType" => "S3",
264
+ "S3Revision" => @s3Revision
265
+ }
266
+ @deployment_spec = {
267
+ "DeploymentId" => @deployment_id,
268
+ "DeploymentGroupId" => @deployment_group_id,
269
+ "Revision" => @revision
270
+ }
271
+ @packed_message = generate_signed_message_for(@deployment_spec)
272
+
273
+ assert_raised_with_message("S3Revision in Deployment Spec must specify Bucket, Key and BundleType") do
274
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
275
+ end
276
+ end
277
+
278
+ should "raise when BundleType is missing" do
279
+ @s3Revision = {
280
+ "Bucket" => "mybucket",
281
+ "Key" => "mykey"
282
+ }
283
+ @revision = {
284
+ "RevisionType" => "S3",
285
+ "S3Revision" => @s3Revision
286
+ }
287
+ @deployment_spec = {
288
+ "DeploymentId" => @deployment_id,
289
+ "DeploymentGroupId" => @deployment_group_id,
290
+ "Revision" => @revision
291
+ }
292
+ @packed_message = generate_signed_message_for(@deployment_spec)
293
+
294
+ assert_raised_with_message("S3Revision in Deployment Spec must specify Bucket, Key and BundleType") do
295
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
296
+ end
297
+ end
298
+
299
+ should "raise when bundle type is not a supported format" do
300
+ @s3Revision = {
301
+ "Bucket" => "mybucket",
302
+ "Key" => "mykey",
303
+ "BundleType" => "bar"
304
+ }
305
+ @revision = {
306
+ "RevisionType" => "S3",
307
+ "S3Revision" => @s3Revision
308
+ }
309
+ @deployment_spec = {
310
+ "DeploymentId" => @deployment_id,
311
+ "DeploymentGroupId" => @deployment_group_id,
312
+ "Revision" => @revision
313
+ }
314
+ @packed_message = generate_signed_message_for(@deployment_spec)
315
+
316
+ assert_raised_with_message("BundleType in S3Revision must be tar, tgz or zip") do
317
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
318
+ end
319
+ end
320
+
321
+ should "raise when JSON submitted as PKCS7/JSON" do
322
+ @packed_message.payload = @deployment_spec.to_json
323
+
324
+ assert_raised_with_message("Could not parse the PKCS7: nested asn1 error") do
325
+ begin
326
+ InstanceAgent::CodeDeployPlugin::DeploymentSpecification.parse(@packed_message)
327
+ rescue ArgumentError => e
328
+ raise e.message
329
+ end
330
+ end
331
+ end
332
+ end
333
+ end
334
+ end
335
+
@@ -0,0 +1,250 @@
1
+ require 'test_helper'
2
+ require 'stringio'
3
+ require 'fileutils'
4
+ require 'instance_agent/codedeploy_plugin/installer'
5
+ require 'com/amazon/codedeploy/command/v20141006/host_command_instance'
6
+
7
+ class HookExecutorTest < InstanceAgentTestCase
8
+
9
+ include InstanceAgent::CodeDeployPlugin
10
+
11
+ def create_full_hook_executor
12
+ HookExecutor.new ({:lifecycle_event => @lifecycle_event,
13
+ :deployment_root_dir => @deployment_root_dir,
14
+ :last_successful_deployment_dir => @last_successful_deployment_dir,
15
+ :app_spec_path => @app_spec_path})
16
+ end
17
+
18
+ context "testing hook executor" do
19
+ setup do
20
+ @deployment_root_dir = "deployment/root/dir"
21
+ @last_successful_deployment_dir = "last/deployment/root/dir"
22
+ @app_spec_path = "app_spec"
23
+ @app_spec = { "version" => 0.0, "os" => "linux" }
24
+ YAML.stubs(:load).returns(@app_spec)
25
+ end
26
+
27
+ context "when creating a hook command" do
28
+ context "first deployment pre-download scripts" do
29
+ setup do
30
+ File.stubs(:exist?).returns(false)
31
+ @lifecycle_event = "ApplicationStop"
32
+ end
33
+
34
+ should "do nothing" do
35
+ @hook_executor = HookExecutor.new ({:lifecycle_event => @lifecycle_event,
36
+ :deployment_root_dir => @deployment_root_dir,
37
+ :app_spec_path => @app_spec_path})
38
+ end
39
+ end
40
+
41
+ context "first deployment post-download scripts" do
42
+ setup do
43
+ File.stubs(:exist?).returns(false)
44
+ @lifecycle_event = "ValidateService"
45
+ end
46
+
47
+ should "raise an error" do
48
+ assert_raise do
49
+ @hook_executor = HookExecutor.new ({:lifecycle_event => @lifecycle_event,
50
+ :deployment_root_dir => @deployment_root_dir})
51
+ end
52
+ end
53
+ end
54
+
55
+ context "all information provided" do
56
+ setup do
57
+ @lifecycle_event = "ValidateService"
58
+ ApplicationSpecification.stubs(:parse)
59
+ end
60
+
61
+ should "parse an app spec from the current deployments directory" do
62
+ File.expects(:read).with(File.join(@deployment_root_dir, 'deployment-archive', @app_spec_path))
63
+ @hook_executor = create_full_hook_executor
64
+ end
65
+
66
+ context "hook is before download bundle" do
67
+ setup do
68
+ @lifecycle_event = "ApplicationStop"
69
+ end
70
+
71
+ should "parse an app spec from the previous deployment's directory" do
72
+ File.expects(:read).with(File.join(@last_successful_deployment_dir, 'deployment-archive', @app_spec_path))
73
+ @hook_executor = create_full_hook_executor
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ context "when executing a hook command" do
80
+ setup do
81
+ @lifecycle_event = "ValidateService"
82
+ File.stubs(:read).with(File.join(@deployment_root_dir, 'deployment-archive', @app_spec_path))
83
+ end
84
+
85
+ context "no scripts to run for a given hook" do
86
+ setup do
87
+ @app_spec = {"version" => 0.0, "os" => "linux", "hooks" => {}}
88
+ YAML.stubs(:load).returns(@app_spec)
89
+ @hook_executor = create_full_hook_executor
90
+ end
91
+
92
+ should "do nothing" do
93
+ @hook_executor.execute
94
+ end
95
+ end
96
+
97
+ context "running with a single basic script" do
98
+ setup do
99
+ @app_spec = {"version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=>[{'location'=>'test'}]}}
100
+ YAML.stubs(:load).returns(@app_spec)
101
+ @script_location = File.join(@deployment_root_dir, 'deployment-archive', 'test')
102
+ @hook_executor = create_full_hook_executor
103
+ end
104
+
105
+ context "when hook script doesn't exist" do
106
+ setup do
107
+ File.stubs(:exist?).with(@script_location).returns(false)
108
+ end
109
+
110
+ should "raise and exception" do
111
+ assert_raised_with_message('Script does not exist at specified location: test', ScriptError)do
112
+ @hook_executor.execute
113
+ end
114
+ end
115
+ end
116
+
117
+ context "when the file exists" do
118
+ setup do
119
+ File.stubs(:exist?).with(@script_location).returns(true)
120
+ end
121
+
122
+ context "and isn't executable" do
123
+ setup do
124
+ 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.')
126
+ end
127
+
128
+ should "log and make the hook script executable" do
129
+ FileUtils.expects(:chmod)#.with("+x", @script_location)
130
+ assert_raised_with_message('No such file or directory - deployment/root/dir/deployment-archive/test', Errno::ENOENT) do
131
+ @hook_executor.execute
132
+ end
133
+ end
134
+
135
+ context "and setting executable fails" do
136
+ setup do
137
+ FileUtils.stubs(:chmod).raises("An exception")
138
+ end
139
+
140
+ should "raise an exception" do
141
+ assert_raised_with_message('Unable to set script at specified location: test as executable', ScriptError) do
142
+ @hook_executor.execute
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ context "files are executable (both intial checks pass)" do
149
+ setup do
150
+ File.stubs(:executable?).with(@script_location).returns(true)
151
+ @mock_pipe = mock
152
+ dummy_array = mock
153
+ @mock_pipe.stubs(:each_line).returns(dummy_array)
154
+ @mock_pipe.stubs(:close)
155
+ dummy_array.stubs(:each).returns(nil)
156
+ @wait_thr = mock
157
+ @value = mock
158
+ @wait_thr.stubs(:value).returns(@value)
159
+ @wait_thr.stubs(:join).returns(1000)
160
+ end
161
+
162
+ context "scripts timeout" do
163
+ setup do
164
+ @app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test", "timeout"=>"30"}]}}
165
+ YAML.stubs(:load).returns(@app_spec)
166
+ @hook_executor = create_full_hook_executor
167
+ @wait_thr.stubs(:join).with(30).returns(nil)
168
+ @wait_thr.stubs(:pid)
169
+ 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
+ end
173
+
174
+ should "raise and exception" do
175
+ assert_raised_with_message('Script at specified location: test failed to complete in 30 seconds', ScriptError) do
176
+ @hook_executor.execute
177
+ end
178
+ end
179
+ end
180
+
181
+ context "Scripts run with a runas" do
182
+ setup do
183
+ @app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test", "runas"=>"user"}]}}
184
+ YAML.stubs(:load).returns(@app_spec)
185
+ @hook_executor = create_full_hook_executor
186
+ mock_pipe = mock
187
+ Open3.stubs(:popen3).with('su user -c ' + @script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
188
+ end
189
+
190
+ context "scripts fail" do
191
+ setup do
192
+ @value.stubs(:exitstatus).returns(1)
193
+ end
194
+
195
+ should "raise an exception" do
196
+ assert_raised_with_message('Script at specified location: test run as user user failed with exit code 1', ScriptError) do
197
+ @hook_executor.execute
198
+ end
199
+ end
200
+ end
201
+
202
+ context "scripts pass" do
203
+ setup do
204
+ @value.stubs(:exitstatus).returns(0)
205
+ end
206
+
207
+ 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])
209
+ @hook_executor.execute
210
+ end
211
+ end
212
+ end
213
+
214
+ context "Scripts run without a runas" do
215
+ setup do
216
+ @app_spec = { "version" => 0.0, "os" => "linux", "hooks" => {'ValidateService'=> [{"location"=>"test"}]}}
217
+ YAML.stubs(:load).returns(@app_spec)
218
+ @hook_executor = create_full_hook_executor
219
+ Open3.stubs(:popen3).with(@script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
220
+ end
221
+
222
+ context "Scripts fail" do
223
+ setup do
224
+ @value.stubs(:exitstatus).returns(1)
225
+ end
226
+
227
+ should "raise an exception" do
228
+ assert_raised_with_message('Script at specified location: test failed with exit code 1', ScriptError) do
229
+ @hook_executor.execute
230
+ end
231
+ end
232
+ end
233
+
234
+ context "Scripts pass" do
235
+ setup do
236
+ @value.stubs(:exitstatus).returns(0)
237
+ end
238
+
239
+ should "execute script" do
240
+ Open3.expects(:popen3).with(@script_location, :pgroup=>true).yields([@mock_pipe,@mock_pipe,@mock_pipe,@wait_thr])
241
+ @hook_executor.execute
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end