capistrano 1.4.2 → 2.0.0
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 +140 -4
- data/MIT-LICENSE +1 -1
- data/README +22 -14
- data/bin/cap +1 -8
- data/bin/capify +77 -0
- data/examples/sample.rb +10 -109
- data/lib/capistrano.rb +1 -0
- data/lib/capistrano/callback.rb +41 -0
- data/lib/capistrano/cli.rb +17 -317
- data/lib/capistrano/cli/execute.rb +82 -0
- data/lib/capistrano/cli/help.rb +102 -0
- data/lib/capistrano/cli/help.txt +53 -0
- data/lib/capistrano/cli/options.rb +183 -0
- data/lib/capistrano/cli/ui.rb +28 -0
- data/lib/capistrano/command.rb +62 -29
- data/lib/capistrano/configuration.rb +25 -226
- data/lib/capistrano/configuration/actions/file_transfer.rb +35 -0
- data/lib/capistrano/configuration/actions/inspect.rb +46 -0
- data/lib/capistrano/configuration/actions/invocation.rb +127 -0
- data/lib/capistrano/configuration/callbacks.rb +148 -0
- data/lib/capistrano/configuration/connections.rb +159 -0
- data/lib/capistrano/configuration/execution.rb +126 -0
- data/lib/capistrano/configuration/loading.rb +112 -0
- data/lib/capistrano/configuration/namespaces.rb +190 -0
- data/lib/capistrano/configuration/roles.rb +51 -0
- data/lib/capistrano/configuration/servers.rb +75 -0
- data/lib/capistrano/configuration/variables.rb +127 -0
- data/lib/capistrano/errors.rb +15 -0
- data/lib/capistrano/extensions.rb +27 -8
- data/lib/capistrano/gateway.rb +54 -29
- data/lib/capistrano/logger.rb +11 -11
- data/lib/capistrano/recipes/compat.rb +32 -0
- data/lib/capistrano/recipes/deploy.rb +483 -0
- data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
- data/lib/capistrano/recipes/deploy/local_dependency.rb +46 -0
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +65 -0
- data/lib/capistrano/recipes/deploy/scm.rb +19 -0
- data/lib/capistrano/recipes/deploy/scm/base.rb +180 -0
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +86 -0
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +151 -0
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +85 -0
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +129 -0
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +126 -0
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +103 -0
- data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
- data/lib/capistrano/recipes/deploy/strategy/base.rb +64 -0
- data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +143 -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 +47 -0
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +53 -0
- data/lib/capistrano/recipes/standard.rb +26 -276
- data/lib/capistrano/recipes/templates/maintenance.rhtml +1 -1
- data/lib/capistrano/recipes/upgrade.rb +33 -0
- data/lib/capistrano/server_definition.rb +51 -0
- data/lib/capistrano/shell.rb +125 -81
- data/lib/capistrano/ssh.rb +80 -36
- data/lib/capistrano/task_definition.rb +69 -0
- data/lib/capistrano/upload.rb +146 -0
- data/lib/capistrano/version.rb +13 -17
- data/test/cli/execute_test.rb +132 -0
- data/test/cli/help_test.rb +139 -0
- data/test/cli/options_test.rb +226 -0
- data/test/cli/ui_test.rb +28 -0
- data/test/cli_test.rb +17 -0
- data/test/command_test.rb +284 -25
- data/test/configuration/actions/file_transfer_test.rb +40 -0
- data/test/configuration/actions/inspect_test.rb +62 -0
- data/test/configuration/actions/invocation_test.rb +195 -0
- data/test/configuration/callbacks_test.rb +206 -0
- data/test/configuration/connections_test.rb +288 -0
- data/test/configuration/execution_test.rb +159 -0
- data/test/configuration/loading_test.rb +119 -0
- data/test/configuration/namespace_dsl_test.rb +283 -0
- data/test/configuration/roles_test.rb +47 -0
- data/test/configuration/servers_test.rb +90 -0
- data/test/configuration/variables_test.rb +180 -0
- data/test/configuration_test.rb +60 -212
- data/test/deploy/scm/base_test.rb +55 -0
- data/test/deploy/strategy/copy_test.rb +146 -0
- data/test/extensions_test.rb +69 -0
- data/test/fixtures/cli_integration.rb +5 -0
- data/test/fixtures/custom.rb +2 -2
- data/test/gateway_test.rb +167 -0
- data/test/logger_test.rb +123 -0
- data/test/server_definition_test.rb +108 -0
- data/test/shell_test.rb +64 -0
- data/test/ssh_test.rb +67 -154
- data/test/task_definition_test.rb +101 -0
- data/test/upload_test.rb +131 -0
- data/test/utils.rb +31 -39
- data/test/version_test.rb +24 -0
- metadata +145 -98
- data/THANKS +0 -4
- data/lib/capistrano/actor.rb +0 -567
- data/lib/capistrano/generators/rails/deployment/deployment_generator.rb +0 -25
- data/lib/capistrano/generators/rails/deployment/templates/capistrano.rake +0 -49
- data/lib/capistrano/generators/rails/deployment/templates/deploy.rb +0 -122
- data/lib/capistrano/generators/rails/loader.rb +0 -20
- data/lib/capistrano/scm/base.rb +0 -61
- data/lib/capistrano/scm/baz.rb +0 -118
- data/lib/capistrano/scm/bzr.rb +0 -70
- data/lib/capistrano/scm/cvs.rb +0 -129
- data/lib/capistrano/scm/darcs.rb +0 -27
- data/lib/capistrano/scm/mercurial.rb +0 -83
- data/lib/capistrano/scm/perforce.rb +0 -139
- data/lib/capistrano/scm/subversion.rb +0 -128
- data/lib/capistrano/transfer.rb +0 -97
- data/lib/capistrano/utils.rb +0 -26
- data/test/actor_test.rb +0 -402
- data/test/scm/cvs_test.rb +0 -196
- data/test/scm/subversion_test.rb +0 -145
data/test/shell_test.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/utils"
|
2
|
+
require 'capistrano/configuration'
|
3
|
+
require 'capistrano/shell'
|
4
|
+
|
5
|
+
class ShellTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@config = Capistrano::Configuration.new
|
8
|
+
@shell = Capistrano::Shell.new(@config)
|
9
|
+
@shell.stubs(:puts)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_readline_fallback_prompt_should_write_to_stdout_and_read_from_stdin
|
13
|
+
STDOUT.expects(:print).with("prompt> ")
|
14
|
+
STDOUT.expects(:flush)
|
15
|
+
STDIN.expects(:gets).returns("hi\n")
|
16
|
+
assert_equal "hi\n", Capistrano::Shell::ReadlineFallback.readline("prompt> ")
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_question_mark_as_input_should_trigger_help
|
20
|
+
@shell.expects(:read_line).returns("?")
|
21
|
+
@shell.expects(:help)
|
22
|
+
assert @shell.read_and_execute
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_help_as_input_should_trigger_help
|
26
|
+
@shell.expects(:read_line).returns("help")
|
27
|
+
@shell.expects(:help)
|
28
|
+
assert @shell.read_and_execute
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_quit_as_input_should_cause_read_and_execute_to_return_false
|
32
|
+
@shell.expects(:read_line).returns("quit")
|
33
|
+
assert !@shell.read_and_execute
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_exit_as_input_should_cause_read_and_execute_to_return_false
|
37
|
+
@shell.expects(:read_line).returns("exit")
|
38
|
+
assert !@shell.read_and_execute
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_set_should_parse_flag_and_value_and_call_set_option
|
42
|
+
@shell.expects(:read_line).returns("set -v 5")
|
43
|
+
@shell.expects(:set_option).with("v", "5")
|
44
|
+
assert @shell.read_and_execute
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_text_without_with_or_on_gets_processed_verbatim
|
48
|
+
@shell.expects(:read_line).returns("hello world")
|
49
|
+
@shell.expects(:process_command).with(nil, nil, "hello world")
|
50
|
+
assert @shell.read_and_execute
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_text_with_with_gets_processed_with_with # lol
|
54
|
+
@shell.expects(:read_line).returns("with app,db hello world")
|
55
|
+
@shell.expects(:process_command).with("with", "app,db", "hello world")
|
56
|
+
assert @shell.read_and_execute
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_text_with_on_gets_processed_with_on
|
60
|
+
@shell.expects(:read_line).returns("on app,db hello world")
|
61
|
+
@shell.expects(:process_command).with("on", "app,db", "hello world")
|
62
|
+
assert @shell.read_and_execute
|
63
|
+
end
|
64
|
+
end
|
data/test/ssh_test.rb
CHANGED
@@ -1,184 +1,97 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require File.dirname(__FILE__) + "/utils"
|
4
|
-
require 'test/unit'
|
1
|
+
require "#{File.dirname(__FILE__)}/utils"
|
5
2
|
require 'capistrano/ssh'
|
6
3
|
|
7
4
|
class SSHTest < Test::Unit::TestCase
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
def setup
|
6
|
+
@options = { :username => nil,
|
7
|
+
:password => nil,
|
8
|
+
:port => 22,
|
9
|
+
:auth_methods => %w(publickey hostbased) }
|
10
|
+
@server = server("capistrano")
|
11
|
+
end
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
raise err if err
|
20
|
-
end
|
13
|
+
def test_connect_with_bare_server_without_options_or_config_with_public_key_succeeding_should_only_loop_once
|
14
|
+
Net::SSH.expects(:start).with(@server.host, @options).returns(success = Object.new)
|
15
|
+
assert_equal success, Capistrano::SSH.connect(@server)
|
21
16
|
end
|
22
17
|
|
23
|
-
def
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
27
|
-
MockSSH.story = []
|
28
|
-
MockSSH.invocations = []
|
18
|
+
def test_connect_with_bare_server_without_options_with_public_key_failing_should_try_password
|
19
|
+
Net::SSH.expects(:start).with(@server.host, @options).raises(Net::SSH::AuthenticationFailed)
|
20
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
|
21
|
+
assert_equal success, Capistrano::SSH.connect(@server, :password => "f4b13n")
|
29
22
|
end
|
30
23
|
|
31
|
-
def
|
32
|
-
Net.
|
33
|
-
|
24
|
+
def test_connect_with_bare_server_without_options_public_key_and_password_failing_should_raise_error
|
25
|
+
Net::SSH.expects(:start).with(@server.host, @options).raises(Net::SSH::AuthenticationFailed)
|
26
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).raises(Net::SSH::AuthenticationFailed)
|
27
|
+
assert_raises(Net::SSH::AuthenticationFailed) do
|
28
|
+
Capistrano::SSH.connect(@server, :password => "f4b13n")
|
34
29
|
end
|
35
|
-
|
36
|
-
assert_equal 1, MockSSH.invocations.length
|
37
|
-
assert_equal 'demo.server.i', MockSSH.invocations.first[0]
|
38
|
-
assert_equal 22, MockSSH.invocations.first[1][:port]
|
39
|
-
assert_equal 'demo', MockSSH.invocations.first[1][:username]
|
40
|
-
assert_nil MockSSH.invocations.first[1][:password]
|
41
|
-
assert_equal %w(publickey hostbased),
|
42
|
-
MockSSH.invocations.first[1][:auth_methods]
|
43
|
-
assert_nil MockSSH.invocations.first[2]
|
44
30
|
end
|
45
|
-
|
46
|
-
def test_explicit_ssh_ports_in_server_string_no_block
|
47
|
-
Net.const_during(:SSH, MockSSH) do
|
48
|
-
Capistrano::SSH.connect('demo.server.i:8088', @config)
|
49
|
-
end
|
50
31
|
|
51
|
-
|
52
|
-
|
53
|
-
assert_equal
|
54
|
-
assert_equal 'demo', MockSSH.invocations.first[1][:username]
|
32
|
+
def test_connect_with_bare_server_and_user_via_public_key_should_pass_user_to_net_ssh
|
33
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis")).returns(success = Object.new)
|
34
|
+
assert_equal success, Capistrano::SSH.connect(@server, :user => "jamis")
|
55
35
|
end
|
56
|
-
|
57
|
-
def test_explicit_ssh_username_in_server_string_no_block
|
58
|
-
Net.const_during(:SSH, MockSSH) do
|
59
|
-
Capistrano::SSH.connect('bob@demo.server.i', @config)
|
60
|
-
end
|
61
36
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
assert_equal
|
37
|
+
def test_connect_with_bare_server_and_user_via_password_should_pass_user_to_net_ssh
|
38
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis")).raises(Net::SSH::AuthenticationFailed)
|
39
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis", :password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
|
40
|
+
assert_equal success, Capistrano::SSH.connect(@server, :user => "jamis", :password => "f4b13n")
|
66
41
|
end
|
67
|
-
|
68
|
-
def test_explicit_ssh_username_and_port_in_server_string_no_block
|
69
|
-
Net.const_during(:SSH, MockSSH) do
|
70
|
-
Capistrano::SSH.connect('bob@demo.server.i:8088', @config)
|
71
|
-
end
|
72
42
|
|
73
|
-
|
74
|
-
|
75
|
-
assert_equal
|
76
|
-
assert_equal 'bob', MockSSH.invocations.first[1][:username]
|
43
|
+
def test_connect_with_bare_server_with_explicit_port_should_pass_port_to_net_ssh
|
44
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:port => 1234)).returns(success = Object.new)
|
45
|
+
assert_equal success, Capistrano::SSH.connect(@server, :port => 1234)
|
77
46
|
end
|
78
47
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
assert_equal 1, MockSSH.invocations.length
|
85
|
-
assert_equal 23, MockSSH.invocations.first[1][:port]
|
86
|
-
assert_nil MockSSH.invocations.first[2]
|
48
|
+
def test_connect_with_server_with_user_should_pass_user_to_net_ssh
|
49
|
+
server = server("jamis@capistrano")
|
50
|
+
Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis")).returns(success = Object.new)
|
51
|
+
assert_equal success, Capistrano::SSH.connect(server)
|
87
52
|
end
|
88
53
|
|
89
|
-
|
90
|
-
|
91
|
-
Net.
|
92
|
-
|
93
|
-
end
|
94
|
-
end
|
95
|
-
assert_equal 'demo.server.i', MockSSH.invocations.first[0]
|
96
|
-
assert_equal '8088', MockSSH.invocations.first[1][:port]
|
97
|
-
assert_equal 1, MockSSH.invocations.length
|
98
|
-
assert_instance_of Proc, MockSSH.invocations.first[2]
|
99
|
-
end
|
100
|
-
|
101
|
-
def test_explicit_ssh_username_in_server_string_with_block
|
102
|
-
Net.const_during(:SSH, MockSSH) do
|
103
|
-
Capistrano::SSH.connect('bob@demo.server.i', @config) do |session|
|
104
|
-
end
|
105
|
-
end
|
106
|
-
assert_equal 'demo.server.i', MockSSH.invocations.first[0]
|
107
|
-
assert_equal 22, MockSSH.invocations.first[1][:port]
|
108
|
-
assert_equal 1, MockSSH.invocations.length
|
109
|
-
assert_equal 'bob', MockSSH.invocations.first[1][:username]
|
110
|
-
assert_instance_of Proc, MockSSH.invocations.first[2]
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_explicit_ssh_username_and_port_in_server_string_with_block
|
114
|
-
Net.const_during(:SSH, MockSSH) do
|
115
|
-
Capistrano::SSH.connect('bob@demo.server.i:8088', @config) do |session|
|
116
|
-
end
|
117
|
-
end
|
118
|
-
assert_equal 'demo.server.i', MockSSH.invocations.first[0]
|
119
|
-
assert_equal '8088', MockSSH.invocations.first[1][:port]
|
120
|
-
assert_equal 1, MockSSH.invocations.length
|
121
|
-
assert_equal 'bob', MockSSH.invocations.first[1][:username]
|
122
|
-
assert_instance_of Proc, MockSSH.invocations.first[2]
|
54
|
+
def test_connect_with_server_with_port_should_pass_port_to_net_ssh
|
55
|
+
server = server("capistrano:1235")
|
56
|
+
Net::SSH.expects(:start).with(server.host, @options.merge(:port => 1235)).returns(success = Object.new)
|
57
|
+
assert_equal success, Capistrano::SSH.connect(server)
|
123
58
|
end
|
124
59
|
|
125
|
-
def
|
126
|
-
|
127
|
-
|
128
|
-
assert_equal
|
129
|
-
Capistrano::SSH.parse_server("demo.server.i:8088"))
|
130
|
-
assert_equal(['bob', 'demo.server.i', nil],
|
131
|
-
Capistrano::SSH.parse_server("bob@demo.server.i"))
|
132
|
-
assert_equal([nil, 'demo.server.i', nil],
|
133
|
-
Capistrano::SSH.parse_server("demo.server.i"))
|
134
|
-
end
|
135
|
-
|
136
|
-
def test_publickey_auth_succeeds_with_block
|
137
|
-
Net.const_during(:SSH, MockSSH) do
|
138
|
-
Capistrano::SSH.connect('demo.server.i', @config) do |session|
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
assert_equal 1, MockSSH.invocations.length
|
143
|
-
assert_instance_of Proc, MockSSH.invocations.first[2]
|
60
|
+
def test_connect_with_server_with_user_and_port_should_pass_user_and_port_to_net_ssh
|
61
|
+
server = server("jamis@capistrano:1235")
|
62
|
+
Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis", :port => 1235)).returns(success = Object.new)
|
63
|
+
assert_equal success, Capistrano::SSH.connect(server)
|
144
64
|
end
|
145
65
|
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
Capistrano::SSH.connect('demo.server.i', @config)
|
151
|
-
end
|
152
|
-
|
153
|
-
assert_equal 2, MockSSH.invocations.length
|
154
|
-
|
155
|
-
assert_nil MockSSH.invocations.first[1][:password]
|
156
|
-
assert_equal %w(publickey hostbased),
|
157
|
-
MockSSH.invocations.first[1][:auth_methods]
|
158
|
-
|
159
|
-
assert_equal 'c0c0nutfr0st1ng', MockSSH.invocations.last[1][:password]
|
160
|
-
assert_equal %w(password keyboard-interactive),
|
161
|
-
MockSSH.invocations.last[1][:auth_methods]
|
66
|
+
def test_connect_with_ssh_options_should_use_ssh_options
|
67
|
+
ssh_options = { :username => "JamisMan", :port => 8125 }
|
68
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "JamisMan", :port => 8125)).returns(success = Object.new)
|
69
|
+
assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options})
|
162
70
|
end
|
163
71
|
|
164
|
-
def
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
assert_raises(Net::SSH::AuthenticationFailed) do
|
170
|
-
Capistrano::SSH.connect('demo.server.i', @config)
|
171
|
-
end
|
172
|
-
end
|
72
|
+
def test_connect_with_options_and_ssh_options_should_see_options_override_ssh_options
|
73
|
+
ssh_options = { :username => "JamisMan", :port => 8125, :forward_agent => true }
|
74
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis", :port => 1235, :forward_agent => true)).returns(success = Object.new)
|
75
|
+
assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options, :user => "jamis", :port => 1235})
|
76
|
+
end
|
173
77
|
|
174
|
-
|
78
|
+
def test_connect_with_ssh_options_should_see_server_options_override_ssh_options
|
79
|
+
ssh_options = { :username => "JamisMan", :port => 8125, :forward_agent => true }
|
80
|
+
server = server("jamis@capistrano:1235")
|
81
|
+
Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis", :port => 1235, :forward_agent => true)).returns(success = Object.new)
|
82
|
+
assert_equal success, Capistrano::SSH.connect(server, {:ssh_options => ssh_options})
|
83
|
+
end
|
175
84
|
|
176
|
-
|
177
|
-
|
178
|
-
|
85
|
+
def test_connect_should_add_xserver_accessor_to_connection
|
86
|
+
Net::SSH.expects(:start).with(@server.host, @options).returns(success = Object.new)
|
87
|
+
assert_equal success, Capistrano::SSH.connect(@server)
|
88
|
+
assert success.respond_to?(:xserver)
|
89
|
+
assert success.respond_to?(:xserver)
|
90
|
+
assert_equal success.xserver, @server
|
91
|
+
end
|
179
92
|
|
180
|
-
|
181
|
-
|
182
|
-
|
93
|
+
def test_connect_should_not_retry_if_custom_auth_methods_are_given
|
94
|
+
Net::SSH.expects(:start).with(@server.host, @options.merge(:auth_methods => %w(publickey))).raises(Net::SSH::AuthenticationFailed)
|
95
|
+
assert_raises(Net::SSH::AuthenticationFailed) { Capistrano::SSH.connect(@server, :ssh_options => { :auth_methods => %w(publickey) }) }
|
183
96
|
end
|
184
97
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/utils"
|
2
|
+
require 'capistrano/task_definition'
|
3
|
+
|
4
|
+
class TaskDefinitionTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@namespace = namespace
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_fqn_at_top_level_should_be_task_name
|
10
|
+
task = new_task(:testing)
|
11
|
+
assert_equal "testing", task.fully_qualified_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_fqn_in_namespace_should_include_namespace_fqn
|
15
|
+
ns = namespace("outer:inner")
|
16
|
+
task = new_task(:testing, ns)
|
17
|
+
assert_equal "outer:inner:testing", task.fully_qualified_name
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_fqn_at_top_level_when_default_should_be_default
|
21
|
+
task = new_task(:default)
|
22
|
+
assert_equal "default", task.fully_qualified_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_fqn_in_namespace_when_default_should_be_namespace_fqn
|
26
|
+
ns = namespace("outer:inner")
|
27
|
+
task = new_task(:default, ns)
|
28
|
+
ns.stubs(:default_task => task)
|
29
|
+
assert_equal "outer:inner", task.fully_qualified_name
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_task_should_require_block
|
33
|
+
assert_raises(ArgumentError) do
|
34
|
+
Capistrano::TaskDefinition.new(:testing, @namespace)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_description_should_return_empty_string_if_not_given
|
39
|
+
assert_equal "", new_task(:testing).description
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_description_should_return_desc_attribute
|
43
|
+
assert_equal "something", new_task(:testing, @namespace, :desc => "something").description
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_description_should_strip_leading_and_trailing_whitespace
|
47
|
+
assert_equal "something", new_task(:testing, @namespace, :desc => " something ").description
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_description_should_normalize_newlines
|
51
|
+
assert_equal "a\nb\nc", new_task(:testing, @namespace, :desc => "a\nb\r\nc").description
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_description_should_detect_and_remove_indentation
|
55
|
+
desc = <<-DESC
|
56
|
+
Here is some indented text \
|
57
|
+
and I want all of this to \
|
58
|
+
run together on a single line, \
|
59
|
+
without any extraneous spaces.
|
60
|
+
|
61
|
+
additional indentation will
|
62
|
+
be preserved.
|
63
|
+
DESC
|
64
|
+
|
65
|
+
task = new_task(:testing, @namespace, :desc => desc)
|
66
|
+
assert_equal "Here is some indented text and I want all of this to run together on a single line, without any extraneous spaces.\n\n additional indentation will\n be preserved.", task.description
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_description_munging_should_be_sensitive_to_code_blocks
|
70
|
+
desc = <<-DESC
|
71
|
+
Here is a line \
|
72
|
+
wrapped with spacing in it.
|
73
|
+
|
74
|
+
foo bar
|
75
|
+
baz bang
|
76
|
+
DESC
|
77
|
+
|
78
|
+
task = new_task(:testing, @namespace, :desc => desc)
|
79
|
+
assert_equal "Here is a line wrapped with spacing in it.\n\n foo bar\n baz bang", task.description
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_brief_description_should_return_first_sentence_in_description
|
83
|
+
desc = "This is the task. It does all kinds of things."
|
84
|
+
task = new_task(:testing, @namespace, :desc => desc)
|
85
|
+
assert_equal "This is the task.", task.brief_description
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_brief_description_should_truncate_if_length_given
|
89
|
+
desc = "This is the task that does all kinds of things. And then some."
|
90
|
+
task = new_task(:testing, @namespace, :desc => desc)
|
91
|
+
assert_equal "This is the task ...", task.brief_description(20)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_brief_description_should_not_break_at_period_in_middle_of_sentence
|
95
|
+
task = new_task(:testing, @namespace, :desc => "Take file.txt and copy it.")
|
96
|
+
assert_equal "Take file.txt and copy it.", task.brief_description
|
97
|
+
|
98
|
+
task = new_task(:testing, @namespace, :desc => "Take file.txt and copy it. Then do something else.")
|
99
|
+
assert_equal "Take file.txt and copy it.", task.brief_description
|
100
|
+
end
|
101
|
+
end
|
data/test/upload_test.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/utils"
|
2
|
+
require 'capistrano/upload'
|
3
|
+
|
4
|
+
class UploadTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@mode = IO::WRONLY | IO::CREAT | IO::TRUNC
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_initialize_should_raise_error_if_data_is_missing
|
10
|
+
assert_raises(ArgumentError) do
|
11
|
+
Capistrano::Upload.new([], "test.txt", :foo => "bar")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_initialize_should_get_sftp_for_each_session
|
16
|
+
new_sftp = Proc.new do |state|
|
17
|
+
sftp = mock("sftp", :state => state, :open => nil)
|
18
|
+
sftp.expects(:connect) unless state == :open
|
19
|
+
sftp.stubs(:channel).returns({})
|
20
|
+
sftp
|
21
|
+
end
|
22
|
+
|
23
|
+
sessions = [mock("session", :xserver => server("a"), :sftp => new_sftp[:closed]),
|
24
|
+
mock("session", :xserver => server("b"), :sftp => new_sftp[:closed]),
|
25
|
+
mock("session", :xserver => server("c"), :sftp => new_sftp[:open])]
|
26
|
+
Capistrano::Upload.new(sessions, "test.txt", :data => "data")
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_self_process_should_instantiate_uploader_and_start_process
|
30
|
+
Capistrano::Upload.expects(:new).with([:s1, :s2], "test.txt", :data => "data").returns(mock(:process! => nil))
|
31
|
+
Capistrano::Upload.process([:s1, :s2], "test.txt", :data => "data")
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_process_when_sftp_open_fails_should_raise_error
|
35
|
+
sftp = mock_sftp
|
36
|
+
sftp.expects(:open).with("test.txt", @mode, 0660).yields(mock("status", :code => "bad status", :message => "bad status"), :file_handle)
|
37
|
+
session = mock("session", :sftp => sftp, :xserver => server("capistrano"))
|
38
|
+
upload = Capistrano::Upload.new([session], "test.txt", :data => "data", :logger => stub_everything)
|
39
|
+
assert_raises(Capistrano::UploadError) { upload.process! }
|
40
|
+
assert_equal 1, upload.failed
|
41
|
+
assert_equal 1, upload.completed
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_process_when_sftp_write_fails_should_raise_error
|
45
|
+
sftp = mock_sftp
|
46
|
+
sftp.expects(:open).with("test.txt", @mode, 0660).yields(mock("status1", :code => Net::SFTP::Session::FX_OK), :file_handle)
|
47
|
+
sftp.expects(:write).with(:file_handle, "data").yields(mock("status2", :code => "bad status", :message => "bad status"))
|
48
|
+
session = mock("session", :sftp => sftp, :xserver => server("capistrano"))
|
49
|
+
upload = Capistrano::Upload.new([session], "test.txt", :data => "data", :logger => stub_everything)
|
50
|
+
assert_raises(Capistrano::UploadError) { upload.process! }
|
51
|
+
assert_equal 1, upload.failed
|
52
|
+
assert_equal 1, upload.completed
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_upload_error_should_include_accessor_with_host_array
|
56
|
+
sftp = mock_sftp
|
57
|
+
sftp.expects(:open).with("test.txt", @mode, 0660).yields(mock("status1", :code => Net::SFTP::Session::FX_OK), :file_handle)
|
58
|
+
sftp.expects(:write).with(:file_handle, "data").yields(mock("status2", :code => "bad status", :message => "bad status"))
|
59
|
+
session = mock("session", :sftp => sftp, :xserver => server("capistrano"))
|
60
|
+
upload = Capistrano::Upload.new([session], "test.txt", :data => "data", :logger => stub_everything)
|
61
|
+
|
62
|
+
begin
|
63
|
+
upload.process!
|
64
|
+
flunk "expected an exception to be raised"
|
65
|
+
rescue Capistrano::UploadError => e
|
66
|
+
assert e.respond_to?(:hosts)
|
67
|
+
assert_equal %w(capistrano), e.hosts.map { |h| h.to_s }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_process_when_sftp_succeeds_should_raise_nothing
|
72
|
+
sftp = mock_sftp
|
73
|
+
sftp.expects(:open).with("test.txt", @mode, 0660).yields(mock("status1", :code => Net::SFTP::Session::FX_OK), :file_handle)
|
74
|
+
sftp.expects(:write).with(:file_handle, "data").yields(mock("status2", :code => Net::SFTP::Session::FX_OK))
|
75
|
+
sftp.expects(:close_handle).with(:file_handle).yields
|
76
|
+
session = mock("session", :sftp => sftp, :xserver => server("capistrano"))
|
77
|
+
upload = Capistrano::Upload.new([session], "test.txt", :data => "data", :logger => stub_everything)
|
78
|
+
assert_nothing_raised { upload.process! }
|
79
|
+
assert_equal 0, upload.failed
|
80
|
+
assert_equal 1, upload.completed
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_process_should_loop_while_running
|
84
|
+
con = mock("connection")
|
85
|
+
con.expects(:process).with(true).times(10)
|
86
|
+
channel = {}
|
87
|
+
channel.expects(:connection).returns(con).times(10)
|
88
|
+
sftp = mock("sftp", :state => :open, :open => nil)
|
89
|
+
sftp.stubs(:channel).returns(channel)
|
90
|
+
session = mock("session", :sftp => sftp, :xserver => server("capistrano"))
|
91
|
+
upload = Capistrano::Upload.new([session], "test.txt", :data => "data")
|
92
|
+
upload.expects(:running?).times(11).returns(*([true]*10 + [false]))
|
93
|
+
upload.process!
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_process_should_loop_but_not_process_done_channels
|
97
|
+
new_sftp = Proc.new do |done|
|
98
|
+
channel = {}
|
99
|
+
channel[:needs_done] = done
|
100
|
+
|
101
|
+
if !done
|
102
|
+
con = mock("connection")
|
103
|
+
con.expects(:process).with(true).times(10)
|
104
|
+
channel.expects(:connection).returns(con).times(10)
|
105
|
+
end
|
106
|
+
|
107
|
+
sftp = mock("sftp", :state => :open, :open => nil)
|
108
|
+
sftp.stubs(:channel).returns(channel)
|
109
|
+
sftp
|
110
|
+
end
|
111
|
+
|
112
|
+
sessions = [stub("session", :sftp => new_sftp[true], :xserver => server("capistrano")),
|
113
|
+
stub("session", :sftp => new_sftp[false], :xserver => server("cap2"))]
|
114
|
+
upload = Capistrano::Upload.new(sessions, "test.txt", :data => "data")
|
115
|
+
|
116
|
+
# make sure the sftp channels we wanted to be done, start as done
|
117
|
+
# (Upload.new marks each channel as not-done, so we have to do it here)
|
118
|
+
sessions.each { |s| s.sftp.channel[:done] = true if s.sftp.channel[:needs_done] }
|
119
|
+
upload.expects(:running?).times(11).returns(*([true]*10 + [false]))
|
120
|
+
upload.process!
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def mock_sftp
|
126
|
+
sftp = mock("sftp", :state => :open)
|
127
|
+
sftp.stubs(:channel).returns(Hash.new)
|
128
|
+
yield sftp if block_given?
|
129
|
+
sftp
|
130
|
+
end
|
131
|
+
end
|