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
data/test/command_test.rb
CHANGED
|
@@ -1,129 +1,127 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "utils"
|
|
2
2
|
require 'capistrano/command'
|
|
3
|
+
require 'capistrano/configuration'
|
|
3
4
|
|
|
4
5
|
class CommandTest < Test::Unit::TestCase
|
|
5
6
|
def test_command_should_open_channels_on_all_sessions
|
|
6
|
-
s1 =
|
|
7
|
-
|
|
8
|
-
s3 = mock(:open_channel => nil)
|
|
9
|
-
assert_equal "ls", Capistrano::Command.new("ls", [s1, s2, s3]).command
|
|
7
|
+
s1, s2, s3 = mock_session, mock_session, mock_session
|
|
8
|
+
assert_equal "ls", Capistrano::Command.new("ls", [s1, s2, s3]).tree.fallback.command
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
def test_command_with_newlines_should_be_properly_escaped
|
|
13
|
-
cmd = Capistrano::Command.new("ls\necho", [
|
|
14
|
-
assert_equal "ls\\\necho", cmd.command
|
|
12
|
+
cmd = Capistrano::Command.new("ls\necho", [mock_session])
|
|
13
|
+
assert_equal "ls\\\necho", cmd.tree.fallback.command
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
def test_command_with_windows_newlines_should_be_properly_escaped
|
|
18
|
-
cmd = Capistrano::Command.new("ls\r\necho", [
|
|
19
|
-
assert_equal "ls\\\necho", cmd.command
|
|
17
|
+
cmd = Capistrano::Command.new("ls\r\necho", [mock_session])
|
|
18
|
+
assert_equal "ls\\\necho", cmd.tree.fallback.command
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_command_with_pty_should_request_pty_and_register_success_callback
|
|
22
|
+
session = setup_for_extracting_channel_action(:request_pty, true) do |ch|
|
|
23
|
+
ch.expects(:exec).with(%(sh -c 'ls'))
|
|
24
|
+
end
|
|
25
|
+
Capistrano::Command.new("ls", [session], :pty => true)
|
|
20
26
|
end
|
|
21
27
|
|
|
22
28
|
def test_command_with_env_key_should_have_environment_constructed_and_prepended
|
|
23
|
-
session = setup_for_extracting_channel_action
|
|
24
|
-
ch.expects(:
|
|
29
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
30
|
+
ch.expects(:request_pty).never
|
|
31
|
+
ch.expects(:exec).with(%(env FOO=bar sh -c 'ls'))
|
|
25
32
|
end
|
|
26
33
|
Capistrano::Command.new("ls", [session], :env => { "FOO" => "bar" })
|
|
27
34
|
end
|
|
28
35
|
|
|
29
36
|
def test_env_with_symbolic_key_should_be_accepted_as_a_string
|
|
30
|
-
session = setup_for_extracting_channel_action
|
|
31
|
-
ch.expects(:exec).with(%(env FOO=bar sh -c
|
|
37
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
38
|
+
ch.expects(:exec).with(%(env FOO=bar sh -c 'ls'))
|
|
32
39
|
end
|
|
33
40
|
Capistrano::Command.new("ls", [session], :env => { :FOO => "bar" })
|
|
34
41
|
end
|
|
35
42
|
|
|
36
43
|
def test_env_as_string_should_be_substituted_in_directly
|
|
37
|
-
session = setup_for_extracting_channel_action
|
|
38
|
-
ch.expects(:exec).with(%(env HOWDY=there sh -c
|
|
44
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
45
|
+
ch.expects(:exec).with(%(env HOWDY=there sh -c 'ls'))
|
|
39
46
|
end
|
|
40
47
|
Capistrano::Command.new("ls", [session], :env => "HOWDY=there")
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
def test_env_with_symbolic_value_should_be_accepted_as_string
|
|
44
|
-
session = setup_for_extracting_channel_action
|
|
45
|
-
ch.expects(:exec).with(%(env FOO=bar sh -c
|
|
51
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
52
|
+
ch.expects(:exec).with(%(env FOO=bar sh -c 'ls'))
|
|
46
53
|
end
|
|
47
54
|
Capistrano::Command.new("ls", [session], :env => { "FOO" => :bar })
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
def test_env_value_should_be_escaped
|
|
51
|
-
session = setup_for_extracting_channel_action
|
|
52
|
-
ch.expects(:exec).with(%(env FOO=(\\ \\\"bar\\\"\\ ) sh -c
|
|
58
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
59
|
+
ch.expects(:exec).with(%(env FOO=(\\ \\\"bar\\\"\\ ) sh -c 'ls'))
|
|
53
60
|
end
|
|
54
61
|
Capistrano::Command.new("ls", [session], :env => { "FOO" => '( "bar" )' })
|
|
55
62
|
end
|
|
56
63
|
|
|
57
64
|
def test_env_with_multiple_keys_should_chain_the_entries_together
|
|
58
|
-
session = setup_for_extracting_channel_action
|
|
65
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
59
66
|
ch.expects(:exec).with do |command|
|
|
60
67
|
command =~ /^env / &&
|
|
61
68
|
command =~ /\ba=b\b/ &&
|
|
62
69
|
command =~ /\bc=d\b/ &&
|
|
63
70
|
command =~ /\be=f\b/ &&
|
|
64
|
-
command =~ / sh -c
|
|
71
|
+
command =~ / sh -c 'ls'$/
|
|
65
72
|
end
|
|
66
73
|
end
|
|
67
74
|
Capistrano::Command.new("ls", [session], :env => { :a => :b, :c => :d, :e => :f })
|
|
68
75
|
end
|
|
69
76
|
|
|
70
77
|
def test_open_channel_should_set_host_key_on_channel
|
|
71
|
-
|
|
72
|
-
channel =
|
|
73
|
-
|
|
74
|
-
session.expects(:open_channel).yields(channel)
|
|
75
|
-
channel.expects(:[]=).with(:host, "capistrano")
|
|
76
|
-
|
|
78
|
+
channel = nil
|
|
79
|
+
session = setup_for_extracting_channel_action { |ch| channel = ch }
|
|
77
80
|
Capistrano::Command.new("ls", [session])
|
|
81
|
+
assert_equal "capistrano", channel[:host]
|
|
78
82
|
end
|
|
79
83
|
|
|
80
84
|
def test_open_channel_should_set_options_key_on_channel
|
|
81
|
-
|
|
82
|
-
channel =
|
|
83
|
-
|
|
84
|
-
session.expects(:open_channel).yields(channel)
|
|
85
|
-
channel.expects(:[]=).with(:options, {:data => "here we go"})
|
|
86
|
-
|
|
85
|
+
channel = nil
|
|
86
|
+
session = setup_for_extracting_channel_action { |ch| channel = ch }
|
|
87
87
|
Capistrano::Command.new("ls", [session], :data => "here we go")
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def test_open_channel_should_request_pty
|
|
91
|
-
session = mock(:xserver => server("capistrano"))
|
|
92
|
-
channel = stub_everything
|
|
93
|
-
|
|
94
|
-
session.expects(:open_channel).yields(channel)
|
|
95
|
-
channel.expects(:request_pty).with(:want_reply => true)
|
|
96
|
-
|
|
97
|
-
Capistrano::Command.new("ls", [session])
|
|
88
|
+
assert_equal({ :data => 'here we go' }, channel[:options])
|
|
98
89
|
end
|
|
99
90
|
|
|
100
91
|
def test_successful_channel_should_send_command
|
|
101
|
-
session = setup_for_extracting_channel_action
|
|
102
|
-
ch.expects(:exec).with(%(sh -c
|
|
92
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
93
|
+
ch.expects(:exec).with(%(sh -c 'ls'))
|
|
103
94
|
end
|
|
104
95
|
Capistrano::Command.new("ls", [session])
|
|
105
96
|
end
|
|
106
97
|
|
|
107
98
|
def test_successful_channel_with_shell_option_should_send_command_via_specified_shell
|
|
108
|
-
session = setup_for_extracting_channel_action
|
|
109
|
-
ch.expects(:exec).with(%(/bin/bash -c
|
|
99
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
100
|
+
ch.expects(:exec).with(%(/bin/bash -c 'ls'))
|
|
110
101
|
end
|
|
111
102
|
Capistrano::Command.new("ls", [session], :shell => "/bin/bash")
|
|
112
103
|
end
|
|
113
104
|
|
|
105
|
+
def test_successful_channel_with_shell_false_should_send_command_without_shell
|
|
106
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
107
|
+
ch.expects(:exec).with(%(echo `hostname`))
|
|
108
|
+
end
|
|
109
|
+
Capistrano::Command.new("echo `hostname`", [session], :shell => false)
|
|
110
|
+
end
|
|
111
|
+
|
|
114
112
|
def test_successful_channel_should_send_data_if_data_key_is_present
|
|
115
|
-
session = setup_for_extracting_channel_action
|
|
116
|
-
ch.expects(:exec).with(%(sh -c
|
|
113
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
114
|
+
ch.expects(:exec).with(%(sh -c 'ls'))
|
|
117
115
|
ch.expects(:send_data).with("here we go")
|
|
118
116
|
end
|
|
119
117
|
Capistrano::Command.new("ls", [session], :data => "here we go")
|
|
120
118
|
end
|
|
121
119
|
|
|
122
|
-
def
|
|
123
|
-
session = setup_for_extracting_channel_action(:
|
|
120
|
+
def test_unsuccessful_pty_request_should_close_channel
|
|
121
|
+
session = setup_for_extracting_channel_action(:request_pty, false) do |ch|
|
|
124
122
|
ch.expects(:close)
|
|
125
123
|
end
|
|
126
|
-
Capistrano::Command.new("ls", [session])
|
|
124
|
+
Capistrano::Command.new("ls", [session], :pty => true)
|
|
127
125
|
end
|
|
128
126
|
|
|
129
127
|
def test_on_data_should_invoke_callback_as_stdout
|
|
@@ -150,48 +148,58 @@ class CommandTest < Test::Unit::TestCase
|
|
|
150
148
|
|
|
151
149
|
def test_on_request_should_record_exit_status
|
|
152
150
|
data = mock(:read_long => 5)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
end
|
|
151
|
+
channel = nil
|
|
152
|
+
session = setup_for_extracting_channel_action([:on_request, "exit-status"], data) { |ch| channel = ch }
|
|
156
153
|
Capistrano::Command.new("ls", [session])
|
|
154
|
+
assert_equal 5, channel[:status]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_on_request_should_log_exit_signal_if_logger_present
|
|
158
|
+
data = mock(:read_string => "TERM")
|
|
159
|
+
logger = stub_everything
|
|
160
|
+
|
|
161
|
+
session = setup_for_extracting_channel_action([:on_request, "exit-signal"], data)
|
|
162
|
+
logger.expects(:important).with("command received signal TERM", server("capistrano"))
|
|
163
|
+
|
|
164
|
+
Capistrano::Command.new("puppet", [session], :logger => logger)
|
|
157
165
|
end
|
|
158
166
|
|
|
159
167
|
def test_on_close_should_set_channel_closed
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
end
|
|
168
|
+
channel = nil
|
|
169
|
+
session = setup_for_extracting_channel_action(:on_close) { |ch| channel = ch }
|
|
163
170
|
Capistrano::Command.new("ls", [session])
|
|
171
|
+
assert channel[:closed]
|
|
164
172
|
end
|
|
165
173
|
|
|
166
174
|
def test_stop_should_close_all_open_channels
|
|
167
|
-
sessions = [
|
|
168
|
-
|
|
169
|
-
|
|
175
|
+
sessions = [mock_session(new_channel(false)),
|
|
176
|
+
mock_session(new_channel(true)),
|
|
177
|
+
mock_session(new_channel(false))]
|
|
170
178
|
|
|
171
179
|
cmd = Capistrano::Command.new("ls", sessions)
|
|
172
180
|
cmd.stop!
|
|
173
181
|
end
|
|
174
182
|
|
|
175
183
|
def test_process_should_return_cleanly_if_all_channels_have_zero_exit_status
|
|
176
|
-
sessions = [
|
|
177
|
-
|
|
178
|
-
|
|
184
|
+
sessions = [mock_session(new_channel(true, 0)),
|
|
185
|
+
mock_session(new_channel(true, 0)),
|
|
186
|
+
mock_session(new_channel(true, 0))]
|
|
179
187
|
cmd = Capistrano::Command.new("ls", sessions)
|
|
180
188
|
assert_nothing_raised { cmd.process! }
|
|
181
189
|
end
|
|
182
190
|
|
|
183
191
|
def test_process_should_raise_error_if_any_channel_has_non_zero_exit_status
|
|
184
|
-
sessions = [
|
|
185
|
-
|
|
186
|
-
|
|
192
|
+
sessions = [mock_session(new_channel(true, 0)),
|
|
193
|
+
mock_session(new_channel(true, 0)),
|
|
194
|
+
mock_session(new_channel(true, 1))]
|
|
187
195
|
cmd = Capistrano::Command.new("ls", sessions)
|
|
188
196
|
assert_raises(Capistrano::CommandError) { cmd.process! }
|
|
189
197
|
end
|
|
190
198
|
|
|
191
199
|
def test_command_error_should_include_accessor_with_host_array
|
|
192
|
-
sessions = [
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
sessions = [mock_session(new_channel(true, 0)),
|
|
201
|
+
mock_session(new_channel(true, 0)),
|
|
202
|
+
mock_session(new_channel(true, 1))]
|
|
195
203
|
cmd = Capistrano::Command.new("ls", sessions)
|
|
196
204
|
|
|
197
205
|
begin
|
|
@@ -207,95 +215,107 @@ class CommandTest < Test::Unit::TestCase
|
|
|
207
215
|
new_channel = Proc.new do |times|
|
|
208
216
|
ch = mock("channel")
|
|
209
217
|
returns = [false] * (times-1)
|
|
218
|
+
ch.stubs(:to_ary)
|
|
210
219
|
ch.stubs(:[]).with(:closed).returns(*(returns + [true]))
|
|
211
|
-
con = mock("connection")
|
|
212
|
-
con.expects(:process).with(true).times(times-1)
|
|
213
|
-
ch.expects(:connection).times(times-1).returns(con)
|
|
214
220
|
ch.expects(:[]).with(:status).returns(0)
|
|
215
221
|
ch
|
|
216
222
|
end
|
|
217
223
|
|
|
218
|
-
sessions = [
|
|
219
|
-
|
|
220
|
-
|
|
224
|
+
sessions = [mock_session(new_channel[5]),
|
|
225
|
+
mock_session(new_channel[10]),
|
|
226
|
+
mock_session(new_channel[7])]
|
|
221
227
|
cmd = Capistrano::Command.new("ls", sessions)
|
|
222
|
-
assert_nothing_raised
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
def test_process_should_ping_all_connections_each_second
|
|
226
|
-
now = Time.now
|
|
227
|
-
|
|
228
|
-
new_channel = Proc.new do
|
|
229
|
-
ch = mock("channel")
|
|
230
|
-
ch.stubs(:now => now)
|
|
231
|
-
def ch.[](key)
|
|
232
|
-
case key
|
|
233
|
-
when :status then 0
|
|
234
|
-
when :closed then Time.now - now < 1.1 ? false : true
|
|
235
|
-
else raise "unknown key: #{key}"
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
con = mock("connection")
|
|
239
|
-
con.stubs(:process)
|
|
240
|
-
con.expects(:ping!)
|
|
241
|
-
ch.stubs(:connection).returns(con)
|
|
242
|
-
ch
|
|
228
|
+
assert_nothing_raised do
|
|
229
|
+
cmd.process!
|
|
243
230
|
end
|
|
244
|
-
|
|
245
|
-
sessions = [mock("session", :open_channel => new_channel[]),
|
|
246
|
-
mock("session", :open_channel => new_channel[]),
|
|
247
|
-
mock("session", :open_channel => new_channel[])]
|
|
248
|
-
cmd = Capistrano::Command.new("ls", sessions)
|
|
249
|
-
assert_nothing_raised { cmd.process! }
|
|
250
231
|
end
|
|
251
232
|
|
|
252
233
|
def test_process_should_instantiate_command_and_process!
|
|
253
234
|
cmd = mock("command", :process! => nil)
|
|
254
|
-
Capistrano::Command.expects(:new).with("ls -l", %w(a b c), {:foo => "bar"}).
|
|
255
|
-
|
|
256
|
-
Capistrano::Command.process("ls -l", %w(a b c), :foo => "bar") { |cmd| parameter = cmd }
|
|
257
|
-
assert_equal :command, parameter
|
|
235
|
+
Capistrano::Command.expects(:new).with("ls -l", %w(a b c), {:foo => "bar"}).returns(cmd)
|
|
236
|
+
Capistrano::Command.process("ls -l", %w(a b c), :foo => "bar")
|
|
258
237
|
end
|
|
259
238
|
|
|
260
|
-
def
|
|
261
|
-
session = setup_for_extracting_channel_action
|
|
262
|
-
ch.expects(:exec).with(%(sh -c
|
|
239
|
+
def test_process_with_host_placeholder_should_substitute_host_placeholder_with_each_host
|
|
240
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
241
|
+
ch.expects(:exec).with(%(sh -c 'echo capistrano'))
|
|
263
242
|
end
|
|
264
243
|
Capistrano::Command.new("echo $CAPISTRANO:HOST$", [session])
|
|
265
244
|
end
|
|
266
245
|
|
|
246
|
+
class MockConfig
|
|
247
|
+
include Capistrano::Configuration::Roles
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def test_hostroles_substitution
|
|
251
|
+
@config = MockConfig.new
|
|
252
|
+
@config.server "capistrano", :db, :worker
|
|
253
|
+
server = @config.roles[:db].servers.first
|
|
254
|
+
channel = {:server => server, :host => 'capistrano'}
|
|
255
|
+
tree = Capistrano::Command::Tree.new(@config) { |t| t.else("echo $CAPISTRANO:HOSTROLES$") }
|
|
256
|
+
result = Capistrano::Command.new(tree, []).send(:replace_placeholders, "echo $CAPISTRANO:HOSTROLES$", channel)
|
|
257
|
+
assert result == "echo db,worker" || result == "echo worker,db"
|
|
258
|
+
end
|
|
259
|
+
|
|
267
260
|
def test_process_with_unknown_placeholder_should_not_replace_placeholder
|
|
268
|
-
session = setup_for_extracting_channel_action
|
|
269
|
-
ch.expects(:exec).with(%(sh -c
|
|
261
|
+
session = setup_for_extracting_channel_action do |ch|
|
|
262
|
+
ch.expects(:exec).with(%(sh -c 'echo $CAPISTRANO:OTHER$'))
|
|
270
263
|
end
|
|
271
264
|
Capistrano::Command.new("echo $CAPISTRANO:OTHER$", [session])
|
|
272
265
|
end
|
|
273
266
|
|
|
267
|
+
def test_input_stream_closed_when_eof_option_is_true
|
|
268
|
+
channel = nil
|
|
269
|
+
session = setup_for_extracting_channel_action { |ch| channel = ch }
|
|
270
|
+
channel.expects(:eof!)
|
|
271
|
+
Capistrano::Command.new("cat", [session], :data => "here we go", :eof => true)
|
|
272
|
+
assert_equal({ :data => 'here we go', :eof => true }, channel[:options])
|
|
273
|
+
end
|
|
274
|
+
|
|
274
275
|
private
|
|
275
276
|
|
|
277
|
+
def mock_session(channel=nil)
|
|
278
|
+
stub('session',
|
|
279
|
+
:open_channel => channel,
|
|
280
|
+
:preprocess => true,
|
|
281
|
+
:postprocess => true,
|
|
282
|
+
:listeners => {},
|
|
283
|
+
:xserver => server("capistrano"))
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
class MockChannel < Hash
|
|
287
|
+
def close
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
276
291
|
def new_channel(closed, status=nil)
|
|
277
|
-
ch =
|
|
278
|
-
ch.
|
|
279
|
-
ch
|
|
292
|
+
ch = MockChannel.new
|
|
293
|
+
ch.update({ :closed => closed, :host => "capistrano", :server => server("capistrano") })
|
|
294
|
+
ch[:status] = status if status
|
|
280
295
|
ch.expects(:close) unless closed
|
|
281
|
-
ch.stubs(:[]).with(:host).returns("capistrano")
|
|
282
|
-
ch.stubs(:[]).with(:server).returns(server("capistrano"))
|
|
283
296
|
ch
|
|
284
297
|
end
|
|
285
298
|
|
|
286
|
-
def setup_for_extracting_channel_action(action, *args)
|
|
299
|
+
def setup_for_extracting_channel_action(action=nil, *args)
|
|
287
300
|
s = server("capistrano")
|
|
288
301
|
session = mock("session", :xserver => s)
|
|
289
302
|
|
|
290
|
-
channel =
|
|
303
|
+
channel = {}
|
|
291
304
|
session.expects(:open_channel).yields(channel)
|
|
292
305
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
channel.
|
|
306
|
+
channel.stubs(:on_data)
|
|
307
|
+
channel.stubs(:on_extended_data)
|
|
308
|
+
channel.stubs(:on_request)
|
|
309
|
+
channel.stubs(:on_close)
|
|
310
|
+
channel.stubs(:exec)
|
|
311
|
+
channel.stubs(:send_data)
|
|
312
|
+
|
|
313
|
+
if action
|
|
314
|
+
action = Array(action)
|
|
315
|
+
channel.expects(action.first).with(*action[1..-1]).yields(channel, *args)
|
|
316
|
+
end
|
|
297
317
|
|
|
298
|
-
yield
|
|
318
|
+
yield channel if block_given?
|
|
299
319
|
|
|
300
320
|
session
|
|
301
321
|
end
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "utils"
|
|
2
2
|
require 'capistrano/configuration/actions/file_transfer'
|
|
3
3
|
|
|
4
4
|
class ConfigurationActionsFileTransferTest < Test::Unit::TestCase
|
|
5
5
|
class MockConfig
|
|
6
6
|
include Capistrano::Configuration::Actions::FileTransfer
|
|
7
|
+
attr_accessor :sessions, :dry_run
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def setup
|
|
@@ -11,30 +12,50 @@ class ConfigurationActionsFileTransferTest < Test::Unit::TestCase
|
|
|
11
12
|
@config.stubs(:logger).returns(stub_everything)
|
|
12
13
|
end
|
|
13
14
|
|
|
14
|
-
def
|
|
15
|
-
@config.expects(:
|
|
16
|
-
|
|
15
|
+
def test_put_should_delegate_to_upload
|
|
16
|
+
@config.expects(:upload).with { |from, to, opts|
|
|
17
|
+
from.string == "some data" && to == "test.txt" && opts == { :mode => 0777 } }
|
|
18
|
+
@config.expects(:run).never
|
|
19
|
+
@config.put("some data", "test.txt", :mode => 0777)
|
|
17
20
|
end
|
|
18
21
|
|
|
19
|
-
def
|
|
20
|
-
@config.expects(:
|
|
21
|
-
@config.
|
|
22
|
-
Capistrano::Upload.expects(:process).with([:s1,:s2,:s3], "test.txt", :data => "some data", :mode => 0777, :logger => @config.logger)
|
|
23
|
-
@config.put("some data", "test.txt", :mode => 0777)
|
|
22
|
+
def test_get_should_delegate_to_download_with_once
|
|
23
|
+
@config.expects(:download).with("testr.txt", "testl.txt", :foo => "bar", :once => true)
|
|
24
|
+
@config.get("testr.txt", "testl.txt", :foo => "bar")
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
def
|
|
27
|
-
@config.expects(:
|
|
28
|
-
@config.
|
|
27
|
+
def test_upload_should_delegate_to_transfer
|
|
28
|
+
@config.expects(:transfer).with(:up, "testl.txt", "testr.txt", :foo => "bar")
|
|
29
|
+
@config.upload("testl.txt", "testr.txt", :foo => "bar")
|
|
29
30
|
end
|
|
30
31
|
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
def test_upload_without_mode_should_not_try_to_chmod
|
|
33
|
+
@config.expects(:transfer).with(:up, "testl.txt", "testr.txt", :foo => "bar")
|
|
34
|
+
@config.expects(:run).never
|
|
35
|
+
@config.upload("testl.txt", "testr.txt", :foo => "bar")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_upload_with_mode_should_try_to_chmod
|
|
39
|
+
@config.expects(:transfer).with(:up, "testl.txt", "testr.txt", :foo => "bar")
|
|
40
|
+
@config.expects(:run).with("chmod 775 testr.txt", {:foo => "bar"})
|
|
41
|
+
@config.upload("testl.txt", "testr.txt", :mode => 0775, :foo => "bar")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_upload_with_symbolic_mode_should_try_to_chmod
|
|
45
|
+
@config.expects(:transfer).with(:up, "testl.txt", "testr.txt", :foo => "bar")
|
|
46
|
+
@config.expects(:run).with("chmod g+w testr.txt", {:foo => "bar"})
|
|
47
|
+
@config.upload("testl.txt", "testr.txt", :mode => "g+w", :foo => "bar")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_download_should_delegate_to_transfer
|
|
51
|
+
@config.expects(:transfer).with(:down, "testr.txt", "testl.txt", :foo => "bar")
|
|
52
|
+
@config.download("testr.txt", "testl.txt", :foo => "bar")
|
|
53
|
+
end
|
|
34
54
|
|
|
35
|
-
|
|
36
|
-
@config.
|
|
37
|
-
@config.expects(:
|
|
38
|
-
|
|
55
|
+
def test_transfer_should_invoke_transfer_on_matching_servers
|
|
56
|
+
@config.sessions = { :a => 1, :b => 2, :c => 3, :d => 4 }
|
|
57
|
+
@config.expects(:execute_on_servers).with(:foo => "bar").yields([:a, :b, :c])
|
|
58
|
+
Capistrano::Transfer.expects(:process).with(:up, "testl.txt", "testr.txt", [1,2,3], {:foo => "bar", :logger => @config.logger})
|
|
59
|
+
@config.transfer(:up, "testl.txt", "testr.txt", :foo => "bar")
|
|
39
60
|
end
|
|
40
|
-
end
|
|
61
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require "
|
|
1
|
+
require "utils"
|
|
2
2
|
require 'capistrano/configuration/actions/inspect'
|
|
3
3
|
|
|
4
4
|
class ConfigurationActionsInspectTest < Test::Unit::TestCase
|
|
@@ -9,13 +9,19 @@ class ConfigurationActionsInspectTest < Test::Unit::TestCase
|
|
|
9
9
|
def setup
|
|
10
10
|
@config = MockConfig.new
|
|
11
11
|
@config.stubs(:logger).returns(stub_everything)
|
|
12
|
+
@config.stubs(:sudo).returns('sudo')
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
def test_stream_should_pass_options_through_to_run
|
|
15
|
-
@config.expects(:invoke_command).with("tail -f foo.log", :once => true)
|
|
16
|
+
@config.expects(:invoke_command).with("tail -f foo.log", :once => true, :eof => true)
|
|
16
17
|
@config.stream("tail -f foo.log", :once => true)
|
|
17
18
|
end
|
|
18
19
|
|
|
20
|
+
def test_stream_with_sudo_should_avoid_closing_stdin
|
|
21
|
+
@config.expects(:invoke_command).with("sudo tail -f foo.log", :once => true, :eof => false)
|
|
22
|
+
@config.stream("sudo tail -f foo.log", :once => true)
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def test_stream_should_emit_stdout_via_puts
|
|
20
26
|
@config.expects(:invoke_command).yields(mock("channel"), :out, "something streamed")
|
|
21
27
|
@config.expects(:puts).with("something streamed")
|
|
@@ -33,13 +39,21 @@ class ConfigurationActionsInspectTest < Test::Unit::TestCase
|
|
|
33
39
|
end
|
|
34
40
|
|
|
35
41
|
def test_capture_should_pass_options_merged_with_once_to_run
|
|
36
|
-
@config.expects(:invoke_command).with("hostname", :foo => "bar", :once => true)
|
|
42
|
+
@config.expects(:invoke_command).with("hostname", :foo => "bar", :once => true, :eof => true)
|
|
37
43
|
@config.capture("hostname", :foo => "bar")
|
|
38
44
|
end
|
|
39
45
|
|
|
40
|
-
def
|
|
41
|
-
@config.expects(:invoke_command).
|
|
42
|
-
|
|
46
|
+
def test_capture_with_sudo_should_avoid_closing_stdin
|
|
47
|
+
@config.expects(:invoke_command).with("sudo hostname", :foo => "bar", :once => true, :eof => false)
|
|
48
|
+
@config.capture("sudo hostname", :foo => "bar")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_capture_with_stderr_should_emit_stderr_via_warn
|
|
52
|
+
ch = mock("channel")
|
|
53
|
+
ch.expects(:[]).with(:server).returns(server("capistrano"))
|
|
54
|
+
@config.expects(:invoke_command).yields(ch, :err, "boom")
|
|
55
|
+
@config.expects(:warn).with("[err :: capistrano] boom")
|
|
56
|
+
@config.capture("hostname")
|
|
43
57
|
end
|
|
44
58
|
|
|
45
59
|
def test_capture_with_stdout_should_aggregate_and_return_stdout
|
|
@@ -59,4 +73,4 @@ class ConfigurationActionsInspectTest < Test::Unit::TestCase
|
|
|
59
73
|
@config.channel = channel
|
|
60
74
|
@config.script = output
|
|
61
75
|
end
|
|
62
|
-
end
|
|
76
|
+
end
|