mbailey-capistrano 2.5.5
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/CHANGELOG.rdoc +761 -0
- data/Manifest +104 -0
- data/README.rdoc +66 -0
- data/Rakefile +34 -0
- data/bin/cap +4 -0
- data/bin/capify +78 -0
- data/examples/sample.rb +14 -0
- data/lib/capistrano/callback.rb +45 -0
- data/lib/capistrano/cli/execute.rb +84 -0
- data/lib/capistrano/cli/help.rb +125 -0
- data/lib/capistrano/cli/help.txt +75 -0
- data/lib/capistrano/cli/options.rb +224 -0
- data/lib/capistrano/cli/ui.rb +40 -0
- data/lib/capistrano/cli.rb +47 -0
- data/lib/capistrano/command.rb +283 -0
- data/lib/capistrano/configuration/actions/file_transfer.rb +47 -0
- data/lib/capistrano/configuration/actions/inspect.rb +46 -0
- data/lib/capistrano/configuration/actions/invocation.rb +293 -0
- data/lib/capistrano/configuration/callbacks.rb +148 -0
- data/lib/capistrano/configuration/connections.rb +200 -0
- data/lib/capistrano/configuration/execution.rb +132 -0
- data/lib/capistrano/configuration/loading.rb +197 -0
- data/lib/capistrano/configuration/namespaces.rb +197 -0
- data/lib/capistrano/configuration/roles.rb +73 -0
- data/lib/capistrano/configuration/servers.rb +85 -0
- data/lib/capistrano/configuration/variables.rb +127 -0
- data/lib/capistrano/configuration.rb +43 -0
- data/lib/capistrano/errors.rb +15 -0
- data/lib/capistrano/extensions.rb +57 -0
- data/lib/capistrano/logger.rb +59 -0
- data/lib/capistrano/processable.rb +53 -0
- data/lib/capistrano/recipes/compat.rb +32 -0
- data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
- data/lib/capistrano/recipes/deploy/local_dependency.rb +54 -0
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +105 -0
- data/lib/capistrano/recipes/deploy/scm/accurev.rb +169 -0
- data/lib/capistrano/recipes/deploy/scm/base.rb +196 -0
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +83 -0
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +152 -0
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +85 -0
- data/lib/capistrano/recipes/deploy/scm/git.rb +271 -0
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +137 -0
- data/lib/capistrano/recipes/deploy/scm/none.rb +44 -0
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +133 -0
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +121 -0
- data/lib/capistrano/recipes/deploy/scm.rb +19 -0
- data/lib/capistrano/recipes/deploy/strategy/base.rb +79 -0
- data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +210 -0
- data/lib/capistrano/recipes/deploy/strategy/export.rb +20 -0
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +52 -0
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +56 -0
- data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +53 -0
- data/lib/capistrano/recipes/deploy.rb +562 -0
- data/lib/capistrano/recipes/standard.rb +37 -0
- data/lib/capistrano/recipes/templates/maintenance.rhtml +53 -0
- data/lib/capistrano/recipes/upgrade.rb +33 -0
- data/lib/capistrano/role.rb +102 -0
- data/lib/capistrano/server_definition.rb +56 -0
- data/lib/capistrano/shell.rb +260 -0
- data/lib/capistrano/ssh.rb +99 -0
- data/lib/capistrano/task_definition.rb +70 -0
- data/lib/capistrano/transfer.rb +216 -0
- data/lib/capistrano/version.rb +18 -0
- data/lib/capistrano.rb +2 -0
- data/setup.rb +1346 -0
- data/test/cli/execute_test.rb +132 -0
- data/test/cli/help_test.rb +165 -0
- data/test/cli/options_test.rb +317 -0
- data/test/cli/ui_test.rb +28 -0
- data/test/cli_test.rb +17 -0
- data/test/command_test.rb +286 -0
- data/test/configuration/actions/file_transfer_test.rb +61 -0
- data/test/configuration/actions/inspect_test.rb +65 -0
- data/test/configuration/actions/invocation_test.rb +224 -0
- data/test/configuration/callbacks_test.rb +220 -0
- data/test/configuration/connections_test.rb +349 -0
- data/test/configuration/execution_test.rb +175 -0
- data/test/configuration/loading_test.rb +132 -0
- data/test/configuration/namespace_dsl_test.rb +311 -0
- data/test/configuration/roles_test.rb +144 -0
- data/test/configuration/servers_test.rb +121 -0
- data/test/configuration/variables_test.rb +184 -0
- data/test/configuration_test.rb +88 -0
- data/test/deploy/local_dependency_test.rb +76 -0
- data/test/deploy/remote_dependency_test.rb +114 -0
- data/test/deploy/scm/accurev_test.rb +23 -0
- data/test/deploy/scm/base_test.rb +55 -0
- data/test/deploy/scm/git_test.rb +167 -0
- data/test/deploy/scm/mercurial_test.rb +129 -0
- data/test/deploy/strategy/copy_test.rb +258 -0
- data/test/extensions_test.rb +69 -0
- data/test/fixtures/cli_integration.rb +5 -0
- data/test/fixtures/config.rb +5 -0
- data/test/fixtures/custom.rb +3 -0
- data/test/logger_test.rb +123 -0
- data/test/role_test.rb +11 -0
- data/test/server_definition_test.rb +121 -0
- data/test/shell_test.rb +90 -0
- data/test/ssh_test.rb +104 -0
- data/test/task_definition_test.rb +101 -0
- data/test/transfer_test.rb +160 -0
- data/test/utils.rb +38 -0
- metadata +205 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
require "utils"
|
2
|
+
require 'capistrano/configuration/callbacks'
|
3
|
+
|
4
|
+
class ConfigurationCallbacksTest < Test::Unit::TestCase
|
5
|
+
class MockConfig
|
6
|
+
attr_reader :original_initialize_called
|
7
|
+
attr_reader :called
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@original_initialize_called = true
|
11
|
+
@called = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute_task(task)
|
15
|
+
invoke_task_directly(task)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def invoke_task_directly(task)
|
21
|
+
@called << task
|
22
|
+
end
|
23
|
+
|
24
|
+
include Capistrano::Configuration::Callbacks
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup
|
28
|
+
@config = MockConfig.new
|
29
|
+
@config.stubs(:logger).returns(stub_everything("logger"))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_initialize_should_initialize_callbacks_collection
|
33
|
+
assert @config.original_initialize_called
|
34
|
+
assert @config.callbacks.empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_before_should_delegate_to_on
|
38
|
+
@config.expects(:on).with(:before, :foo, "bing:blang", {:only => :bar, :zip => :zing})
|
39
|
+
@config.before :bar, :foo, "bing:blang", :zip => :zing
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_after_should_delegate_to_on
|
43
|
+
@config.expects(:on).with(:after, :foo, "bing:blang", {:only => :bar, :zip => :zing})
|
44
|
+
@config.after :bar, :foo, "bing:blang", :zip => :zing
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_on_with_single_reference_should_add_task_callback
|
48
|
+
@config.on :before, :a_test
|
49
|
+
assert_equal 1, @config.callbacks[:before].length
|
50
|
+
assert_equal :a_test, @config.callbacks[:before][0].source
|
51
|
+
@config.expects(:find_and_execute_task).with(:a_test)
|
52
|
+
@config.callbacks[:before][0].call
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_on_with_multi_reference_should_add_all_as_task_callback
|
56
|
+
@config.on :before, :first, :second, :third
|
57
|
+
assert_equal 3, @config.callbacks[:before].length
|
58
|
+
assert_equal %w(first second third), @config.callbacks[:before].map { |c| c.source.to_s }
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_on_with_block_should_add_block_as_proc_callback
|
62
|
+
called = false
|
63
|
+
@config.on(:before) { called = true }
|
64
|
+
assert_equal 1, @config.callbacks[:before].length
|
65
|
+
assert_instance_of Proc, @config.callbacks[:before][0].source
|
66
|
+
@config.callbacks[:before][0].call
|
67
|
+
assert called
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_on_with_single_only_should_set_only_as_string_array_on_all_references
|
71
|
+
@config.on :before, :first, "second:third", :only => :primary
|
72
|
+
assert_equal 2, @config.callbacks[:before].length
|
73
|
+
assert @config.callbacks[:before].all? { |c| c.only == %w(primary) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_on_with_multi_only_should_set_only_as_string_array_on_all_references
|
77
|
+
@config.on :before, :first, "second:third", :only => [:primary, "other:one"]
|
78
|
+
assert_equal 2, @config.callbacks[:before].length
|
79
|
+
assert @config.callbacks[:before].all? { |c| c.only == %w(primary other:one) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_on_with_single_except_should_set_except_as_string_array_on_all_references
|
83
|
+
@config.on :before, :first, "second:third", :except => :primary
|
84
|
+
assert_equal 2, @config.callbacks[:before].length
|
85
|
+
assert @config.callbacks[:before].all? { |c| c.except == %w(primary) }
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_on_with_multi_except_should_set_except_as_string_array_on_all_references
|
89
|
+
@config.on :before, :first, "second:third", :except => [:primary, "other:one"]
|
90
|
+
assert_equal 2, @config.callbacks[:before].length
|
91
|
+
assert @config.callbacks[:before].all? { |c| c.except == %w(primary other:one) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_on_with_only_and_block_should_set_only_as_string_array
|
95
|
+
@config.on(:before, :only => :primary) { blah }
|
96
|
+
assert_equal 1, @config.callbacks[:before].length
|
97
|
+
assert_equal %w(primary), @config.callbacks[:before].first.only
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_on_with_except_and_block_should_set_except_as_string_array
|
101
|
+
@config.on(:before, :except => :primary) { blah }
|
102
|
+
assert_equal 1, @config.callbacks[:before].length
|
103
|
+
assert_equal %w(primary), @config.callbacks[:before].first.except
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_on_without_tasks_or_block_should_raise_error
|
107
|
+
assert_raises(ArgumentError) { @config.on(:before) }
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_on_with_both_tasks_and_block_should_raise_error
|
111
|
+
assert_raises(ArgumentError) { @config.on(:before, :first) { blah } }
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_trigger_without_constraints_should_invoke_all_callbacks
|
115
|
+
task = stub(:fully_qualified_name => "any:old:thing")
|
116
|
+
@config.on(:before, :first, "second:third")
|
117
|
+
@config.on(:after, :another, "and:another")
|
118
|
+
@config.expects(:find_and_execute_task).with(:first)
|
119
|
+
@config.expects(:find_and_execute_task).with("second:third")
|
120
|
+
@config.expects(:find_and_execute_task).with(:another).never
|
121
|
+
@config.expects(:find_and_execute_task).with("and:another").never
|
122
|
+
@config.trigger(:before, task)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_trigger_with_only_constraint_should_invoke_only_matching_callbacks
|
126
|
+
task = stub(:fully_qualified_name => "any:old:thing")
|
127
|
+
@config.on(:before, :first)
|
128
|
+
@config.on(:before, "second:third", :only => "any:old:thing")
|
129
|
+
@config.on(:before, "this:too", :only => "any:other:thing")
|
130
|
+
@config.on(:after, :another, "and:another")
|
131
|
+
@config.expects(:find_and_execute_task).with(:first)
|
132
|
+
@config.expects(:find_and_execute_task).with("second:third")
|
133
|
+
@config.expects(:find_and_execute_task).with("this:too").never
|
134
|
+
@config.expects(:find_and_execute_task).with(:another).never
|
135
|
+
@config.expects(:find_and_execute_task).with("and:another").never
|
136
|
+
@config.trigger(:before, task)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_trigger_with_except_constraint_should_invoke_anything_but_matching_callbacks
|
140
|
+
task = stub(:fully_qualified_name => "any:old:thing")
|
141
|
+
@config.on(:before, :first)
|
142
|
+
@config.on(:before, "second:third", :except => "any:old:thing")
|
143
|
+
@config.on(:before, "this:too", :except => "any:other:thing")
|
144
|
+
@config.on(:after, :another, "and:another")
|
145
|
+
@config.expects(:find_and_execute_task).with(:first)
|
146
|
+
@config.expects(:find_and_execute_task).with("second:third").never
|
147
|
+
@config.expects(:find_and_execute_task).with("this:too")
|
148
|
+
@config.expects(:find_and_execute_task).with(:another).never
|
149
|
+
@config.expects(:find_and_execute_task).with("and:another").never
|
150
|
+
@config.trigger(:before, task)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_trigger_without_task_should_invoke_all_callbacks_for_that_event
|
154
|
+
task = stub(:fully_qualified_name => "any:old:thing")
|
155
|
+
@config.on(:before, :first)
|
156
|
+
@config.on(:before, "second:third", :except => "any:old:thing")
|
157
|
+
@config.on(:before, "this:too", :except => "any:other:thing")
|
158
|
+
@config.on(:after, :another, "and:another")
|
159
|
+
@config.expects(:find_and_execute_task).with(:first)
|
160
|
+
@config.expects(:find_and_execute_task).with("second:third")
|
161
|
+
@config.expects(:find_and_execute_task).with("this:too")
|
162
|
+
@config.expects(:find_and_execute_task).with(:another).never
|
163
|
+
@config.expects(:find_and_execute_task).with("and:another").never
|
164
|
+
@config.trigger(:before)
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_execute_task_without_named_hooks_should_just_call_task
|
168
|
+
ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
|
169
|
+
task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
|
170
|
+
|
171
|
+
ns.stubs(:search_task).returns(nil)
|
172
|
+
|
173
|
+
@config.execute_task(task)
|
174
|
+
assert_equal [task], @config.called
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_execute_task_with_named_before_hook_should_call_named_before_hook
|
178
|
+
ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
|
179
|
+
task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
|
180
|
+
before_task = stub(:fully_qualified_name => "any:old:before_thing", :name => "before_thing", :namespace => ns)
|
181
|
+
|
182
|
+
ns.stubs(:search_task).returns(nil)
|
183
|
+
ns.expects(:search_task).with("before_thing").returns(before_task)
|
184
|
+
|
185
|
+
@config.execute_task(task)
|
186
|
+
assert_equal [before_task, task], @config.called
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_execute_task_with_named_after_hook_should_call_named_after_hook
|
190
|
+
ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
|
191
|
+
task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
|
192
|
+
after_task = stub(:fully_qualified_name => "any:old:after_thing", :name => "after_thing", :namespace => ns)
|
193
|
+
|
194
|
+
ns.stubs(:search_task).returns(nil)
|
195
|
+
ns.expects(:search_task).with("after_thing").returns(after_task)
|
196
|
+
|
197
|
+
@config.execute_task(task)
|
198
|
+
assert_equal [task, after_task], @config.called
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_execute_task_with_on_hooks_should_trigger_hooks_around_task
|
202
|
+
ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
|
203
|
+
task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
|
204
|
+
before_task = stub(:fully_qualified_name => "any:old:before_thing", :name => "before_thing", :namespace => ns)
|
205
|
+
after_task = stub(:fully_qualified_name => "any:old:after_thing", :name => "after_thing", :namespace => ns)
|
206
|
+
|
207
|
+
ns.stubs(:search_task).returns(nil)
|
208
|
+
ns.expects(:search_task).with("before_thing").returns(before_task)
|
209
|
+
ns.expects(:search_task).with("after_thing").returns(after_task)
|
210
|
+
|
211
|
+
@config.before("any:old:thing", :first_this, :then_this)
|
212
|
+
@config.after("any:old:thing", :and_then_this, :lastly_this)
|
213
|
+
|
214
|
+
[:first_this, :then_this, :and_then_this, :lastly_this].each do |t|
|
215
|
+
@config.expects(:find_and_execute_task).with(t)
|
216
|
+
end
|
217
|
+
|
218
|
+
@config.execute_task(task)
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,349 @@
|
|
1
|
+
require "utils"
|
2
|
+
require 'capistrano/configuration/connections'
|
3
|
+
|
4
|
+
class ConfigurationConnectionsTest < Test::Unit::TestCase
|
5
|
+
class MockConfig
|
6
|
+
attr_reader :original_initialize_called
|
7
|
+
attr_reader :values
|
8
|
+
attr_accessor :current_task
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@original_initialize_called = true
|
12
|
+
@values = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch(*args)
|
16
|
+
@values.fetch(*args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](key)
|
20
|
+
@values[key]
|
21
|
+
end
|
22
|
+
|
23
|
+
def exists?(key)
|
24
|
+
@values.key?(key)
|
25
|
+
end
|
26
|
+
|
27
|
+
include Capistrano::Configuration::Connections
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup
|
31
|
+
@config = MockConfig.new
|
32
|
+
@config.stubs(:logger).returns(stub_everything)
|
33
|
+
Net::SSH.stubs(:configuration_for).returns({})
|
34
|
+
@ssh_options = {
|
35
|
+
:user => "user",
|
36
|
+
:port => 8080,
|
37
|
+
:password => "g00b3r",
|
38
|
+
:ssh_options => { :debug => :verbose }
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_initialize_should_initialize_collections_and_call_original_initialize
|
43
|
+
assert @config.original_initialize_called
|
44
|
+
assert @config.sessions.empty?
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_connection_factory_should_return_default_connection_factory_instance
|
48
|
+
factory = @config.connection_factory
|
49
|
+
assert_instance_of Capistrano::Configuration::Connections::DefaultConnectionFactory, factory
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_connection_factory_instance_should_be_cached
|
53
|
+
assert_same @config.connection_factory, @config.connection_factory
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_default_connection_factory_honors_config_options
|
57
|
+
server = server("capistrano")
|
58
|
+
Capistrano::SSH.expects(:connect).with(server, @config).returns(:session)
|
59
|
+
assert_equal :session, @config.connection_factory.connect_to(server)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_connect_through_gateway_if_gateway_variable_is_set
|
63
|
+
@config.values[:gateway] = "j@gateway"
|
64
|
+
Net::SSH::Gateway.expects(:new).with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
65
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_connection_factory_as_gateway_should_honor_config_options
|
69
|
+
@config.values[:gateway] = "gateway"
|
70
|
+
@config.values.update(@ssh_options)
|
71
|
+
Net::SSH::Gateway.expects(:new).with("gateway", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
72
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_an_array
|
76
|
+
@config.values[:gateway] = ["j@gateway1", "k@gateway2"]
|
77
|
+
gateway1 = mock
|
78
|
+
Net::SSH::Gateway.expects(:new).with("gateway1", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(gateway1)
|
79
|
+
gateway1.expects(:open).returns(65535)
|
80
|
+
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)
|
81
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_connection_factory_as_gateway_should_share_gateway_between_connections
|
85
|
+
@config.values[:gateway] = "j@gateway"
|
86
|
+
Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
|
87
|
+
Capistrano::SSH.stubs(:connect).returns(stub_everything)
|
88
|
+
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
|
89
|
+
@config.establish_connections_to(server("capistrano"))
|
90
|
+
@config.establish_connections_to(server("another"))
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_establish_connections_to_should_accept_a_single_nonarray_parameter
|
94
|
+
Capistrano::SSH.expects(:connect).with { |s,| s.host == "capistrano" }.returns(:success)
|
95
|
+
assert @config.sessions.empty?
|
96
|
+
@config.establish_connections_to(server("capistrano"))
|
97
|
+
assert ["capistrano"], @config.sessions.keys
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_establish_connections_to_should_accept_an_array
|
101
|
+
Capistrano::SSH.expects(:connect).times(3).returns(:success)
|
102
|
+
assert @config.sessions.empty?
|
103
|
+
@config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
|
104
|
+
assert %w(cap1 cap2 cap3), @config.sessions.keys.sort
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_establish_connections_to_should_not_attempt_to_reestablish_existing_connections
|
108
|
+
Capistrano::SSH.expects(:connect).times(2).returns(:success)
|
109
|
+
@config.sessions[server("cap1")] = :ok
|
110
|
+
@config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
|
111
|
+
assert %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_establish_connections_to_should_raise_one_connection_error_on_failure
|
115
|
+
Capistrano::SSH.expects(:connect).times(2).raises(Exception)
|
116
|
+
assert_raises(Capistrano::ConnectionError) {
|
117
|
+
@config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_connection_error_should_include_accessor_with_host_array
|
122
|
+
Capistrano::SSH.expects(:connect).times(2).raises(Exception)
|
123
|
+
|
124
|
+
begin
|
125
|
+
@config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
|
126
|
+
flunk "expected an exception to be raised"
|
127
|
+
rescue Capistrano::ConnectionError => e
|
128
|
+
assert e.respond_to?(:hosts)
|
129
|
+
assert_equal %w(cap1 cap2), e.hosts.map { |h| h.to_s }.sort
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_connection_error_should_only_include_failed_hosts
|
134
|
+
Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
|
135
|
+
Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
|
136
|
+
|
137
|
+
begin
|
138
|
+
@config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
|
139
|
+
flunk "expected an exception to be raised"
|
140
|
+
rescue Capistrano::ConnectionError => e
|
141
|
+
assert_equal %w(cap1), e.hosts.map { |h| h.to_s }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_execute_on_servers_should_require_a_block
|
146
|
+
assert_raises(ArgumentError) { @config.execute_on_servers }
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_execute_on_servers_without_current_task_should_call_find_servers
|
150
|
+
list = [server("first"), server("second")]
|
151
|
+
@config.expects(:find_servers).with(:a => :b, :c => :d).returns(list)
|
152
|
+
@config.expects(:establish_connections_to).with(list).returns(:done)
|
153
|
+
@config.execute_on_servers(:a => :b, :c => :d) do |result|
|
154
|
+
assert_equal list, result
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_execute_on_servers_without_current_task_should_raise_error_if_no_matching_servers
|
159
|
+
@config.expects(:find_servers).with(:a => :b, :c => :d).returns([])
|
160
|
+
assert_raises(Capistrano::NoMatchingServersError) { @config.execute_on_servers(:a => :b, :c => :d) { |list| } }
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_execute_on_servers_should_raise_an_error_if_the_current_task_has_no_matching_servers_by_default
|
164
|
+
@config.current_task = mock_task
|
165
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([])
|
166
|
+
assert_raises(Capistrano::NoMatchingServersError) do
|
167
|
+
@config.execute_on_servers do
|
168
|
+
flunk "should not get here"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_execute_on_servers_should_determine_server_list_from_active_task
|
174
|
+
assert @config.sessions.empty?
|
175
|
+
@config.current_task = mock_task
|
176
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2"), server("cap3")])
|
177
|
+
Capistrano::SSH.expects(:connect).times(3).returns(:success)
|
178
|
+
@config.execute_on_servers {}
|
179
|
+
assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_execute_on_servers_should_yield_server_list_to_block
|
183
|
+
assert @config.sessions.empty?
|
184
|
+
@config.current_task = mock_task
|
185
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2"), server("cap3")])
|
186
|
+
Capistrano::SSH.expects(:connect).times(3).returns(:success)
|
187
|
+
block_called = false
|
188
|
+
@config.execute_on_servers do |servers|
|
189
|
+
block_called = true
|
190
|
+
assert servers.detect { |s| s.host == "cap1" }
|
191
|
+
assert servers.detect { |s| s.host == "cap2" }
|
192
|
+
assert servers.detect { |s| s.host == "cap3" }
|
193
|
+
assert servers.all? { |s| @config.sessions[s] }
|
194
|
+
end
|
195
|
+
assert block_called
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_execute_on_servers_with_once_option_should_establish_connection_to_and_yield_only_the_first_server
|
199
|
+
assert @config.sessions.empty?
|
200
|
+
@config.current_task = mock_task
|
201
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, :once => true).returns([server("cap1"), server("cap2"), server("cap3")])
|
202
|
+
Capistrano::SSH.expects(:connect).returns(:success)
|
203
|
+
block_called = false
|
204
|
+
@config.execute_on_servers(:once => true) do |servers|
|
205
|
+
block_called = true
|
206
|
+
assert_equal %w(cap1), servers.map { |s| s.host }
|
207
|
+
end
|
208
|
+
assert block_called
|
209
|
+
assert_equal %w(cap1), @config.sessions.keys.sort.map { |s| s.host }
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_execute_servers_should_raise_connection_error_on_failure_by_default
|
213
|
+
@config.current_task = mock_task
|
214
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1")])
|
215
|
+
Capistrano::SSH.expects(:connect).raises(Exception)
|
216
|
+
assert_raises(Capistrano::ConnectionError) do
|
217
|
+
@config.execute_on_servers do
|
218
|
+
flunk "expected an exception to be raised"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_execute_servers_should_not_raise_connection_error_on_failure_with_on_errors_continue
|
224
|
+
@config.current_task = mock_task(:on_error => :continue)
|
225
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2")])
|
226
|
+
Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
|
227
|
+
Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
|
228
|
+
assert_nothing_raised {
|
229
|
+
@config.execute_on_servers do |servers|
|
230
|
+
assert_equal %w(cap2), servers.map { |s| s.host }
|
231
|
+
end
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_connection_errors_with_on_errors_continue
|
236
|
+
list = [server("cap1"), server("cap2")]
|
237
|
+
@config.current_task = mock_task(:on_error => :continue)
|
238
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns(list)
|
239
|
+
Capistrano::SSH.expects(:connect).with(server('cap1'), anything).raises(Exception)
|
240
|
+
Capistrano::SSH.expects(:connect).with(server('cap2'), anything).returns(:success)
|
241
|
+
@config.execute_on_servers do |servers|
|
242
|
+
assert_equal %w(cap2), servers.map { |s| s.host }
|
243
|
+
end
|
244
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns(list)
|
245
|
+
@config.execute_on_servers do |servers|
|
246
|
+
assert_equal %w(cap2), servers.map { |s| s.host }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_command_errors_with_on_errors_continue
|
251
|
+
cap1 = server("cap1")
|
252
|
+
cap2 = server("cap2")
|
253
|
+
@config.current_task = mock_task(:on_error => :continue)
|
254
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
255
|
+
Capistrano::SSH.expects(:connect).times(2).returns(:success)
|
256
|
+
@config.execute_on_servers do |servers|
|
257
|
+
error = Capistrano::CommandError.new
|
258
|
+
error.hosts = [cap1]
|
259
|
+
raise error
|
260
|
+
end
|
261
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
262
|
+
@config.execute_on_servers do |servers|
|
263
|
+
assert_equal %w(cap2), servers.map { |s| s.host }
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_transfer_errors_with_on_errors_continue
|
268
|
+
cap1 = server("cap1")
|
269
|
+
cap2 = server("cap2")
|
270
|
+
@config.current_task = mock_task(:on_error => :continue)
|
271
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
272
|
+
Capistrano::SSH.expects(:connect).times(2).returns(:success)
|
273
|
+
@config.execute_on_servers do |servers|
|
274
|
+
error = Capistrano::TransferError.new
|
275
|
+
error.hosts = [cap1]
|
276
|
+
raise error
|
277
|
+
end
|
278
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
279
|
+
@config.execute_on_servers do |servers|
|
280
|
+
assert_equal %w(cap2), servers.map { |s| s.host }
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_connect_should_establish_connections_to_all_servers_in_scope
|
285
|
+
assert @config.sessions.empty?
|
286
|
+
@config.current_task = mock_task
|
287
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2"), server("cap3")])
|
288
|
+
Capistrano::SSH.expects(:connect).times(3).returns(:success)
|
289
|
+
@config.connect!
|
290
|
+
assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_execute_on_servers_should_only_run_on_tasks_max_hosts_hosts_at_once
|
294
|
+
cap1 = server("cap1")
|
295
|
+
cap2 = server("cap2")
|
296
|
+
connection1 = mock()
|
297
|
+
connection2 = mock()
|
298
|
+
connection1.expects(:close)
|
299
|
+
connection2.expects(:close)
|
300
|
+
@config.current_task = mock_task(:max_hosts => 1)
|
301
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
302
|
+
Capistrano::SSH.expects(:connect).times(2).returns(connection1).then.returns(connection2)
|
303
|
+
block_called = 0
|
304
|
+
@config.execute_on_servers do |servers|
|
305
|
+
block_called += 1
|
306
|
+
assert_equal 1, servers.size
|
307
|
+
end
|
308
|
+
assert_equal 2, block_called
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_execute_on_servers_should_only_run_on_max_hosts_hosts_at_once
|
312
|
+
cap1 = server("cap1")
|
313
|
+
cap2 = server("cap2")
|
314
|
+
connection1 = mock()
|
315
|
+
connection2 = mock()
|
316
|
+
connection1.expects(:close)
|
317
|
+
connection2.expects(:close)
|
318
|
+
@config.current_task = mock_task(:max_hosts => 1)
|
319
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
|
320
|
+
Capistrano::SSH.expects(:connect).times(2).returns(connection1).then.returns(connection2)
|
321
|
+
block_called = 0
|
322
|
+
@config.execute_on_servers do |servers|
|
323
|
+
block_called += 1
|
324
|
+
assert_equal 1, servers.size
|
325
|
+
end
|
326
|
+
assert_equal 2, block_called
|
327
|
+
end
|
328
|
+
|
329
|
+
def test_connect_should_honor_once_option
|
330
|
+
assert @config.sessions.empty?
|
331
|
+
@config.current_task = mock_task
|
332
|
+
@config.expects(:find_servers_for_task).with(@config.current_task, :once => true).returns([server("cap1"), server("cap2"), server("cap3")])
|
333
|
+
Capistrano::SSH.expects(:connect).returns(:success)
|
334
|
+
@config.connect! :once => true
|
335
|
+
assert_equal %w(cap1), @config.sessions.keys.sort.map { |s| s.host }
|
336
|
+
end
|
337
|
+
|
338
|
+
private
|
339
|
+
|
340
|
+
def mock_task(options={})
|
341
|
+
continue_on_error = options[:on_error] == :continue
|
342
|
+
stub("task",
|
343
|
+
:fully_qualified_name => "name",
|
344
|
+
:options => options,
|
345
|
+
:continue_on_error? => continue_on_error,
|
346
|
+
:max_hosts => options[:max_hosts]
|
347
|
+
)
|
348
|
+
end
|
349
|
+
end
|