capistrano 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +89 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +674 -0
  7. data/README.md +226 -0
  8. data/Rakefile +5 -0
  9. data/bin/cap +2 -3
  10. data/bin/capify +7 -77
  11. data/capistrano-public_cert.pem +22 -0
  12. data/capistrano.gemspec +35 -0
  13. data/features/deploy.feature +52 -0
  14. data/features/installation.feature +16 -0
  15. data/features/remote_file_task.feature +14 -0
  16. data/features/step_definitions/assertions.rb +90 -0
  17. data/features/step_definitions/cap_commands.rb +8 -0
  18. data/features/step_definitions/setup.rb +25 -0
  19. data/features/support/env.rb +12 -0
  20. data/features/support/remote_command_helpers.rb +20 -0
  21. data/lib/Capfile +3 -0
  22. data/lib/capistrano/all.rb +16 -0
  23. data/lib/capistrano/application.rb +60 -0
  24. data/lib/capistrano/configuration/question.rb +42 -0
  25. data/lib/capistrano/configuration/server.rb +133 -0
  26. data/lib/capistrano/configuration/servers/role_filter.rb +86 -0
  27. data/lib/capistrano/configuration/servers.rb +53 -58
  28. data/lib/capistrano/configuration.rb +84 -30
  29. data/lib/capistrano/console.rb +1 -0
  30. data/lib/capistrano/defaults.rb +13 -0
  31. data/lib/capistrano/deploy.rb +3 -0
  32. data/lib/capistrano/dotfile.rb +3 -0
  33. data/lib/capistrano/dsl/env.rb +64 -0
  34. data/lib/capistrano/dsl/paths.rb +94 -0
  35. data/lib/capistrano/dsl/stages.rb +15 -0
  36. data/lib/capistrano/dsl/task_enhancements.rb +53 -0
  37. data/lib/capistrano/dsl.rb +48 -0
  38. data/lib/capistrano/git.rb +1 -0
  39. data/lib/capistrano/hg.rb +1 -0
  40. data/lib/capistrano/i18n.rb +34 -0
  41. data/lib/capistrano/install.rb +1 -0
  42. data/lib/capistrano/setup.rb +21 -0
  43. data/lib/capistrano/tasks/console.rake +21 -0
  44. data/lib/capistrano/tasks/deploy.rake +204 -0
  45. data/lib/capistrano/tasks/framework.rake +67 -0
  46. data/lib/capistrano/tasks/git.rake +62 -0
  47. data/lib/capistrano/tasks/hg.rake +39 -0
  48. data/lib/capistrano/tasks/install.rake +39 -0
  49. data/lib/capistrano/templates/Capfile +26 -0
  50. data/lib/capistrano/templates/deploy.rb.erb +40 -0
  51. data/lib/capistrano/templates/stage.rb.erb +42 -0
  52. data/lib/capistrano/version.rb +1 -20
  53. data/lib/capistrano/version_validator.rb +37 -0
  54. data/lib/capistrano.rb +0 -2
  55. data/spec/integration/dsl_spec.rb +344 -0
  56. data/spec/integration_spec_helper.rb +7 -0
  57. data/spec/lib/capistrano/application_spec.rb +61 -0
  58. data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
  59. data/spec/lib/capistrano/configuration/server_spec.rb +249 -0
  60. data/spec/lib/capistrano/configuration/servers/role_filter_spec.rb +140 -0
  61. data/spec/lib/capistrano/configuration/servers_spec.rb +184 -0
  62. data/spec/lib/capistrano/configuration_spec.rb +101 -0
  63. data/spec/lib/capistrano/dsl/env_spec.rb +10 -0
  64. data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
  65. data/spec/lib/capistrano/dsl_spec.rb +63 -0
  66. data/spec/lib/capistrano/version_validator_spec.rb +103 -0
  67. data/spec/lib/capistrano_spec.rb +8 -0
  68. data/spec/spec_helper.rb +15 -0
  69. data/spec/support/.gitignore +1 -0
  70. data/spec/support/Vagrantfile +13 -0
  71. data/spec/support/matchers.rb +5 -0
  72. data/spec/support/tasks/database.cap +11 -0
  73. data/spec/support/test_app.rb +138 -0
  74. metadata +251 -179
  75. data/CHANGELOG +0 -512
  76. data/MIT-LICENSE +0 -20
  77. data/README +0 -43
  78. data/examples/sample.rb +0 -14
  79. data/lib/capistrano/callback.rb +0 -45
  80. data/lib/capistrano/cli/execute.rb +0 -82
  81. data/lib/capistrano/cli/help.rb +0 -102
  82. data/lib/capistrano/cli/help.txt +0 -53
  83. data/lib/capistrano/cli/options.rb +0 -183
  84. data/lib/capistrano/cli/ui.rb +0 -28
  85. data/lib/capistrano/cli.rb +0 -47
  86. data/lib/capistrano/command.rb +0 -161
  87. data/lib/capistrano/configuration/actions/file_transfer.rb +0 -35
  88. data/lib/capistrano/configuration/actions/inspect.rb +0 -46
  89. data/lib/capistrano/configuration/actions/invocation.rb +0 -134
  90. data/lib/capistrano/configuration/callbacks.rb +0 -148
  91. data/lib/capistrano/configuration/connections.rb +0 -159
  92. data/lib/capistrano/configuration/execution.rb +0 -126
  93. data/lib/capistrano/configuration/loading.rb +0 -198
  94. data/lib/capistrano/configuration/namespaces.rb +0 -196
  95. data/lib/capistrano/configuration/roles.rb +0 -51
  96. data/lib/capistrano/configuration/variables.rb +0 -127
  97. data/lib/capistrano/errors.rb +0 -15
  98. data/lib/capistrano/extensions.rb +0 -57
  99. data/lib/capistrano/gateway.rb +0 -131
  100. data/lib/capistrano/logger.rb +0 -59
  101. data/lib/capistrano/recipes/compat.rb +0 -32
  102. data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
  103. data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -46
  104. data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -96
  105. data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
  106. data/lib/capistrano/recipes/deploy/scm/base.rb +0 -192
  107. data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
  108. data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -151
  109. data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -85
  110. data/lib/capistrano/recipes/deploy/scm/git.rb +0 -191
  111. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -129
  112. data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -126
  113. data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -114
  114. data/lib/capistrano/recipes/deploy/scm.rb +0 -19
  115. data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -64
  116. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
  117. data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -144
  118. data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
  119. data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
  120. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -47
  121. data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
  122. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
  123. data/lib/capistrano/recipes/deploy.rb +0 -494
  124. data/lib/capistrano/recipes/standard.rb +0 -37
  125. data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
  126. data/lib/capistrano/recipes/upgrade.rb +0 -33
  127. data/lib/capistrano/server_definition.rb +0 -51
  128. data/lib/capistrano/shell.rb +0 -256
  129. data/lib/capistrano/ssh.rb +0 -109
  130. data/lib/capistrano/task_definition.rb +0 -69
  131. data/lib/capistrano/upload.rb +0 -146
  132. data/test/cli/execute_test.rb +0 -132
  133. data/test/cli/help_test.rb +0 -139
  134. data/test/cli/options_test.rb +0 -226
  135. data/test/cli/ui_test.rb +0 -28
  136. data/test/cli_test.rb +0 -17
  137. data/test/command_test.rb +0 -309
  138. data/test/configuration/actions/file_transfer_test.rb +0 -40
  139. data/test/configuration/actions/inspect_test.rb +0 -62
  140. data/test/configuration/actions/invocation_test.rb +0 -202
  141. data/test/configuration/callbacks_test.rb +0 -206
  142. data/test/configuration/connections_test.rb +0 -288
  143. data/test/configuration/execution_test.rb +0 -159
  144. data/test/configuration/loading_test.rb +0 -127
  145. data/test/configuration/namespace_dsl_test.rb +0 -297
  146. data/test/configuration/roles_test.rb +0 -47
  147. data/test/configuration/servers_test.rb +0 -90
  148. data/test/configuration/variables_test.rb +0 -180
  149. data/test/configuration_test.rb +0 -81
  150. data/test/deploy/scm/accurev_test.rb +0 -23
  151. data/test/deploy/scm/base_test.rb +0 -55
  152. data/test/deploy/scm/git_test.rb +0 -112
  153. data/test/deploy/strategy/copy_test.rb +0 -147
  154. data/test/extensions_test.rb +0 -69
  155. data/test/fixtures/cli_integration.rb +0 -5
  156. data/test/fixtures/config.rb +0 -5
  157. data/test/fixtures/custom.rb +0 -3
  158. data/test/gateway_test.rb +0 -167
  159. data/test/logger_test.rb +0 -123
  160. data/test/server_definition_test.rb +0 -108
  161. data/test/shell_test.rb +0 -64
  162. data/test/ssh_test.rb +0 -97
  163. data/test/task_definition_test.rb +0 -101
  164. data/test/upload_test.rb +0 -131
  165. data/test/utils.rb +0 -42
  166. data/test/version_test.rb +0 -24
@@ -1,206 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../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
- @called << task
16
- end
17
-
18
- include Capistrano::Configuration::Callbacks
19
- end
20
-
21
- def setup
22
- @config = MockConfig.new
23
- @config.stubs(:logger).returns(stub_everything("logger"))
24
- end
25
-
26
- def test_initialize_should_initialize_callbacks_collection
27
- assert @config.original_initialize_called
28
- assert @config.callbacks.empty?
29
- end
30
-
31
- def test_before_should_delegate_to_on
32
- @config.expects(:on).with(:before, :foo, "bing:blang", {:only => :bar, :zip => :zing})
33
- @config.before :bar, :foo, "bing:blang", :zip => :zing
34
- end
35
-
36
- def test_after_should_delegate_to_on
37
- @config.expects(:on).with(:after, :foo, "bing:blang", {:only => :bar, :zip => :zing})
38
- @config.after :bar, :foo, "bing:blang", :zip => :zing
39
- end
40
-
41
- def test_on_with_single_reference_should_add_task_callback
42
- @config.on :before, :a_test
43
- assert_equal 1, @config.callbacks[:before].length
44
- assert_equal :a_test, @config.callbacks[:before][0].source
45
- @config.expects(:find_and_execute_task).with(:a_test)
46
- @config.callbacks[:before][0].call
47
- end
48
-
49
- def test_on_with_multi_reference_should_add_all_as_task_callback
50
- @config.on :before, :first, :second, :third
51
- assert_equal 3, @config.callbacks[:before].length
52
- assert_equal %w(first second third), @config.callbacks[:before].map { |c| c.source.to_s }
53
- end
54
-
55
- def test_on_with_block_should_add_block_as_proc_callback
56
- called = false
57
- @config.on(:before) { called = true }
58
- assert_equal 1, @config.callbacks[:before].length
59
- assert_instance_of Proc, @config.callbacks[:before][0].source
60
- @config.callbacks[:before][0].call
61
- assert called
62
- end
63
-
64
- def test_on_with_single_only_should_set_only_as_string_array_on_all_references
65
- @config.on :before, :first, "second:third", :only => :primary
66
- assert_equal 2, @config.callbacks[:before].length
67
- assert @config.callbacks[:before].all? { |c| c.only == %w(primary) }
68
- end
69
-
70
- def test_on_with_multi_only_should_set_only_as_string_array_on_all_references
71
- @config.on :before, :first, "second:third", :only => [:primary, "other:one"]
72
- assert_equal 2, @config.callbacks[:before].length
73
- assert @config.callbacks[:before].all? { |c| c.only == %w(primary other:one) }
74
- end
75
-
76
- def test_on_with_single_except_should_set_except_as_string_array_on_all_references
77
- @config.on :before, :first, "second:third", :except => :primary
78
- assert_equal 2, @config.callbacks[:before].length
79
- assert @config.callbacks[:before].all? { |c| c.except == %w(primary) }
80
- end
81
-
82
- def test_on_with_multi_except_should_set_except_as_string_array_on_all_references
83
- @config.on :before, :first, "second:third", :except => [:primary, "other:one"]
84
- assert_equal 2, @config.callbacks[:before].length
85
- assert @config.callbacks[:before].all? { |c| c.except == %w(primary other:one) }
86
- end
87
-
88
- def test_on_with_only_and_block_should_set_only_as_string_array
89
- @config.on(:before, :only => :primary) { blah }
90
- assert_equal 1, @config.callbacks[:before].length
91
- assert_equal %w(primary), @config.callbacks[:before].first.only
92
- end
93
-
94
- def test_on_with_except_and_block_should_set_except_as_string_array
95
- @config.on(:before, :except => :primary) { blah }
96
- assert_equal 1, @config.callbacks[:before].length
97
- assert_equal %w(primary), @config.callbacks[:before].first.except
98
- end
99
-
100
- def test_trigger_without_constraints_should_invoke_all_callbacks
101
- task = stub(:fully_qualified_name => "any:old:thing")
102
- @config.on(:before, :first, "second:third")
103
- @config.on(:after, :another, "and:another")
104
- @config.expects(:find_and_execute_task).with(:first)
105
- @config.expects(:find_and_execute_task).with("second:third")
106
- @config.expects(:find_and_execute_task).with(:another).never
107
- @config.expects(:find_and_execute_task).with("and:another").never
108
- @config.trigger(:before, task)
109
- end
110
-
111
- def test_trigger_with_only_constraint_should_invoke_only_matching_callbacks
112
- task = stub(:fully_qualified_name => "any:old:thing")
113
- @config.on(:before, :first)
114
- @config.on(:before, "second:third", :only => "any:old:thing")
115
- @config.on(:before, "this:too", :only => "any:other:thing")
116
- @config.on(:after, :another, "and:another")
117
- @config.expects(:find_and_execute_task).with(:first)
118
- @config.expects(:find_and_execute_task).with("second:third")
119
- @config.expects(:find_and_execute_task).with("this:too").never
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_except_constraint_should_invoke_anything_but_matching_callbacks
126
- task = stub(:fully_qualified_name => "any:old:thing")
127
- @config.on(:before, :first)
128
- @config.on(:before, "second:third", :except => "any:old:thing")
129
- @config.on(:before, "this:too", :except => "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").never
133
- @config.expects(:find_and_execute_task).with("this:too")
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_without_task_should_invoke_all_callbacks_for_that_event
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")
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)
151
- end
152
-
153
- def test_execute_task_without_named_hooks_should_just_call_task
154
- ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
155
- task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
156
-
157
- ns.stubs(:search_task).returns(nil)
158
-
159
- @config.execute_task(task)
160
- assert_equal [task], @config.called
161
- end
162
-
163
- def test_execute_task_with_named_before_hook_should_call_named_before_hook
164
- ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
165
- task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
166
- before_task = stub(:fully_qualified_name => "any:old:before_thing", :name => "before_thing", :namespace => ns)
167
-
168
- ns.stubs(:search_task).returns(nil)
169
- ns.expects(:search_task).with("before_thing").returns(before_task)
170
-
171
- @config.execute_task(task)
172
- assert_equal [before_task, task], @config.called
173
- end
174
-
175
- def test_execute_task_with_named_after_hook_should_call_named_after_hook
176
- ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
177
- task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
178
- after_task = stub(:fully_qualified_name => "any:old:after_thing", :name => "after_thing", :namespace => ns)
179
-
180
- ns.stubs(:search_task).returns(nil)
181
- ns.expects(:search_task).with("after_thing").returns(after_task)
182
-
183
- @config.execute_task(task)
184
- assert_equal [task, after_task], @config.called
185
- end
186
-
187
- def test_execute_task_with_on_hooks_should_trigger_hooks_around_task
188
- ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
189
- task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
190
- before_task = stub(:fully_qualified_name => "any:old:before_thing", :name => "before_thing", :namespace => ns)
191
- after_task = stub(:fully_qualified_name => "any:old:after_thing", :name => "after_thing", :namespace => ns)
192
-
193
- ns.stubs(:search_task).returns(nil)
194
- ns.expects(:search_task).with("before_thing").returns(before_task)
195
- ns.expects(:search_task).with("after_thing").returns(after_task)
196
-
197
- @config.before("any:old:thing", :first_this, :then_this)
198
- @config.after("any:old:thing", :and_then_this, :lastly_this)
199
-
200
- [:first_this, :then_this, :and_then_this, :lastly_this].each do |t|
201
- @config.expects(:find_and_execute_task).with(t)
202
- end
203
-
204
- @config.execute_task(task)
205
- end
206
- end
@@ -1,288 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../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
- @ssh_options = {
34
- :user => "jamis",
35
- :port => 8080,
36
- :password => "g00b3r",
37
- :ssh_options => { :debug => :verbose }
38
- }
39
- end
40
-
41
- def test_initialize_should_initialize_collections_and_call_original_initialize
42
- assert @config.original_initialize_called
43
- assert @config.sessions.empty?
44
- end
45
-
46
- def test_connection_factory_should_return_default_connection_factory_instance
47
- factory = @config.connection_factory
48
- assert_instance_of Capistrano::Configuration::Connections::DefaultConnectionFactory, factory
49
- end
50
-
51
- def test_connection_factory_instance_should_be_cached
52
- assert_same @config.connection_factory, @config.connection_factory
53
- end
54
-
55
- def test_default_connection_factory_honors_config_options
56
- server = server("capistrano")
57
- Capistrano::SSH.expects(:connect).with(server, @config).returns(:session)
58
- assert_equal :session, @config.connection_factory.connect_to(server)
59
- end
60
-
61
- def test_connection_factory_should_return_gateway_instance_if_gateway_variable_is_set
62
- @config.values[:gateway] = "capistrano"
63
- server = server("capistrano")
64
- Capistrano::SSH.expects(:connect).with { |s,| s.host == "capistrano" }.yields(stub_everything)
65
- assert_instance_of Capistrano::Gateway, @config.connection_factory
66
- end
67
-
68
- def test_connection_factory_as_gateway_should_honor_config_options
69
- @config.values[:gateway] = "capistrano"
70
- @config.values.update(@ssh_options)
71
- Capistrano::SSH.expects(:connect).with { |s,opts| s.host == "capistrano" && opts == @config }.yields(stub_everything)
72
- assert_instance_of Capistrano::Gateway, @config.connection_factory
73
- end
74
-
75
- def test_establish_connections_to_should_accept_a_single_nonarray_parameter
76
- Capistrano::SSH.expects(:connect).with { |s,| s.host == "capistrano" }.returns(:success)
77
- assert @config.sessions.empty?
78
- @config.establish_connections_to(server("capistrano"))
79
- assert ["capistrano"], @config.sessions.keys
80
- end
81
-
82
- def test_establish_connections_to_should_accept_an_array
83
- Capistrano::SSH.expects(:connect).times(3).returns(:success)
84
- assert @config.sessions.empty?
85
- @config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
86
- assert %w(cap1 cap2 cap3), @config.sessions.keys.sort
87
- end
88
-
89
- def test_establish_connections_to_should_not_attempt_to_reestablish_existing_connections
90
- Capistrano::SSH.expects(:connect).times(2).returns(:success)
91
- @config.sessions[server("cap1")] = :ok
92
- @config.establish_connections_to(%w(cap1 cap2 cap3).map { |s| server(s) })
93
- assert %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
94
- end
95
-
96
- def test_establish_connections_to_should_raise_one_connection_error_on_failure
97
- Capistrano::SSH.expects(:connect).times(2).raises(Exception)
98
- assert_raises(Capistrano::ConnectionError) {
99
- @config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
100
- }
101
- end
102
-
103
- def test_connection_error_should_include_accessor_with_host_array
104
- Capistrano::SSH.expects(:connect).times(2).raises(Exception)
105
-
106
- begin
107
- @config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
108
- flunk "expected an exception to be raised"
109
- rescue Capistrano::ConnectionError => e
110
- assert e.respond_to?(:hosts)
111
- assert_equal %w(cap1 cap2), e.hosts.map { |h| h.to_s }
112
- end
113
- end
114
-
115
- def test_connection_error_should_only_include_failed_hosts
116
- Capistrano::SSH.expects(:connect).times(2).raises(Exception).then.returns(:success)
117
-
118
- begin
119
- @config.establish_connections_to(%w(cap1 cap2).map { |s| server(s) })
120
- flunk "expected an exception to be raised"
121
- rescue Capistrano::ConnectionError => e
122
- assert_equal %w(cap1), e.hosts.map { |h| h.to_s }
123
- end
124
- end
125
-
126
- def test_execute_on_servers_should_require_a_block
127
- assert_raises(ArgumentError) { @config.execute_on_servers }
128
- end
129
-
130
- def test_execute_on_servers_without_current_task_should_call_find_servers
131
- list = [server("first"), server("second")]
132
- @config.expects(:find_servers).with(:a => :b, :c => :d).returns(list)
133
- @config.expects(:establish_connections_to).with(list).returns(:done)
134
- @config.execute_on_servers(:a => :b, :c => :d) do |result|
135
- assert_equal list, result
136
- end
137
- end
138
-
139
- def test_execute_on_servers_without_current_task_should_raise_error_if_no_matching_servers
140
- @config.expects(:find_servers).with(:a => :b, :c => :d).returns([])
141
- assert_raises(Capistrano::NoMatchingServersError) { @config.execute_on_servers(:a => :b, :c => :d) { |list| } }
142
- end
143
-
144
- def test_execute_on_servers_should_raise_an_error_if_the_current_task_has_no_matching_servers_by_default
145
- @config.current_task = mock_task
146
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([])
147
- assert_raises(Capistrano::NoMatchingServersError) do
148
- @config.execute_on_servers do
149
- flunk "should not get here"
150
- end
151
- end
152
- end
153
-
154
- def test_execute_on_servers_should_determine_server_list_from_active_task
155
- assert @config.sessions.empty?
156
- @config.current_task = mock_task
157
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2"), server("cap3")])
158
- Capistrano::SSH.expects(:connect).times(3).returns(:success)
159
- @config.execute_on_servers {}
160
- assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
161
- end
162
-
163
- def test_execute_on_servers_should_yield_server_list_to_block
164
- assert @config.sessions.empty?
165
- @config.current_task = mock_task
166
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2"), server("cap3")])
167
- Capistrano::SSH.expects(:connect).times(3).returns(:success)
168
- block_called = false
169
- @config.execute_on_servers do |servers|
170
- block_called = true
171
- assert servers.detect { |s| s.host == "cap1" }
172
- assert servers.detect { |s| s.host == "cap2" }
173
- assert servers.detect { |s| s.host == "cap3" }
174
- assert servers.all? { |s| @config.sessions[s] }
175
- end
176
- assert block_called
177
- end
178
-
179
- def test_execute_on_servers_with_once_option_should_establish_connection_to_and_yield_only_the_first_server
180
- assert @config.sessions.empty?
181
- @config.current_task = mock_task
182
- @config.expects(:find_servers_for_task).with(@config.current_task, :once => true).returns([server("cap1"), server("cap2"), server("cap3")])
183
- Capistrano::SSH.expects(:connect).returns(:success)
184
- block_called = false
185
- @config.execute_on_servers(:once => true) do |servers|
186
- block_called = true
187
- assert_equal %w(cap1), servers.map { |s| s.host }
188
- end
189
- assert block_called
190
- assert_equal %w(cap1), @config.sessions.keys.sort.map { |s| s.host }
191
- end
192
-
193
- def test_execute_servers_should_raise_connection_error_on_failure_by_default
194
- @config.current_task = mock_task
195
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1")])
196
- Capistrano::SSH.expects(:connect).raises(Exception)
197
- assert_raises(Capistrano::ConnectionError) {
198
- @config.execute_on_servers do
199
- flunk "expected an exception to be raised"
200
- end
201
- }
202
- end
203
-
204
- def test_execute_servers_should_not_raise_connection_error_on_failure_with_on_errors_continue
205
- @config.current_task = mock_task(:on_error => :continue)
206
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2")])
207
- Capistrano::SSH.expects(:connect).times(2).raises(Exception).then.returns(:success)
208
- assert_nothing_raised {
209
- @config.execute_on_servers do |servers|
210
- assert_equal %w(cap2), servers.map { |s| s.host }
211
- end
212
- }
213
- end
214
-
215
- def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_connection_errors_with_on_errors_continue
216
- list = [server("cap1"), server("cap2")]
217
- @config.current_task = mock_task(:on_error => :continue)
218
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns(list)
219
- Capistrano::SSH.expects(:connect).times(2).raises(Exception).then.returns(:success)
220
- @config.expects(:failed!).with(server("cap1"))
221
- @config.execute_on_servers do |servers|
222
- assert_equal %w(cap2), servers.map { |s| s.host }
223
- end
224
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns(list)
225
- @config.execute_on_servers do |servers|
226
- assert_equal %w(cap2), servers.map { |s| s.host }
227
- end
228
- end
229
-
230
- def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_command_errors_with_on_errors_continue
231
- cap1 = server("cap1")
232
- cap2 = server("cap2")
233
- @config.current_task = mock_task(:on_error => :continue)
234
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
235
- Capistrano::SSH.expects(:connect).times(2).returns(:success)
236
- @config.execute_on_servers do |servers|
237
- error = Capistrano::CommandError.new
238
- error.hosts = [cap1]
239
- raise error
240
- end
241
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
242
- @config.execute_on_servers do |servers|
243
- assert_equal %w(cap2), servers.map { |s| s.host }
244
- end
245
- end
246
-
247
- def test_execute_on_servers_should_not_try_to_connect_to_hosts_with_upload_errors_with_on_errors_continue
248
- cap1 = server("cap1")
249
- cap2 = server("cap2")
250
- @config.current_task = mock_task(:on_error => :continue)
251
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
252
- Capistrano::SSH.expects(:connect).times(2).returns(:success)
253
- @config.execute_on_servers do |servers|
254
- error = Capistrano::UploadError.new
255
- error.hosts = [cap1]
256
- raise error
257
- end
258
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([cap1, cap2])
259
- @config.execute_on_servers do |servers|
260
- assert_equal %w(cap2), servers.map { |s| s.host }
261
- end
262
- end
263
-
264
- def test_connect_should_establish_connections_to_all_servers_in_scope
265
- assert @config.sessions.empty?
266
- @config.current_task = mock_task
267
- @config.expects(:find_servers_for_task).with(@config.current_task, {}).returns([server("cap1"), server("cap2"), server("cap3")])
268
- Capistrano::SSH.expects(:connect).times(3).returns(:success)
269
- @config.connect!
270
- assert_equal %w(cap1 cap2 cap3), @config.sessions.keys.sort.map { |s| s.host }
271
- end
272
-
273
- def test_connect_should_honor_once_option
274
- assert @config.sessions.empty?
275
- @config.current_task = mock_task
276
- @config.expects(:find_servers_for_task).with(@config.current_task, :once => true).returns([server("cap1"), server("cap2"), server("cap3")])
277
- Capistrano::SSH.expects(:connect).returns(:success)
278
- @config.connect! :once => true
279
- assert_equal %w(cap1), @config.sessions.keys.sort.map { |s| s.host }
280
- end
281
-
282
- private
283
-
284
- def mock_task(options={})
285
- continue_on_error = options[:on_error] == :continue
286
- stub("task", :fully_qualified_name => "name", :options => options, :continue_on_error? => continue_on_error)
287
- end
288
- end
@@ -1,159 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../utils"
2
- require 'capistrano/configuration/execution'
3
- require 'capistrano/task_definition'
4
-
5
- class ConfigurationExecutionTest < Test::Unit::TestCase
6
- class MockConfig
7
- attr_reader :tasks, :namespaces, :fully_qualified_name, :parent
8
- attr_reader :state, :original_initialize_called
9
- attr_accessor :logger, :default_task
10
-
11
- def initialize(options={})
12
- @original_initialize_called = true
13
- @tasks = {}
14
- @namespaces = {}
15
- @state = {}
16
- @fully_qualified_name = options[:fqn]
17
- @parent = options[:parent]
18
- @logger = options.delete(:logger)
19
- end
20
-
21
- include Capistrano::Configuration::Execution
22
- end
23
-
24
- def setup
25
- @config = MockConfig.new(:logger => stub(:debug => nil, :info => nil, :important => nil))
26
- @config.stubs(:search_task).returns(nil)
27
- end
28
-
29
- def test_initialize_should_initialize_collections
30
- assert_nil @config.rollback_requests
31
- assert @config.original_initialize_called
32
- assert @config.task_call_frames.empty?
33
- end
34
-
35
- def test_execute_task_should_populate_call_stack
36
- task = new_task @config, :testing
37
- assert_nothing_raised { @config.execute_task(task) }
38
- assert_equal %w(testing), @config.state[:testing][:stack]
39
- assert_nil @config.state[:testing][:history]
40
- assert @config.task_call_frames.empty?
41
- end
42
-
43
- def test_nested_execute_task_should_add_to_call_stack
44
- testing = new_task @config, :testing
45
- outer = new_task(@config, :outer) { execute_task(testing) }
46
-
47
- assert_nothing_raised { @config.execute_task(outer) }
48
- assert_equal %w(outer testing), @config.state[:testing][:stack]
49
- assert_nil @config.state[:testing][:history]
50
- assert @config.task_call_frames.empty?
51
- end
52
-
53
- def test_execute_task_should_execute_in_scope_of_tasks_parent
54
- ns = stub("namespace", :tasks => {}, :default_task => nil, :fully_qualified_name => "ns")
55
- ns.expects(:instance_eval)
56
- testing = new_task ns, :testing
57
- @config.execute_task(testing)
58
- end
59
-
60
- def test_transaction_outside_of_task_should_raise_exception
61
- assert_raises(ScriptError) { @config.transaction {} }
62
- end
63
-
64
- def test_transaction_without_block_should_raise_argument_error
65
- testing = new_task(@config, :testing) { transaction }
66
- assert_raises(ArgumentError) { @config.execute_task(testing) }
67
- end
68
-
69
- def test_transaction_should_initialize_transaction_history
70
- @config.state[:inspector] = stack_inspector
71
- testing = new_task(@config, :testing) { transaction { instance_eval(&state[:inspector]) } }
72
- @config.execute_task(testing)
73
- assert_equal [], @config.state[:testing][:history]
74
- end
75
-
76
- def test_transaction_from_within_transaction_should_not_start_new_transaction
77
- third = new_task(@config, :third, &stack_inspector)
78
- second = new_task(@config, :second) { transaction { execute_task(third) } }
79
- first = new_task(@config, :first) { transaction { execute_task(second) } }
80
- # kind of fragile...not sure how else to check that transaction was only
81
- # really run twice...but if the transaction was REALLY run, logger.info
82
- # will be called once when it starts, and once when it finishes.
83
- @config.logger = mock()
84
- @config.logger.stubs(:debug)
85
- @config.logger.expects(:info).times(2)
86
- @config.execute_task(first)
87
- end
88
-
89
- def test_on_rollback_should_have_no_effect_outside_of_transaction
90
- aaa = new_task(@config, :aaa) { on_rollback { state[:rollback] = true }; raise "boom" }
91
- assert_raises(RuntimeError) { @config.execute_task(aaa) }
92
- assert_nil @config.state[:rollback]
93
- end
94
-
95
- def test_exception_raised_in_transaction_should_call_all_registered_rollback_handlers_in_reverse_order
96
- aaa = new_task(@config, :aaa) { on_rollback { (state[:rollback] ||= []) << :aaa } }
97
- bbb = new_task(@config, :bbb) { on_rollback { (state[:rollback] ||= []) << :bbb } }
98
- ccc = new_task(@config, :ccc) {}
99
- ddd = new_task(@config, :ddd) { on_rollback { (state[:rollback] ||= []) << :ddd }; execute_task(bbb); execute_task(ccc) }
100
- eee = new_task(@config, :eee) { transaction { execute_task(ddd); execute_task(aaa); raise "boom" } }
101
- assert_raises(RuntimeError) do
102
- @config.execute_task(eee)
103
- end
104
- assert_equal [:aaa, :bbb, :ddd], @config.state[:rollback]
105
- assert_nil @config.rollback_requests
106
- assert @config.task_call_frames.empty?
107
- end
108
-
109
- def test_exception_during_rollback_should_simply_be_logged_and_ignored
110
- aaa = new_task(@config, :aaa) { on_rollback { state[:aaa] = true; raise LoadError, "ouch" }; execute_task(bbb) }
111
- bbb = new_task(@config, :bbb) { raise MadError, "boom" }
112
- ccc = new_task(@config, :ccc) { transaction { execute_task(aaa) } }
113
- assert_raises(NameError) do
114
- @config.execute_task(ccc)
115
- end
116
- assert @config.state[:aaa]
117
- end
118
-
119
- def test_find_and_execute_task_should_raise_error_when_task_cannot_be_found
120
- @config.expects(:find_task).with("path:to:task").returns(nil)
121
- assert_raises(Capistrano::NoSuchTaskError) { @config.find_and_execute_task("path:to:task") }
122
- end
123
-
124
- def test_find_and_execute_task_should_execute_task_when_task_is_found
125
- @config.expects(:find_task).with("path:to:task").returns(:found)
126
- @config.expects(:execute_task).with(:found)
127
- assert_nothing_raised { @config.find_and_execute_task("path:to:task") }
128
- end
129
-
130
- def test_find_and_execute_task_with_before_option_should_trigger_callback
131
- @config.expects(:find_task).with("path:to:task").returns(:found)
132
- @config.expects(:trigger).with(:incoming, :found)
133
- @config.expects(:execute_task).with(:found)
134
- @config.find_and_execute_task("path:to:task", :before => :incoming)
135
- end
136
-
137
- def test_find_and_execute_task_with_after_option_should_trigger_callback
138
- @config.expects(:find_task).with("path:to:task").returns(:found)
139
- @config.expects(:trigger).with(:outgoing, :found)
140
- @config.expects(:execute_task).with(:found)
141
- @config.find_and_execute_task("path:to:task", :after => :outgoing)
142
- end
143
-
144
- private
145
-
146
- def stack_inspector
147
- Proc.new do
148
- (state[:trail] ||= []) << current_task.fully_qualified_name
149
- data = state[current_task.name] = {}
150
- data[:stack] = task_call_frames.map { |frame| frame.task.fully_qualified_name }
151
- data[:history] = rollback_requests && rollback_requests.map { |frame| frame.task.fully_qualified_name }
152
- end
153
- end
154
-
155
- def new_task(namespace, name, options={}, &block)
156
- block ||= stack_inspector
157
- namespace.tasks[name] = Capistrano::TaskDefinition.new(name, namespace, &block)
158
- end
159
- end