capistrano 2.0.0 → 2.15.2
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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +7 -0
- data/CHANGELOG +715 -18
- data/Gemfile +12 -0
- data/README.md +94 -0
- data/Rakefile +11 -0
- data/bin/cap +0 -0
- data/bin/capify +37 -22
- data/capistrano.gemspec +40 -0
- data/lib/capistrano/callback.rb +5 -1
- data/lib/capistrano/cli/execute.rb +10 -7
- data/lib/capistrano/cli/help.rb +39 -16
- data/lib/capistrano/cli/help.txt +44 -16
- data/lib/capistrano/cli/options.rb +71 -11
- data/lib/capistrano/cli/ui.rb +13 -1
- data/lib/capistrano/cli.rb +5 -5
- data/lib/capistrano/command.rb +215 -58
- data/lib/capistrano/configuration/actions/file_transfer.rb +29 -14
- data/lib/capistrano/configuration/actions/inspect.rb +3 -3
- data/lib/capistrano/configuration/actions/invocation.rb +212 -22
- data/lib/capistrano/configuration/alias_task.rb +26 -0
- data/lib/capistrano/configuration/callbacks.rb +26 -27
- data/lib/capistrano/configuration/connections.rb +130 -52
- data/lib/capistrano/configuration/execution.rb +34 -18
- data/lib/capistrano/configuration/loading.rb +91 -6
- data/lib/capistrano/configuration/log_formatters.rb +75 -0
- data/lib/capistrano/configuration/namespaces.rb +45 -12
- data/lib/capistrano/configuration/roles.rb +28 -2
- data/lib/capistrano/configuration/servers.rb +51 -10
- data/lib/capistrano/configuration/variables.rb +3 -3
- data/lib/capistrano/configuration.rb +20 -4
- data/lib/capistrano/errors.rb +12 -8
- data/lib/capistrano/ext/multistage.rb +62 -0
- data/lib/capistrano/ext/string.rb +5 -0
- data/lib/capistrano/extensions.rb +1 -1
- data/lib/capistrano/fix_rake_deprecated_dsl.rb +8 -0
- data/lib/capistrano/logger.rb +112 -5
- data/lib/capistrano/processable.rb +55 -0
- data/lib/capistrano/recipes/compat.rb +2 -2
- data/lib/capistrano/recipes/deploy/assets.rb +185 -0
- data/lib/capistrano/recipes/deploy/dependencies.rb +2 -2
- data/lib/capistrano/recipes/deploy/local_dependency.rb +10 -2
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +54 -2
- data/lib/capistrano/recipes/deploy/scm/accurev.rb +169 -0
- data/lib/capistrano/recipes/deploy/scm/base.rb +31 -11
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +14 -14
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +10 -8
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +12 -1
- data/lib/capistrano/recipes/deploy/scm/git.rb +293 -0
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +23 -15
- data/lib/capistrano/recipes/deploy/scm/none.rb +55 -0
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +54 -28
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +35 -17
- data/lib/capistrano/recipes/deploy/scm.rb +1 -1
- data/lib/capistrano/recipes/deploy/strategy/base.rb +32 -4
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +238 -43
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +1 -1
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +11 -1
- data/lib/capistrano/recipes/deploy/strategy/unshared_remote_cache.rb +21 -0
- data/lib/capistrano/recipes/deploy/strategy.rb +1 -1
- data/lib/capistrano/recipes/deploy.rb +265 -123
- data/lib/capistrano/recipes/standard.rb +1 -1
- data/lib/capistrano/role.rb +102 -0
- data/lib/capistrano/server_definition.rb +6 -1
- data/lib/capistrano/shell.rb +30 -33
- data/lib/capistrano/ssh.rb +46 -60
- data/lib/capistrano/task_definition.rb +16 -8
- data/lib/capistrano/transfer.rb +218 -0
- data/lib/capistrano/version.rb +6 -17
- data/lib/capistrano.rb +4 -1
- data/test/cli/execute_test.rb +3 -3
- data/test/cli/help_test.rb +33 -7
- data/test/cli/options_test.rb +109 -6
- data/test/cli/ui_test.rb +2 -2
- data/test/cli_test.rb +3 -3
- data/test/command_test.rb +144 -124
- data/test/configuration/actions/file_transfer_test.rb +41 -20
- data/test/configuration/actions/inspect_test.rb +21 -7
- data/test/configuration/actions/invocation_test.rb +91 -30
- data/test/configuration/alias_task_test.rb +118 -0
- data/test/configuration/callbacks_test.rb +41 -46
- data/test/configuration/connections_test.rb +187 -36
- data/test/configuration/execution_test.rb +18 -2
- data/test/configuration/loading_test.rb +17 -4
- data/test/configuration/namespace_dsl_test.rb +54 -5
- data/test/configuration/roles_test.rb +114 -4
- data/test/configuration/servers_test.rb +97 -4
- data/test/configuration/variables_test.rb +12 -2
- data/test/configuration_test.rb +9 -13
- data/test/deploy/local_dependency_test.rb +76 -0
- data/test/deploy/remote_dependency_test.rb +146 -0
- data/test/deploy/scm/accurev_test.rb +23 -0
- data/test/deploy/scm/base_test.rb +1 -1
- data/test/deploy/scm/bzr_test.rb +51 -0
- data/test/deploy/scm/darcs_test.rb +37 -0
- data/test/deploy/scm/git_test.rb +221 -0
- data/test/deploy/scm/mercurial_test.rb +134 -0
- data/test/deploy/scm/none_test.rb +35 -0
- data/test/deploy/scm/perforce_test.rb +23 -0
- data/test/deploy/scm/subversion_test.rb +40 -0
- data/test/deploy/strategy/copy_test.rb +240 -26
- data/test/extensions_test.rb +2 -2
- data/test/logger_formatting_test.rb +149 -0
- data/test/logger_test.rb +13 -2
- data/test/recipes_test.rb +25 -0
- data/test/role_test.rb +11 -0
- data/test/server_definition_test.rb +15 -2
- data/test/shell_test.rb +33 -1
- data/test/ssh_test.rb +40 -24
- data/test/task_definition_test.rb +18 -2
- data/test/transfer_test.rb +168 -0
- data/test/utils.rb +27 -33
- metadata +215 -102
- data/MIT-LICENSE +0 -20
- data/README +0 -43
- data/examples/sample.rb +0 -14
- data/lib/capistrano/gateway.rb +0 -131
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/upgrade.rb +0 -33
- data/lib/capistrano/upload.rb +0 -146
- data/test/gateway_test.rb +0 -167
- data/test/upload_test.rb +0 -131
- data/test/version_test.rb +0 -24
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "utils"
|
|
2
2
|
require 'capistrano/configuration/connections'
|
|
3
3
|
|
|
4
4
|
class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
5
5
|
class MockConfig
|
|
6
6
|
attr_reader :original_initialize_called
|
|
7
7
|
attr_reader :values
|
|
8
|
+
attr_reader :dry_run
|
|
8
9
|
attr_accessor :current_task
|
|
9
10
|
|
|
10
11
|
def initialize
|
|
@@ -30,8 +31,9 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
30
31
|
def setup
|
|
31
32
|
@config = MockConfig.new
|
|
32
33
|
@config.stubs(:logger).returns(stub_everything)
|
|
34
|
+
Net::SSH.stubs(:configuration_for).returns({})
|
|
33
35
|
@ssh_options = {
|
|
34
|
-
:user => "
|
|
36
|
+
:user => "user",
|
|
35
37
|
:port => 8080,
|
|
36
38
|
:password => "g00b3r",
|
|
37
39
|
:ssh_options => { :debug => :verbose }
|
|
@@ -58,65 +60,111 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
58
60
|
assert_equal :session, @config.connection_factory.connect_to(server)
|
|
59
61
|
end
|
|
60
62
|
|
|
61
|
-
def
|
|
62
|
-
@config.values[:gateway] = "
|
|
63
|
-
|
|
64
|
-
Capistrano::
|
|
65
|
-
assert_instance_of Capistrano::Gateway, @config.connection_factory
|
|
63
|
+
def test_should_connect_through_gateway_if_gateway_variable_is_set
|
|
64
|
+
@config.values[:gateway] = "j@gateway"
|
|
65
|
+
Net::SSH::Gateway.expects(:new).with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
66
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
def test_connection_factory_as_gateway_should_honor_config_options
|
|
69
|
-
@config.values[:gateway] = "
|
|
70
|
+
@config.values[:gateway] = "gateway"
|
|
70
71
|
@config.values.update(@ssh_options)
|
|
71
|
-
|
|
72
|
-
assert_instance_of Capistrano::
|
|
72
|
+
Net::SSH::Gateway.expects(:new).with("gateway", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
73
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_an_array
|
|
77
|
+
@config.values[:gateway] = ["j@gateway1", "k@gateway2"]
|
|
78
|
+
gateway1 = mock
|
|
79
|
+
Net::SSH::Gateway.expects(:new).with("gateway1", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(gateway1)
|
|
80
|
+
gateway1.expects(:open).returns(65535)
|
|
81
|
+
Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
82
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_a_hash
|
|
86
|
+
@config.values[:gateway] = { ["j@gateway1", "k@gateway2"] => :default }
|
|
87
|
+
gateway1 = mock
|
|
88
|
+
Net::SSH::Gateway.expects(:new).with("gateway1", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(gateway1)
|
|
89
|
+
gateway1.expects(:open).returns(65535)
|
|
90
|
+
Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
91
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_connection_factory_as_gateway_should_share_gateway_between_connections
|
|
95
|
+
@config.values[:gateway] = "j@gateway"
|
|
96
|
+
Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
97
|
+
Capistrano::SSH.stubs(:connect).returns(stub_everything)
|
|
98
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
|
99
|
+
@config.establish_connections_to(server("capistrano"))
|
|
100
|
+
@config.establish_connections_to(server("another"))
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_connection_factory_as_gateway_should_share_gateway_between_like_connections_if_gateway_variable_is_a_hash
|
|
104
|
+
@config.values[:gateway] = { "j@gateway" => [ "capistrano", "another"] }
|
|
105
|
+
Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
106
|
+
Capistrano::SSH.stubs(:connect).returns(stub_everything)
|
|
107
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
|
108
|
+
@config.establish_connections_to(server("capistrano"))
|
|
109
|
+
@config.establish_connections_to(server("another"))
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_connection_factory_as_gateways_should_not_share_gateway_between_unlike_connections_if_gateway_variable_is_a_hash
|
|
113
|
+
@config.values[:gateway] = { "j@gateway" => [ "capistrano", "another"], "k@gateway2" => "yafhost" }
|
|
114
|
+
Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
115
|
+
Net::SSH::Gateway.expects(:new).once.with("gateway2", "k", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
|
116
|
+
Capistrano::SSH.stubs(:connect).returns(stub_everything)
|
|
117
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
|
118
|
+
@config.establish_connections_to(server("capistrano"))
|
|
119
|
+
@config.establish_connections_to(server("another"))
|
|
120
|
+
@config.establish_connections_to(server("yafhost"))
|
|
73
121
|
end
|
|
74
122
|
|
|
75
123
|
def test_establish_connections_to_should_accept_a_single_nonarray_parameter
|
|
76
124
|
Capistrano::SSH.expects(:connect).with { |s,| s.host == "capistrano" }.returns(:success)
|
|
77
125
|
assert @config.sessions.empty?
|
|
78
126
|
@config.establish_connections_to(server("capistrano"))
|
|
79
|
-
|
|
127
|
+
assert_equal ["capistrano"], @config.sessions.keys.map(&:host)
|
|
80
128
|
end
|
|
81
129
|
|
|
82
130
|
def test_establish_connections_to_should_accept_an_array
|
|
83
131
|
Capistrano::SSH.expects(:connect).times(3).returns(:success)
|
|
84
132
|
assert @config.sessions.empty?
|
|
85
133
|
@config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
|
|
86
|
-
|
|
134
|
+
assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map(&:host)
|
|
87
135
|
end
|
|
88
136
|
|
|
89
137
|
def test_establish_connections_to_should_not_attempt_to_reestablish_existing_connections
|
|
90
138
|
Capistrano::SSH.expects(:connect).times(2).returns(:success)
|
|
91
139
|
@config.sessions[server("cap1")] = :ok
|
|
92
140
|
@config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
|
|
93
|
-
|
|
141
|
+
assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map(&:host)
|
|
94
142
|
end
|
|
95
|
-
|
|
143
|
+
|
|
96
144
|
def test_establish_connections_to_should_raise_one_connection_error_on_failure
|
|
97
145
|
Capistrano::SSH.expects(:connect).times(2).raises(Exception)
|
|
98
146
|
assert_raises(Capistrano::ConnectionError) {
|
|
99
|
-
@config.establish_connections_to(%w(cap1 cap2)
|
|
147
|
+
@config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
|
|
100
148
|
}
|
|
101
149
|
end
|
|
102
150
|
|
|
103
151
|
def test_connection_error_should_include_accessor_with_host_array
|
|
104
152
|
Capistrano::SSH.expects(:connect).times(2).raises(Exception)
|
|
105
|
-
|
|
106
153
|
begin
|
|
107
|
-
@config.establish_connections_to(%w(cap1 cap2)
|
|
154
|
+
@config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
|
|
108
155
|
flunk "expected an exception to be raised"
|
|
109
156
|
rescue Capistrano::ConnectionError => e
|
|
110
157
|
assert e.respond_to?(:hosts)
|
|
111
|
-
assert_equal %w(cap1 cap2), e.hosts.map { |h| h.to_s }
|
|
158
|
+
assert_equal %w(cap1 cap2), e.hosts.map { |h| h.to_s }.sort
|
|
112
159
|
end
|
|
113
160
|
end
|
|
114
|
-
|
|
161
|
+
|
|
115
162
|
def test_connection_error_should_only_include_failed_hosts
|
|
116
|
-
Capistrano::SSH.expects(:connect).
|
|
163
|
+
Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
|
|
164
|
+
Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
|
|
117
165
|
|
|
118
166
|
begin
|
|
119
|
-
@config.establish_connections_to(%w(cap1 cap2)
|
|
167
|
+
@config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
|
|
120
168
|
flunk "expected an exception to be raised"
|
|
121
169
|
rescue Capistrano::ConnectionError => e
|
|
122
170
|
assert_equal %w(cap1), e.hosts.map { |h| h.to_s }
|
|
@@ -141,6 +189,11 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
141
189
|
assert_raises(Capistrano::NoMatchingServersError) { @config.execute_on_servers(:a => :b, :c => :d) { |list| } }
|
|
142
190
|
end
|
|
143
191
|
|
|
192
|
+
def test_execute_on_servers_without_current_task_should_not_raise_error_if_no_matching_servers_and_continue_on_no_matching_servers
|
|
193
|
+
@config.expects(:find_servers).with(:a => :b, :c => :d, :on_no_matching_servers => :continue).returns([])
|
|
194
|
+
assert_nothing_raised { @config.execute_on_servers(:a => :b, :c => :d, :on_no_matching_servers => :continue) { |list| } }
|
|
195
|
+
end
|
|
196
|
+
|
|
144
197
|
def test_execute_on_servers_should_raise_an_error_if_the_current_task_has_no_matching_servers_by_default
|
|
145
198
|
@config.current_task = mock_task
|
|
146
199
|
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([])
|
|
@@ -150,7 +203,27 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
150
203
|
end
|
|
151
204
|
end
|
|
152
205
|
end
|
|
153
|
-
|
|
206
|
+
|
|
207
|
+
def test_execute_on_servers_should_not_raise_an_error_if_the_current_task_has_no_matching_servers_by_default_and_continue_on_no_matching_servers
|
|
208
|
+
@config.current_task = mock_task(:on_no_matching_servers => :continue)
|
|
209
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([])
|
|
210
|
+
assert_nothing_raised do
|
|
211
|
+
@config.execute_on_servers do
|
|
212
|
+
flunk "should not get here"
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_execute_on_servers_should_not_raise_an_error_if_the_current_task_has_no_matching_servers_by_default_and_command_continues_on_no_matching_servers
|
|
218
|
+
@config.current_task = mock_task
|
|
219
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, :on_no_matching_servers => :continue).returns([])
|
|
220
|
+
assert_nothing_raised do
|
|
221
|
+
@config.execute_on_servers(:on_no_matching_servers => :continue) do
|
|
222
|
+
flunk "should not get here"
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
154
227
|
def test_execute_on_servers_should_determine_server_list_from_active_task
|
|
155
228
|
assert @config.sessions.empty?
|
|
156
229
|
@config.current_task = mock_task
|
|
@@ -189,35 +262,36 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
189
262
|
assert block_called
|
|
190
263
|
assert_equal %w(cap1), @config.sessions.keys.sort.map { |s| s.host }
|
|
191
264
|
end
|
|
192
|
-
|
|
265
|
+
|
|
193
266
|
def test_execute_servers_should_raise_connection_error_on_failure_by_default
|
|
194
267
|
@config.current_task = mock_task
|
|
195
268
|
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1")])
|
|
196
269
|
Capistrano::SSH.expects(:connect).raises(Exception)
|
|
197
|
-
assert_raises(Capistrano::ConnectionError)
|
|
270
|
+
assert_raises(Capistrano::ConnectionError) do
|
|
198
271
|
@config.execute_on_servers do
|
|
199
272
|
flunk "expected an exception to be raised"
|
|
200
273
|
end
|
|
201
|
-
|
|
274
|
+
end
|
|
202
275
|
end
|
|
203
|
-
|
|
276
|
+
|
|
204
277
|
def test_execute_servers_should_not_raise_connection_error_on_failure_with_on_errors_continue
|
|
205
278
|
@config.current_task = mock_task(:on_error => :continue)
|
|
206
279
|
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2")])
|
|
207
|
-
Capistrano::SSH.expects(:connect).
|
|
280
|
+
Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
|
|
281
|
+
Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
|
|
208
282
|
assert_nothing_raised {
|
|
209
283
|
@config.execute_on_servers do |servers|
|
|
210
284
|
assert_equal %w(cap2), servers.map { |s| s.host }
|
|
211
285
|
end
|
|
212
286
|
}
|
|
213
287
|
end
|
|
214
|
-
|
|
288
|
+
|
|
215
289
|
def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_connection_errors_with_on_errors_continue
|
|
216
290
|
list = [server("cap1"), server("cap2")]
|
|
217
291
|
@config.current_task = mock_task(:on_error => :continue)
|
|
218
292
|
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns(list)
|
|
219
|
-
Capistrano::SSH.expects(:connect).
|
|
220
|
-
|
|
293
|
+
Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
|
|
294
|
+
Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
|
|
221
295
|
@config.execute_on_servers do |servers|
|
|
222
296
|
assert_equal %w(cap2), servers.map { |s| s.host }
|
|
223
297
|
end
|
|
@@ -226,7 +300,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
226
300
|
assert_equal %w(cap2), servers.map { |s| s.host }
|
|
227
301
|
end
|
|
228
302
|
end
|
|
229
|
-
|
|
303
|
+
|
|
230
304
|
def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_command_errors_with_on_errors_continue
|
|
231
305
|
cap1 = server("cap1")
|
|
232
306
|
cap2 = server("cap2")
|
|
@@ -243,15 +317,15 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
243
317
|
assert_equal %w(cap2), servers.map { |s| s.host }
|
|
244
318
|
end
|
|
245
319
|
end
|
|
246
|
-
|
|
247
|
-
def
|
|
320
|
+
|
|
321
|
+
def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_transfer_errors_with_on_errors_continue
|
|
248
322
|
cap1 = server("cap1")
|
|
249
323
|
cap2 = server("cap2")
|
|
250
324
|
@config.current_task = mock_task(:on_error => :continue)
|
|
251
325
|
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
|
252
326
|
Capistrano::SSH.expects(:connect).times(2).returns(:success)
|
|
253
327
|
@config.execute_on_servers do |servers|
|
|
254
|
-
error = Capistrano::
|
|
328
|
+
error = Capistrano::TransferError.new
|
|
255
329
|
error.hosts = [cap1]
|
|
256
330
|
raise error
|
|
257
331
|
end
|
|
@@ -270,6 +344,78 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
270
344
|
assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
|
|
271
345
|
end
|
|
272
346
|
|
|
347
|
+
def test_execute_on_servers_should_only_run_on_tasks_max_hosts_hosts_at_once
|
|
348
|
+
cap1 = server("cap1")
|
|
349
|
+
cap2 = server("cap2")
|
|
350
|
+
connection1 = mock()
|
|
351
|
+
connection2 = mock()
|
|
352
|
+
connection1.expects(:close)
|
|
353
|
+
connection2.expects(:close)
|
|
354
|
+
@config.current_task = mock_task(:max_hosts => 1)
|
|
355
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
|
356
|
+
Capistrano::SSH.expects(:connect).times(2).returns(connection1).then.returns(connection2)
|
|
357
|
+
block_called = 0
|
|
358
|
+
@config.execute_on_servers do |servers|
|
|
359
|
+
block_called += 1
|
|
360
|
+
assert_equal 1, servers.size
|
|
361
|
+
end
|
|
362
|
+
assert_equal 2, block_called
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def test_execute_on_servers_should_only_run_on_max_hosts_hosts_at_once
|
|
366
|
+
cap1 = server("cap1")
|
|
367
|
+
cap2 = server("cap2")
|
|
368
|
+
connection1 = mock()
|
|
369
|
+
connection2 = mock()
|
|
370
|
+
connection1.expects(:close)
|
|
371
|
+
connection2.expects(:close)
|
|
372
|
+
@config.current_task = mock_task(:max_hosts => 1)
|
|
373
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
|
374
|
+
Capistrano::SSH.expects(:connect).times(2).returns(connection1).then.returns(connection2)
|
|
375
|
+
block_called = 0
|
|
376
|
+
@config.execute_on_servers do |servers|
|
|
377
|
+
block_called += 1
|
|
378
|
+
assert_equal 1, servers.size
|
|
379
|
+
end
|
|
380
|
+
assert_equal 2, block_called
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def test_execute_on_servers_should_cope_with_already_dropped_connections_when_attempting_to_close_them
|
|
384
|
+
cap1 = server("cap1")
|
|
385
|
+
cap2 = server("cap2")
|
|
386
|
+
connection1 = mock()
|
|
387
|
+
connection2 = mock()
|
|
388
|
+
connection3 = mock()
|
|
389
|
+
connection4 = mock()
|
|
390
|
+
connection1.expects(:close).raises(IOError)
|
|
391
|
+
connection2.expects(:close)
|
|
392
|
+
connection3.expects(:close)
|
|
393
|
+
connection4.expects(:close)
|
|
394
|
+
@config.current_task = mock_task(:max_hosts => 1)
|
|
395
|
+
@config.expects(:find_servers_for_task).times(2).with(@config.current_task, {}).returns([cap1, cap2])
|
|
396
|
+
Capistrano::SSH.expects(:connect).times(4).returns(connection1).then.returns(connection2).then.returns(connection3).then.returns(connection4)
|
|
397
|
+
@config.execute_on_servers {}
|
|
398
|
+
@config.execute_on_servers {}
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def test_execute_on_servers_should_cope_with_already_disconnected_connections_when_attempting_to_close_them
|
|
402
|
+
cap1 = server("cap1")
|
|
403
|
+
cap2 = server("cap2")
|
|
404
|
+
connection1 = mock()
|
|
405
|
+
connection2 = mock()
|
|
406
|
+
connection3 = mock()
|
|
407
|
+
connection4 = mock()
|
|
408
|
+
connection1.expects(:close).raises(Net::SSH::Disconnect)
|
|
409
|
+
connection2.expects(:close)
|
|
410
|
+
connection3.expects(:close)
|
|
411
|
+
connection4.expects(:close)
|
|
412
|
+
@config.current_task = mock_task(:max_hosts => 1)
|
|
413
|
+
@config.expects(:find_servers_for_task).times(2).with(@config.current_task, {}).returns([cap1, cap2])
|
|
414
|
+
Capistrano::SSH.expects(:connect).times(4).returns(connection1).then.returns(connection2).then.returns(connection3).then.returns(connection4)
|
|
415
|
+
@config.execute_on_servers {}
|
|
416
|
+
@config.execute_on_servers {}
|
|
417
|
+
end
|
|
418
|
+
|
|
273
419
|
def test_connect_should_honor_once_option
|
|
274
420
|
assert @config.sessions.empty?
|
|
275
421
|
@config.current_task = mock_task
|
|
@@ -283,6 +429,11 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
|
|
|
283
429
|
|
|
284
430
|
def mock_task(options={})
|
|
285
431
|
continue_on_error = options[:on_error] == :continue
|
|
286
|
-
stub("task",
|
|
432
|
+
stub("task",
|
|
433
|
+
:fully_qualified_name => "name",
|
|
434
|
+
:options => options,
|
|
435
|
+
:continue_on_error? => continue_on_error,
|
|
436
|
+
:max_hosts => options[:max_hosts]
|
|
437
|
+
)
|
|
287
438
|
end
|
|
288
|
-
end
|
|
439
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "utils"
|
|
2
2
|
require 'capistrano/configuration/execution'
|
|
3
3
|
require 'capistrano/task_definition'
|
|
4
4
|
|
|
@@ -116,6 +116,22 @@ class ConfigurationExecutionTest < Test::Unit::TestCase
|
|
|
116
116
|
assert @config.state[:aaa]
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
+
def test_on_rollback_called_twice_should_result_in_last_rollback_block_being_effective
|
|
120
|
+
aaa = new_task(@config, :aaa) do
|
|
121
|
+
transaction do
|
|
122
|
+
on_rollback { (state[:rollback] ||= []) << :first }
|
|
123
|
+
on_rollback { (state[:rollback] ||= []) << :second }
|
|
124
|
+
raise "boom"
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
assert_raises(RuntimeError) do
|
|
129
|
+
@config.execute_task(aaa)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
assert_equal [:second], @config.state[:rollback]
|
|
133
|
+
end
|
|
134
|
+
|
|
119
135
|
def test_find_and_execute_task_should_raise_error_when_task_cannot_be_found
|
|
120
136
|
@config.expects(:find_task).with("path:to:task").returns(nil)
|
|
121
137
|
assert_raises(Capistrano::NoSuchTaskError) { @config.find_and_execute_task("path:to:task") }
|
|
@@ -156,4 +172,4 @@ class ConfigurationExecutionTest < Test::Unit::TestCase
|
|
|
156
172
|
block ||= stack_inspector
|
|
157
173
|
namespace.tasks[name] = Capistrano::TaskDefinition.new(name, namespace, &block)
|
|
158
174
|
end
|
|
159
|
-
end
|
|
175
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'utils'
|
|
2
2
|
require 'capistrano/configuration/loading'
|
|
3
3
|
|
|
4
4
|
class ConfigurationLoadingTest < Test::Unit::TestCase
|
|
@@ -23,7 +23,7 @@ class ConfigurationLoadingTest < Test::Unit::TestCase
|
|
|
23
23
|
|
|
24
24
|
def teardown
|
|
25
25
|
MockConfig.instance = nil
|
|
26
|
-
$
|
|
26
|
+
$LOADED_FEATURES.delete_if { |a| a =~ /fixtures\/custom\.rb$/ }
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def test_initialize_should_init_collections
|
|
@@ -106,7 +106,7 @@ class ConfigurationLoadingTest < Test::Unit::TestCase
|
|
|
106
106
|
|
|
107
107
|
def test_require_from_config_should_load_file_in_config_scope
|
|
108
108
|
assert_nothing_raised do
|
|
109
|
-
@config.require "#{File.dirname(__FILE__)}/../fixtures/custom"
|
|
109
|
+
@config.require "#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom"
|
|
110
110
|
end
|
|
111
111
|
assert_equal :custom, @config.ping
|
|
112
112
|
end
|
|
@@ -116,4 +116,17 @@ class ConfigurationLoadingTest < Test::Unit::TestCase
|
|
|
116
116
|
require "#{File.dirname(__FILE__)}/../fixtures/custom"
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
|
-
|
|
119
|
+
|
|
120
|
+
def test_require_from_config_should_return_false_when_called_a_second_time_with_same_args
|
|
121
|
+
assert @config.require("#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom")
|
|
122
|
+
assert_equal false, @config.require("#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom")
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_require_in_multiple_instances_should_load_recipes_in_each_instance
|
|
126
|
+
config2 = MockConfig.new
|
|
127
|
+
@config.require "#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom"
|
|
128
|
+
config2.require "#{File.expand_path(File.dirname(__FILE__))}/../fixtures/custom"
|
|
129
|
+
assert_equal :custom, @config.ping
|
|
130
|
+
assert_equal :custom, config2.ping
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "utils"
|
|
2
2
|
require 'capistrano/configuration/namespaces'
|
|
3
3
|
|
|
4
4
|
class ConfigurationNamespacesDSLTest < Test::Unit::TestCase
|
|
@@ -108,9 +108,9 @@ class ConfigurationNamespacesDSLTest < Test::Unit::TestCase
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def test_defining_ask_should_add_task_as_method
|
|
111
|
-
assert !@config.methods.
|
|
111
|
+
assert !@config.methods.any? { |m| m.to_sym == :original }
|
|
112
112
|
@config.task(:original) { puts "foo" }
|
|
113
|
-
assert @config.methods.
|
|
113
|
+
assert @config.methods.any? { |m| m.to_sym == :original }
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
def test_calling_defined_task_should_delegate_to_execute_task
|
|
@@ -146,7 +146,7 @@ class ConfigurationNamespacesDSLTest < Test::Unit::TestCase
|
|
|
146
146
|
|
|
147
147
|
def test_parent_for_namespace_should_be_the_top_level
|
|
148
148
|
@config.namespace(:outer) {}
|
|
149
|
-
assert_equal @config, @config.namespaces[:outer].parent
|
|
149
|
+
assert_equal @config, @config.namespaces[:outer].parent
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
def test_fqn_for_nested_namespace_should_be_color_delimited
|
|
@@ -239,6 +239,12 @@ class ConfigurationNamespacesDSLTest < Test::Unit::TestCase
|
|
|
239
239
|
assert ns.respond_to?(:original_initialize_called)
|
|
240
240
|
end
|
|
241
241
|
|
|
242
|
+
def test_namespace_should_accept_respond_to_with_include_priv_parameter
|
|
243
|
+
@config.namespace(:outer) {}
|
|
244
|
+
ns = @config.namespaces[:outer]
|
|
245
|
+
assert ns.respond_to?(:original_initialize_called, true)
|
|
246
|
+
end
|
|
247
|
+
|
|
242
248
|
def test_namespace_should_delegate_unknown_messages_to_its_parent
|
|
243
249
|
@config.namespace(:outer) {}
|
|
244
250
|
ns = @config.namespaces[:outer]
|
|
@@ -280,4 +286,47 @@ class ConfigurationNamespacesDSLTest < Test::Unit::TestCase
|
|
|
280
286
|
inner = @config.namespaces[:outer].namespaces[:inner]
|
|
281
287
|
assert_nil inner.search_task(:first)
|
|
282
288
|
end
|
|
283
|
-
|
|
289
|
+
|
|
290
|
+
def test_top_should_return_self_if_self_is_top
|
|
291
|
+
assert_equal @config, @config.top
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def test_top_should_return_parent_if_parent_is_top
|
|
295
|
+
@config.namespace(:outer) {}
|
|
296
|
+
assert_equal @config, @config.namespaces[:outer].top
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def test_top_should_return_topmost_parent_if_self_is_deeply_nested
|
|
300
|
+
@config.namespace(:outer) { namespace(:middle) { namespace(:inner) {} } }
|
|
301
|
+
assert_equal @config, @config.namespaces[:outer].namespaces[:middle].namespaces[:inner].top
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def test_find_task_should_return_nil_when_empty_inner_task
|
|
305
|
+
@config.namespace :outer do
|
|
306
|
+
namespace :inner do
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
assert_nil @config.find_task("outer::inner")
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def test_kernel_method_clashing_should_not_affect_method_delegation_to_parent
|
|
313
|
+
@config.class.class_eval do
|
|
314
|
+
def some_weird_method() 'config' end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
@config.namespace(:clash) {}
|
|
318
|
+
namespace = @config.namespaces[:clash]
|
|
319
|
+
assert_equal 'config', namespace.some_weird_method
|
|
320
|
+
|
|
321
|
+
Kernel.module_eval do
|
|
322
|
+
def some_weird_method() 'kernel' end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
@config.namespace(:clash2) {}
|
|
326
|
+
namespace = @config.namespaces[:clash2]
|
|
327
|
+
assert_equal 'config', namespace.some_weird_method
|
|
328
|
+
|
|
329
|
+
Kernel.send :remove_method, :some_weird_method
|
|
330
|
+
@config.class.send :remove_method, :some_weird_method
|
|
331
|
+
end
|
|
332
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "utils"
|
|
2
2
|
require 'capistrano/configuration/roles'
|
|
3
|
+
require 'capistrano/server_definition'
|
|
3
4
|
|
|
4
5
|
class ConfigurationRolesTest < Test::Unit::TestCase
|
|
5
6
|
class MockConfig
|
|
@@ -21,21 +22,56 @@ class ConfigurationRolesTest < Test::Unit::TestCase
|
|
|
21
22
|
assert @config.roles.empty?
|
|
22
23
|
end
|
|
23
24
|
|
|
25
|
+
def test_roles_for_host_with_one_role
|
|
26
|
+
@config.role :app, "app1.capistrano.test"
|
|
27
|
+
@config.role :not_app, "not-app.capistrano.test"
|
|
28
|
+
app_server = @config.roles[:app].servers.first
|
|
29
|
+
assert @config.role_names_for_host(app_server)==[ :app ]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_roles_for_host_with_multiple_roles
|
|
33
|
+
@config.server "www.capistrano.test", :db, :worker
|
|
34
|
+
db_server = @config.roles[:db].servers.first
|
|
35
|
+
assert_equal @config.role_names_for_host(db_server).map(&:to_s).sort, [ 'db', 'worker' ]
|
|
36
|
+
end
|
|
37
|
+
|
|
24
38
|
def test_role_should_allow_empty_list
|
|
25
39
|
@config.role :app
|
|
40
|
+
assert @config.roles.keys.include?(:app)
|
|
26
41
|
assert @config.roles[:app].empty?
|
|
27
42
|
end
|
|
28
43
|
|
|
29
44
|
def test_role_with_one_argument_should_add_to_roles_collection
|
|
30
45
|
@config.role :app, "app1.capistrano.test"
|
|
31
46
|
assert_equal [:app], @config.roles.keys
|
|
32
|
-
|
|
47
|
+
assert_role_equals %w(app1.capistrano.test)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_role_block_returning_single_string_is_added_to_roles_collection
|
|
51
|
+
@config.role :app do
|
|
52
|
+
'app1.capistrano.test'
|
|
53
|
+
end
|
|
54
|
+
assert_role_equals %w(app1.capistrano.test)
|
|
33
55
|
end
|
|
34
56
|
|
|
35
57
|
def test_role_with_multiple_arguments_should_add_each_to_roles_collection
|
|
36
58
|
@config.role :app, "app1.capistrano.test", "app2.capistrano.test"
|
|
37
59
|
assert_equal [:app], @config.roles.keys
|
|
38
|
-
|
|
60
|
+
assert_role_equals %w(app1.capistrano.test app2.capistrano.test)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def test_role_with_block_and_strings_should_add_both_to_roles_collection
|
|
64
|
+
@config.role :app, 'app1.capistrano.test' do
|
|
65
|
+
'app2.capistrano.test'
|
|
66
|
+
end
|
|
67
|
+
assert_role_equals %w(app1.capistrano.test app2.capistrano.test)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_role_block_returning_array_should_add_each_to_roles_collection
|
|
71
|
+
@config.role :app do
|
|
72
|
+
['app1.capistrano.test', 'app2.capistrano.test']
|
|
73
|
+
end
|
|
74
|
+
assert_role_equals %w(app1.capistrano.test app2.capistrano.test)
|
|
39
75
|
end
|
|
40
76
|
|
|
41
77
|
def test_role_with_options_should_apply_options_to_each_argument
|
|
@@ -44,4 +80,78 @@ class ConfigurationRolesTest < Test::Unit::TestCase
|
|
|
44
80
|
assert_equal({:extra => :value}, server.options)
|
|
45
81
|
end
|
|
46
82
|
end
|
|
47
|
-
|
|
83
|
+
|
|
84
|
+
def test_role_with_options_should_apply_options_to_block_results
|
|
85
|
+
@config.role :app, :extra => :value do
|
|
86
|
+
['app1.capistrano.test', 'app2.capistrano.test']
|
|
87
|
+
end
|
|
88
|
+
@config.roles[:app].each do |server|
|
|
89
|
+
assert_equal({:extra => :value}, server.options)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_options_should_apply_only_to_this_argument_set
|
|
94
|
+
@config.role :app, 'app1.capistrano.test', 'app2.capistrano.test' do
|
|
95
|
+
['app3.capistrano.test', 'app4.capistrano.test']
|
|
96
|
+
end
|
|
97
|
+
@config.role :app, 'app5.capistrano.test', 'app6.capistrano.test', :extra => :value do
|
|
98
|
+
['app7.capistrano.test', 'app8.capistrano.test']
|
|
99
|
+
end
|
|
100
|
+
@config.role :app, 'app9.capistrano.test'
|
|
101
|
+
|
|
102
|
+
option_hosts = ['app5.capistrano.test', 'app6.capistrano.test', 'app7.capistrano.test', 'app8.capistrano.test']
|
|
103
|
+
@config.roles[:app].each do |server|
|
|
104
|
+
if (option_hosts.include? server.host)
|
|
105
|
+
assert_equal({:extra => :value}, server.options)
|
|
106
|
+
else
|
|
107
|
+
assert_not_equal({:extra => :value}, server.options)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Here, the source should be more readable than the method name
|
|
113
|
+
def test_role_block_returns_options_hash_is_merged_with_role_options_argument
|
|
114
|
+
@config.role :app, :first => :one, :second => :two do
|
|
115
|
+
['app1.capistrano.test', 'app2.capistrano.test', {:second => :please, :third => :three}]
|
|
116
|
+
end
|
|
117
|
+
@config.roles[:app].each do |server|
|
|
118
|
+
assert_equal({:first => :one, :second => :please, :third => :three}, server.options)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def test_role_block_can_override_role_options_argument
|
|
123
|
+
@config.role :app, :value => :wrong do
|
|
124
|
+
Capistrano::ServerDefinition.new('app.capistrano.test')
|
|
125
|
+
end
|
|
126
|
+
@config.roles[:app].servers
|
|
127
|
+
@config.roles[:app].servers.each do |server|
|
|
128
|
+
assert_not_equal({:value => :wrong}, server.options)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_role_block_can_return_nil
|
|
133
|
+
@config.role :app do
|
|
134
|
+
nil
|
|
135
|
+
end
|
|
136
|
+
assert_role_equals ([])
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_role_block_can_return_empty_array
|
|
140
|
+
@config.role :app do
|
|
141
|
+
[]
|
|
142
|
+
end
|
|
143
|
+
assert_role_equals ([])
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_role_definitions_via_server_should_associate_server_with_roles
|
|
147
|
+
@config.server "www.capistrano.test", :web, :app
|
|
148
|
+
assert_equal %w(www.capistrano.test), @config.roles[:app].map { |s| s.host }
|
|
149
|
+
assert_equal %w(www.capistrano.test), @config.roles[:web].map { |s| s.host }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
|
|
154
|
+
def assert_role_equals(list)
|
|
155
|
+
assert_equal list, @config.roles[:app].map { |s| s.host }
|
|
156
|
+
end
|
|
157
|
+
end
|