simple_deploy 0.5.6 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -0
- data/CHANGELOG +8 -0
- data/README.md +2 -0
- data/lib/simple_deploy/cli/execute.rb +57 -0
- data/lib/simple_deploy/cli.rb +5 -2
- data/lib/simple_deploy/logger.rb +7 -0
- data/lib/simple_deploy/stack/deployment/status.rb +4 -4
- data/lib/simple_deploy/stack/deployment.rb +50 -86
- data/lib/simple_deploy/stack/execute.rb +36 -0
- data/lib/simple_deploy/stack/ssh.rb +93 -0
- data/lib/simple_deploy/stack.rb +15 -1
- data/lib/simple_deploy/version.rb +1 -1
- data/simple_deploy.gemspec +6 -5
- data/spec/logger_spec.rb +29 -23
- data/spec/stack/deployment/status_spec.rb +63 -1
- data/spec/stack/deployment_spec.rb +120 -90
- data/spec/stack/execute_spec.rb +27 -0
- data/spec/stack/ssh_spec.rb +86 -0
- data/spec/stack_spec.rb +67 -15
- metadata +47 -18
- data/script/ci_setup +0 -16
@@ -3,19 +3,20 @@ require 'spec_helper'
|
|
3
3
|
describe SimpleDeploy do
|
4
4
|
|
5
5
|
before do
|
6
|
-
@attributes = { 'key'
|
7
|
-
'
|
8
|
-
'chef_repo' => 'chef_repo',
|
6
|
+
@attributes = { 'key' => 'val',
|
7
|
+
'chef_repo' => 'chef_repo',
|
9
8
|
'chef_repo_bucket_prefix' => 'chef_repo_bp',
|
10
|
-
'chef_repo_domain'
|
11
|
-
'app'
|
12
|
-
'app_bucket_prefix'
|
13
|
-
'app_domain'
|
14
|
-
'cookbooks'
|
9
|
+
'chef_repo_domain' => 'chef_repo_d',
|
10
|
+
'app' => 'app',
|
11
|
+
'app_bucket_prefix' => 'app_bp',
|
12
|
+
'app_domain' => 'app_d',
|
13
|
+
'cookbooks' => 'cookbooks',
|
15
14
|
'cookbooks_bucket_prefix' => 'cookbooks_bp',
|
16
|
-
'cookbooks_domain'
|
15
|
+
'cookbooks_domain' => 'cookbooks_d' }
|
17
16
|
@logger_stub = stub 'logger stub'
|
18
|
-
@logger_stub.stub :debug => 'true',
|
17
|
+
@logger_stub.stub :debug => 'true',
|
18
|
+
:info => 'true',
|
19
|
+
:error => 'true'
|
19
20
|
|
20
21
|
@config_mock = mock 'config mock'
|
21
22
|
@config_mock.stub(:logger) { @logger_stub }
|
@@ -24,6 +25,8 @@ describe SimpleDeploy do
|
|
24
25
|
@stack_mock = mock 'stack mock'
|
25
26
|
@stack_mock.stub(:attributes) { @attributes }
|
26
27
|
|
28
|
+
@status_mock = mock 'status mock'
|
29
|
+
|
27
30
|
options = { :config => @config_mock,
|
28
31
|
:instances => ['1.2.3.4', '4.3.2.1'],
|
29
32
|
:environment => 'test-us-west-1',
|
@@ -31,112 +34,139 @@ describe SimpleDeploy do
|
|
31
34
|
:ssh_key => 'key',
|
32
35
|
:stack => @stack_mock,
|
33
36
|
:name => 'stack-name' }
|
34
|
-
@
|
37
|
+
@deployment = SimpleDeploy::Stack::Deployment.new options
|
38
|
+
@deployment.stub(:sleep) { false }
|
35
39
|
end
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
41
|
+
context "manage locks" do
|
42
|
+
before do
|
43
|
+
status_options = { :name => 'stack-name',
|
44
|
+
:environment => 'test-us-west-1',
|
45
|
+
:ssh_user => 'user',
|
46
|
+
:config => @config_mock,
|
47
|
+
:stack => @stack_mock }
|
48
|
+
SimpleDeploy::Stack::Deployment::Status.should_receive(:new).
|
49
|
+
with(status_options).
|
50
|
+
and_return @status_mock
|
51
|
+
end
|
40
52
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
:ssh_user => 'user',
|
47
|
-
:ssh_key => 'key',
|
48
|
-
:stack => @stack_mock,
|
49
|
-
:name => 'stack-name' }
|
50
|
-
stack = SimpleDeploy::Stack::Deployment.new options
|
51
|
-
|
52
|
-
expect {
|
53
|
-
stack.create_deployment
|
54
|
-
}.to raise_error(RuntimeError, 'There are no running instances to deploy to')
|
53
|
+
describe "clear_for_deployment?" do
|
54
|
+
it "should test the clear_for_deployment method" do
|
55
|
+
@status_mock.stub :clear_for_deployment? => true
|
56
|
+
@deployment.clear_for_deployment?.should be_true
|
57
|
+
end
|
55
58
|
end
|
59
|
+
|
60
|
+
describe "clear_deployment_lock" do
|
61
|
+
it "should test the clear_deployment_lock" do
|
62
|
+
@status_mock.should_receive(:clear_deployment_lock).
|
63
|
+
with(true).
|
64
|
+
and_return true
|
65
|
+
@deployment.clear_deployment_lock(true).should be_true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
56
69
|
end
|
57
70
|
|
58
71
|
describe "executing a deploy" do
|
59
72
|
before do
|
60
|
-
@
|
61
|
-
@
|
62
|
-
@
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
@
|
69
|
-
|
70
|
-
@variables_mock.should_receive(:[]=).
|
71
|
-
with :ssh_options, ( { :keys => 'key',
|
72
|
-
:paranoid => false } )
|
73
|
-
@deployment_mock.should_receive(:server).with '1.2.3.4', :instances
|
74
|
-
@deployment_mock.should_receive(:server).with '4.3.2.1', :instances
|
75
|
-
@config_mock.should_receive(:artifacts).
|
76
|
-
and_return ['cookbooks']
|
77
|
-
@config_mock.should_receive(:artifact_deploy_variable).with('cookbooks').
|
78
|
-
and_return 'deploy_var'
|
79
|
-
SimpleDeploy::Artifact.should_receive(:new).and_return @artifact_mock
|
80
|
-
@artifact_mock.should_receive(:endpoints).
|
81
|
-
and_return('s3' => 's3://bucket/dir/key')
|
82
|
-
@stack_mock.should_receive(:instances).exactly(2).times.
|
83
|
-
and_return [ { 'instancesSet' =>
|
84
|
-
[ { 'privateIpAddress' => '10.1.2.3' } ] } ]
|
85
|
-
@config_mock.should_receive(:deploy_script).and_return 'script.sh'
|
86
|
-
@deployment_mock.should_receive(:load).with({:string=>"task :simpledeploy do\n sudo 'env deploy_var=s3://bucket/dir/key PRIMARY_HOST=10.1.2.3 script.sh'\n end"}).and_return true
|
87
|
-
@stack.create_deployment
|
88
|
-
end
|
89
|
-
|
90
|
-
it "should deploy if the stack is clear to deploy" do
|
91
|
-
status_mock = mock 'status mock'
|
73
|
+
@config_mock.stub(:artifacts) { ['chef_repo', 'cookbooks', 'app'] }
|
74
|
+
@config_mock.stub(:deploy_script) { '/tmp/script' }
|
75
|
+
@stack_mock.stub(:instances) { [ { 'instancesSet' =>
|
76
|
+
[ { 'privateIpAddress' => '10.1.2.3' } ] } ] }
|
77
|
+
|
78
|
+
status_options = { :name => 'stack-name',
|
79
|
+
:environment => 'test-us-west-1',
|
80
|
+
:ssh_user => 'user',
|
81
|
+
:config => @config_mock,
|
82
|
+
:stack => @stack_mock }
|
92
83
|
SimpleDeploy::Stack::Deployment::Status.should_receive(:new).
|
93
|
-
|
94
|
-
|
95
|
-
status_mock.should_receive(:set_deployment_in_progress)
|
96
|
-
@deployment_mock.should_receive(:simpledeploy)
|
97
|
-
status_mock.should_receive(:unset_deployment_in_progress)
|
98
|
-
|
99
|
-
@stack.execute.should == true
|
84
|
+
with(status_options).
|
85
|
+
and_return @status_mock
|
100
86
|
end
|
101
87
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
88
|
+
describe "when succesful" do
|
89
|
+
before do
|
90
|
+
@execute_mock = mock "execute"
|
91
|
+
execute_options = { :name => 'stack-name',
|
92
|
+
:environment => 'test-us-west-1',
|
93
|
+
:instances => ['1.2.3.4', '4.3.2.1'],
|
94
|
+
:ssh_user => 'user',
|
95
|
+
:ssh_key => 'key',
|
96
|
+
:config => @config_mock,
|
97
|
+
:stack => @stack_mock }
|
98
|
+
SimpleDeploy::Stack::Execute.should_receive(:new).
|
99
|
+
with(execute_options).
|
100
|
+
and_return @execute_mock
|
101
|
+
@config_mock.should_receive(:artifact_deploy_variable).
|
102
|
+
with("cookbooks").
|
103
|
+
and_return('CHEF_REPO_URL')
|
104
|
+
@config_mock.should_receive(:artifact_deploy_variable).
|
105
|
+
with("app").
|
106
|
+
and_return('APP_URL')
|
107
|
+
@config_mock.should_receive(:artifact_deploy_variable).
|
108
|
+
with("chef_repo").
|
109
|
+
and_return('CHEF_REPO_URL')
|
110
|
+
@execute_mock.should_receive(:execute).
|
111
|
+
with( {:sudo=>true, :command=>"env CHEF_REPO_URL=s3://cookbooks_bp-test-us-west-1/cookbooks_d/cookbooks.tar.gz APP_URL=s3://app_bp-test-us-west-1/app_d/app.tar.gz PRIMARY_HOST=10.1.2.3 /tmp/script"} )
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should deploy if the stack is clear to deploy" do
|
115
|
+
@status_mock.stub :clear_for_deployment? => true
|
116
|
+
@status_mock.should_receive(:set_deployment_in_progress)
|
117
|
+
@status_mock.should_receive(:unset_deployment_in_progress)
|
118
|
+
@deployment.execute(false).should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should deploy if the stack is not clear to deploy but forced and clear in time" do
|
122
|
+
@status_mock.should_receive(:clear_for_deployment?).
|
123
|
+
and_return(false)
|
124
|
+
@status_mock.should_receive(:clear_deployment_lock).
|
125
|
+
with(true)
|
126
|
+
@status_mock.should_receive(:clear_for_deployment?).
|
127
|
+
exactly(2).times.
|
128
|
+
and_return(true)
|
129
|
+
@status_mock.should_receive(:set_deployment_in_progress)
|
130
|
+
@status_mock.should_receive(:unset_deployment_in_progress)
|
131
|
+
@deployment.execute(true).should be_true
|
132
|
+
end
|
114
133
|
|
115
|
-
|
116
|
-
status_mock = mock 'status mock'
|
117
|
-
SimpleDeploy::Stack::Deployment::Status.should_receive(:new).
|
118
|
-
and_return status_mock
|
119
|
-
status_mock.stub(:clear_for_deployment?).and_return false
|
120
|
-
@logger_stub.should_receive(:error)
|
134
|
+
end
|
121
135
|
|
122
|
-
|
136
|
+
describe "when unsuccesful" do
|
137
|
+
it "should not deploy if the stack is not clear to deploy but forced however does not clear in time" do
|
138
|
+
@status_mock.stub(:clear_for_deployment?) { false }
|
139
|
+
@status_mock.should_receive(:clear_deployment_lock).
|
140
|
+
with(true)
|
141
|
+
@deployment.execute(true).should be_false
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should not deploy if the stack is not clear to deploy and not forced" do
|
145
|
+
@status_mock.should_receive(:clear_deployment_lock).never
|
146
|
+
@status_mock.stub :clear_for_deployment? => false
|
147
|
+
@deployment.execute(false).should be_false
|
148
|
+
end
|
123
149
|
end
|
124
150
|
end
|
125
151
|
|
126
152
|
describe "get_artifact_endpoints" do
|
127
153
|
before do
|
128
154
|
@config_mock.stub(:artifacts) { ['chef_repo', 'cookbooks', 'app'] }
|
129
|
-
@config_mock.should_receive(:artifact_deploy_variable).
|
130
|
-
|
131
|
-
@config_mock.should_receive(:artifact_deploy_variable).
|
155
|
+
@config_mock.should_receive(:artifact_deploy_variable).
|
156
|
+
with('chef_repo').and_return('CHEF_REPO_URL')
|
157
|
+
@config_mock.should_receive(:artifact_deploy_variable).
|
158
|
+
with('app').and_return('APP_URL')
|
159
|
+
@config_mock.should_receive(:artifact_deploy_variable).
|
160
|
+
with('cookbooks').and_return('COOKBOOKS_URL')
|
132
161
|
end
|
133
162
|
|
134
163
|
it "should create S3 endpoints" do
|
135
|
-
endpoints = @
|
164
|
+
endpoints = @deployment.send :get_artifact_endpoints
|
136
165
|
|
137
166
|
endpoints['CHEF_REPO_URL'].should == 's3://chef_repo_bp-test-us-west-1/chef_repo_d/chef_repo.tar.gz'
|
138
167
|
endpoints['APP_URL'].should == 's3://app_bp-test-us-west-1/app_d/app.tar.gz'
|
139
168
|
endpoints['COOKBOOKS_URL'].should == 's3://cookbooks_bp-test-us-west-1/cookbooks_d/cookbooks.tar.gz'
|
140
169
|
end
|
170
|
+
|
141
171
|
end
|
142
172
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy::Stack::Execute do
|
4
|
+
before do
|
5
|
+
@ssh_mock = mock 'ssh'
|
6
|
+
options = { :config => @config,
|
7
|
+
:instances => @instances,
|
8
|
+
:environment => @environment,
|
9
|
+
:ssh_user => @ssh_user,
|
10
|
+
:ssh_key => @ssh_key,
|
11
|
+
:stack => @stack,
|
12
|
+
:name => @name }
|
13
|
+
|
14
|
+
SimpleDeploy::Stack::SSH.should_receive(:new).
|
15
|
+
with(options).
|
16
|
+
and_return @ssh_mock
|
17
|
+
@execute = SimpleDeploy::Stack::Execute.new options
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should call execute with the given options" do
|
21
|
+
options = { :sudo => true, :command => 'uname' }
|
22
|
+
@ssh_mock.should_receive(:execute).
|
23
|
+
with(options).
|
24
|
+
and_return true
|
25
|
+
@execute.execute(options).should be_true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleDeploy::Stack::SSH do
|
4
|
+
before do
|
5
|
+
@stack_mock = mock 'stack'
|
6
|
+
@task_mock = mock 'task'
|
7
|
+
@config_mock = mock 'config'
|
8
|
+
@logger_stub = stub 'logger', :debug => true,
|
9
|
+
:info => true,
|
10
|
+
:error => true
|
11
|
+
@config_mock.stub :logger => @logger_stub
|
12
|
+
@config_mock.should_receive(:region).
|
13
|
+
with('test-env').
|
14
|
+
and_return 'test-us-west-1'
|
15
|
+
@stack_mock.stub :attributes => { :ssh_gateway => false }
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when unsuccessful" do
|
19
|
+
it "should notify the user there are no running instances" do
|
20
|
+
options = { :config => @config_mock,
|
21
|
+
:instances => [],
|
22
|
+
:environment => 'test-env',
|
23
|
+
:ssh_user => 'user',
|
24
|
+
:ssh_key => 'key',
|
25
|
+
:stack => @stack_mock,
|
26
|
+
:name => 'test-stack' }
|
27
|
+
@ssh = SimpleDeploy::Stack::SSH.new options
|
28
|
+
error = 'There are no running instances to execute this command.'
|
29
|
+
expect { @ssh.execute(:sudo => true,
|
30
|
+
:command => 'uname') }.to raise_error(RuntimeError, error)
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when successful" do
|
36
|
+
before do
|
37
|
+
options = { :config => @config_mock,
|
38
|
+
:instances => ['1.2.3.4', '4.3.2.1'],
|
39
|
+
:environment => 'test-env',
|
40
|
+
:ssh_user => 'user',
|
41
|
+
:ssh_key => 'key',
|
42
|
+
:stack => @stack_mock,
|
43
|
+
:name => 'test-stack' }
|
44
|
+
@ssh = SimpleDeploy::Stack::SSH.new options
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "when execute called" do
|
48
|
+
before do
|
49
|
+
task_logger_mock = mock 'task_logger'
|
50
|
+
@ssh_options = Hash.new
|
51
|
+
Capistrano::Configuration.should_receive(:new).
|
52
|
+
with(:output => @logger_stub).
|
53
|
+
and_return @task_mock
|
54
|
+
@task_mock.stub :logger => task_logger_mock,
|
55
|
+
:variables => @ssh_options
|
56
|
+
task_logger_mock.should_receive(:level=).with(3)
|
57
|
+
@task_mock.should_receive(:set).with :user, 'user'
|
58
|
+
@task_mock.should_receive(:server).with('1.2.3.4', :instances)
|
59
|
+
@task_mock.should_receive(:server).with('4.3.2.1', :instances)
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "when succesful" do
|
63
|
+
it "should execute a task with sudo" do
|
64
|
+
@task_mock.should_receive(:load).with({:string=>"task :execute do\n sudo 'uname'\n end"})
|
65
|
+
@task_mock.should_receive(:execute).and_return true
|
66
|
+
@ssh.execute(:sudo => true,
|
67
|
+
:command => 'uname').should be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should execute a task as the calling user " do
|
71
|
+
@task_mock.should_receive(:load).with({:string=>"task :execute do\n run 'uname'\n end"})
|
72
|
+
@task_mock.should_receive(:execute).and_return true
|
73
|
+
@ssh.execute(:sudo => false,
|
74
|
+
:command => 'uname').should be_true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
after do
|
79
|
+
@ssh_options.should == { :ssh_options => {
|
80
|
+
:keys => 'key', :paranoid => false
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/spec/stack_spec.rb
CHANGED
@@ -98,6 +98,7 @@ describe SimpleDeploy do
|
|
98
98
|
deployment_mock.should_receive(:clear_for_deployment?).and_return(false, true, true)
|
99
99
|
deployment_mock.should_receive(:clear_deployment_lock).with(true)
|
100
100
|
@stack.stub(:deployment).and_return(deployment_mock)
|
101
|
+
@stack.stub(:sleep).and_return(false)
|
101
102
|
|
102
103
|
Stackster::Stack.should_receive(:new).with(:environment => 'test-env',
|
103
104
|
:name => 'test-stack',
|
@@ -167,10 +168,10 @@ describe SimpleDeploy do
|
|
167
168
|
|
168
169
|
it 'should use the private IP when vpc' do
|
169
170
|
stack = SimpleDeploy::Stack.new :environment => 'test-env',
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
171
|
+
:name => 'test-stack',
|
172
|
+
:logger => 'my-logger',
|
173
|
+
:config => @config_stub,
|
174
|
+
:internal => false
|
174
175
|
stack.stub(:stack) { @stack_mock }
|
175
176
|
|
176
177
|
@instances.first['instancesSet'].first['vpcId'] = 'my-vpc'
|
@@ -181,10 +182,10 @@ describe SimpleDeploy do
|
|
181
182
|
|
182
183
|
it 'should use the private IP when internal' do
|
183
184
|
stack = SimpleDeploy::Stack.new :environment => 'test-env',
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
185
|
+
:name => 'test-stack',
|
186
|
+
:logger => 'my-logger',
|
187
|
+
:config => @config_stub,
|
188
|
+
:internal => true
|
188
189
|
stack.stub(:stack) { @stack_mock }
|
189
190
|
@stack_mock.stub(:instances).and_return(@instances)
|
190
191
|
|
@@ -193,10 +194,10 @@ describe SimpleDeploy do
|
|
193
194
|
|
194
195
|
it 'should use the public IP when not vpc and not internal' do
|
195
196
|
stack = SimpleDeploy::Stack.new :environment => 'test-env',
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
197
|
+
:name => 'test-stack',
|
198
|
+
:logger => 'my-logger',
|
199
|
+
:config => @config_stub,
|
200
|
+
:internal => false
|
200
201
|
stack.stub(:stack) { @stack_mock }
|
201
202
|
@stack_mock.stub(:instances).and_return(@instances)
|
202
203
|
|
@@ -209,14 +210,65 @@ describe SimpleDeploy do
|
|
209
210
|
{ 'ipAddress' => '50.40.30.21', 'privateIpAddress' => '10.1.2.4' }] }]
|
210
211
|
|
211
212
|
stack = SimpleDeploy::Stack.new :environment => 'test-env',
|
213
|
+
:name => 'test-stack',
|
214
|
+
:logger => 'my-logger',
|
215
|
+
:config => @config_stub,
|
216
|
+
:internal => false
|
217
|
+
stack.stub(:stack) { @stack_mock }
|
218
|
+
@stack_mock.stub(:instances).and_return(@instances)
|
219
|
+
|
220
|
+
stack.instances.should == ['50.40.30.20', '50.40.30.21']
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe 'deploy' do
|
225
|
+
before do
|
226
|
+
@stack = SimpleDeploy::Stack.new :environment => 'test-env',
|
212
227
|
:name => 'test-stack',
|
213
228
|
:logger => 'my-logger',
|
214
229
|
:config => @config_stub,
|
215
230
|
:internal => false
|
216
|
-
|
217
|
-
@
|
231
|
+
@deployment_mock = mock "deployment"
|
232
|
+
@stack.stub(:deployment).and_return(@deployment_mock)
|
233
|
+
end
|
218
234
|
|
219
|
-
|
235
|
+
it "should call exec on deployment" do
|
236
|
+
@deployment_mock.should_receive(:execute).with(true).and_return true
|
237
|
+
@stack.deploy(true).should be_true
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should not force the deployment by default" do
|
241
|
+
@deployment_mock.should_receive(:execute).with(false).and_return true
|
242
|
+
@stack.deploy.should be_true
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should return false if the deployment fails" do
|
246
|
+
@deployment_mock.should_receive(:execute).with(false).and_return false
|
247
|
+
@stack.deploy.should be_false
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe 'execute' do
|
252
|
+
before do
|
253
|
+
@stack = SimpleDeploy::Stack.new :environment => 'test-env',
|
254
|
+
:name => 'test-stack',
|
255
|
+
:logger => 'my-logger',
|
256
|
+
:config => @config_stub,
|
257
|
+
:internal => false
|
258
|
+
@execute_mock = mock "execute"
|
259
|
+
@stack.stub(:executer).and_return(@execute_mock)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should call exec with the given args" do
|
263
|
+
@execute_mock.should_receive(:execute).
|
264
|
+
with(:arg => 'val').and_return true
|
265
|
+
@stack.execute(:arg => 'val').should be_true
|
266
|
+
end
|
267
|
+
|
268
|
+
it "should return false if the exec fails" do
|
269
|
+
@execute_mock.should_receive(:execute).
|
270
|
+
with(:arg => 'val').and_return false
|
271
|
+
@stack.execute(:arg => 'val').should be_false
|
220
272
|
end
|
221
273
|
end
|
222
274
|
end
|