capistrano 2.0.0 → 2.15.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG +737 -18
  5. data/Gemfile +13 -0
  6. data/README.md +94 -0
  7. data/Rakefile +11 -0
  8. data/bin/cap +0 -0
  9. data/bin/capify +37 -22
  10. data/capistrano.gemspec +40 -0
  11. data/lib/capistrano/callback.rb +5 -1
  12. data/lib/capistrano/cli/execute.rb +10 -7
  13. data/lib/capistrano/cli/help.rb +39 -16
  14. data/lib/capistrano/cli/help.txt +44 -16
  15. data/lib/capistrano/cli/options.rb +71 -11
  16. data/lib/capistrano/cli/ui.rb +13 -1
  17. data/lib/capistrano/cli.rb +5 -5
  18. data/lib/capistrano/command.rb +215 -58
  19. data/lib/capistrano/configuration/actions/file_transfer.rb +29 -14
  20. data/lib/capistrano/configuration/actions/inspect.rb +3 -3
  21. data/lib/capistrano/configuration/actions/invocation.rb +224 -22
  22. data/lib/capistrano/configuration/alias_task.rb +26 -0
  23. data/lib/capistrano/configuration/callbacks.rb +26 -27
  24. data/lib/capistrano/configuration/connections.rb +130 -52
  25. data/lib/capistrano/configuration/execution.rb +34 -18
  26. data/lib/capistrano/configuration/loading.rb +99 -6
  27. data/lib/capistrano/configuration/log_formatters.rb +75 -0
  28. data/lib/capistrano/configuration/namespaces.rb +45 -12
  29. data/lib/capistrano/configuration/roles.rb +28 -2
  30. data/lib/capistrano/configuration/servers.rb +51 -10
  31. data/lib/capistrano/configuration/variables.rb +3 -3
  32. data/lib/capistrano/configuration.rb +20 -4
  33. data/lib/capistrano/errors.rb +12 -8
  34. data/lib/capistrano/ext/multistage.rb +67 -0
  35. data/lib/capistrano/ext/string.rb +5 -0
  36. data/lib/capistrano/extensions.rb +1 -1
  37. data/lib/capistrano/fix_rake_deprecated_dsl.rb +8 -0
  38. data/lib/capistrano/logger.rb +112 -5
  39. data/lib/capistrano/processable.rb +55 -0
  40. data/lib/capistrano/recipes/compat.rb +2 -2
  41. data/lib/capistrano/recipes/deploy/assets.rb +201 -0
  42. data/lib/capistrano/recipes/deploy/dependencies.rb +2 -2
  43. data/lib/capistrano/recipes/deploy/local_dependency.rb +10 -2
  44. data/lib/capistrano/recipes/deploy/remote_dependency.rb +54 -2
  45. data/lib/capistrano/recipes/deploy/scm/accurev.rb +169 -0
  46. data/lib/capistrano/recipes/deploy/scm/base.rb +31 -11
  47. data/lib/capistrano/recipes/deploy/scm/bzr.rb +14 -14
  48. data/lib/capistrano/recipes/deploy/scm/cvs.rb +11 -9
  49. data/lib/capistrano/recipes/deploy/scm/darcs.rb +12 -1
  50. data/lib/capistrano/recipes/deploy/scm/git.rb +293 -0
  51. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +23 -15
  52. data/lib/capistrano/recipes/deploy/scm/none.rb +55 -0
  53. data/lib/capistrano/recipes/deploy/scm/perforce.rb +54 -28
  54. data/lib/capistrano/recipes/deploy/scm/subversion.rb +36 -18
  55. data/lib/capistrano/recipes/deploy/scm.rb +1 -1
  56. data/lib/capistrano/recipes/deploy/strategy/base.rb +32 -4
  57. data/lib/capistrano/recipes/deploy/strategy/copy.rb +238 -43
  58. data/lib/capistrano/recipes/deploy/strategy/remote.rb +1 -1
  59. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +11 -1
  60. data/lib/capistrano/recipes/deploy/strategy/unshared_remote_cache.rb +21 -0
  61. data/lib/capistrano/recipes/deploy/strategy.rb +1 -1
  62. data/lib/capistrano/recipes/deploy.rb +265 -123
  63. data/lib/capistrano/recipes/standard.rb +1 -1
  64. data/lib/capistrano/role.rb +102 -0
  65. data/lib/capistrano/server_definition.rb +6 -1
  66. data/lib/capistrano/shell.rb +30 -33
  67. data/lib/capistrano/ssh.rb +46 -60
  68. data/lib/capistrano/task_definition.rb +16 -8
  69. data/lib/capistrano/transfer.rb +218 -0
  70. data/lib/capistrano/version.rb +6 -17
  71. data/lib/capistrano.rb +4 -1
  72. data/test/cli/execute_test.rb +3 -3
  73. data/test/cli/help_test.rb +33 -7
  74. data/test/cli/options_test.rb +109 -6
  75. data/test/cli/ui_test.rb +2 -2
  76. data/test/cli_test.rb +3 -3
  77. data/test/command_test.rb +144 -124
  78. data/test/configuration/actions/file_transfer_test.rb +41 -20
  79. data/test/configuration/actions/inspect_test.rb +21 -7
  80. data/test/configuration/actions/invocation_test.rb +123 -30
  81. data/test/configuration/alias_task_test.rb +118 -0
  82. data/test/configuration/callbacks_test.rb +41 -46
  83. data/test/configuration/connections_test.rb +187 -36
  84. data/test/configuration/execution_test.rb +18 -2
  85. data/test/configuration/loading_test.rb +33 -4
  86. data/test/configuration/namespace_dsl_test.rb +54 -5
  87. data/test/configuration/roles_test.rb +114 -4
  88. data/test/configuration/servers_test.rb +97 -4
  89. data/test/configuration/variables_test.rb +12 -2
  90. data/test/configuration_test.rb +9 -13
  91. data/test/deploy/local_dependency_test.rb +76 -0
  92. data/test/deploy/remote_dependency_test.rb +146 -0
  93. data/test/deploy/scm/accurev_test.rb +23 -0
  94. data/test/deploy/scm/base_test.rb +1 -1
  95. data/test/deploy/scm/bzr_test.rb +51 -0
  96. data/test/deploy/scm/darcs_test.rb +37 -0
  97. data/test/deploy/scm/git_test.rb +274 -0
  98. data/test/deploy/scm/mercurial_test.rb +134 -0
  99. data/test/deploy/scm/none_test.rb +35 -0
  100. data/test/deploy/scm/perforce_test.rb +23 -0
  101. data/test/deploy/scm/subversion_test.rb +68 -0
  102. data/test/deploy/strategy/copy_test.rb +240 -26
  103. data/test/extensions_test.rb +2 -2
  104. data/test/logger_formatting_test.rb +149 -0
  105. data/test/logger_test.rb +13 -2
  106. data/test/recipes_test.rb +25 -0
  107. data/test/role_test.rb +11 -0
  108. data/test/server_definition_test.rb +15 -2
  109. data/test/shell_test.rb +33 -1
  110. data/test/ssh_test.rb +40 -24
  111. data/test/task_definition_test.rb +18 -2
  112. data/test/transfer_test.rb +168 -0
  113. data/test/utils.rb +28 -33
  114. metadata +215 -101
  115. data/MIT-LICENSE +0 -20
  116. data/README +0 -43
  117. data/examples/sample.rb +0 -14
  118. data/lib/capistrano/gateway.rb +0 -131
  119. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
  120. data/lib/capistrano/recipes/upgrade.rb +0 -33
  121. data/lib/capistrano/upload.rb +0 -146
  122. data/test/gateway_test.rb +0 -167
  123. data/test/upload_test.rb +0 -131
  124. data/test/version_test.rb +0 -24
data/test/shell_test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/configuration'
3
3
  require 'capistrano/shell'
4
4
 
@@ -44,6 +44,12 @@ class ShellTest < Test::Unit::TestCase
44
44
  assert @shell.read_and_execute
45
45
  end
46
46
 
47
+ def test_set_with_colon_changes_setting
48
+ @shell.expects(:read_line).returns("set :random_setting value")
49
+ @shell.configuration.expects(:set).with(:random_setting, "value")
50
+ assert @shell.read_and_execute
51
+ end
52
+
47
53
  def test_text_without_with_or_on_gets_processed_verbatim
48
54
  @shell.expects(:read_line).returns("hello world")
49
55
  @shell.expects(:process_command).with(nil, nil, "hello world")
@@ -61,4 +67,30 @@ class ShellTest < Test::Unit::TestCase
61
67
  @shell.expects(:process_command).with("on", "app,db", "hello world")
62
68
  assert @shell.read_and_execute
63
69
  end
70
+
71
+ def test_task_command_with_bang_gets_processed_by_exec_tasks
72
+ while_testing_post_exec_commands do
73
+ @shell.expects(:read_line).returns("!deploy")
74
+ @shell.expects(:exec_tasks).with(["deploy"])
75
+ assert @shell.read_and_execute
76
+ end
77
+ end
78
+
79
+ def test_normal_command_gets_processed_by_exec_command
80
+ while_testing_post_exec_commands do
81
+ @shell.expects(:read_line).returns("uptime")
82
+ @shell.expects(:exec_command).with("uptime",nil)
83
+ @shell.expects(:connect)
84
+ assert @shell.read_and_execute
85
+ end
86
+ end
87
+
88
+
89
+ private
90
+
91
+ def while_testing_post_exec_commands(&block)
92
+ @shell.instance_variable_set(:@mutex,Mutex.new)
93
+ yield
94
+ end
95
+
64
96
  end
data/test/ssh_test.rb CHANGED
@@ -1,89 +1,105 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/ssh'
3
3
 
4
4
  class SSHTest < Test::Unit::TestCase
5
5
  def setup
6
- @options = { :username => nil,
7
- :password => nil,
8
- :port => 22,
9
- :auth_methods => %w(publickey hostbased) }
6
+ Capistrano::ServerDefinition.stubs(:default_user).returns("default-user")
7
+ @options = { :password => nil,
8
+ :auth_methods => %w(publickey hostbased),
9
+ :config => false }
10
10
  @server = server("capistrano")
11
+ Net::SSH.stubs(:configuration_for).returns({})
11
12
  end
12
13
 
13
14
  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
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).returns(success = Object.new)
15
16
  assert_equal success, Capistrano::SSH.connect(@server)
16
17
  end
17
18
 
18
19
  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)
20
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).raises(Net::SSH::AuthenticationFailed)
21
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
21
22
  assert_equal success, Capistrano::SSH.connect(@server, :password => "f4b13n")
22
23
  end
23
24
 
24
25
  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)
26
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).raises(Net::SSH::AuthenticationFailed)
27
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).raises(Net::SSH::AuthenticationFailed)
27
28
  assert_raises(Net::SSH::AuthenticationFailed) do
28
29
  Capistrano::SSH.connect(@server, :password => "f4b13n")
29
30
  end
30
31
  end
31
32
 
32
33
  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
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options).returns(success = Object.new)
34
35
  assert_equal success, Capistrano::SSH.connect(@server, :user => "jamis")
35
36
  end
36
37
 
37
38
  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)
39
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options).raises(Net::SSH::AuthenticationFailed)
40
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options.merge(:password => "f4b13n", :auth_methods => %w(password keyboard-interactive))).returns(success = Object.new)
40
41
  assert_equal success, Capistrano::SSH.connect(@server, :user => "jamis", :password => "f4b13n")
41
42
  end
42
43
 
43
44
  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
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:port => 1234)).returns(success = Object.new)
45
46
  assert_equal success, Capistrano::SSH.connect(@server, :port => 1234)
46
47
  end
47
48
 
48
49
  def test_connect_with_server_with_user_should_pass_user_to_net_ssh
49
50
  server = server("jamis@capistrano")
50
- Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis")).returns(success = Object.new)
51
+ Net::SSH.expects(:start).with(server.host, "jamis", @options).returns(success = Object.new)
51
52
  assert_equal success, Capistrano::SSH.connect(server)
52
53
  end
53
54
 
54
55
  def test_connect_with_server_with_port_should_pass_port_to_net_ssh
55
56
  server = server("capistrano:1235")
56
- Net::SSH.expects(:start).with(server.host, @options.merge(:port => 1235)).returns(success = Object.new)
57
+ Net::SSH.expects(:start).with(server.host, "default-user", @options.merge(:port => 1235)).returns(success = Object.new)
57
58
  assert_equal success, Capistrano::SSH.connect(server)
58
59
  end
59
60
 
60
61
  def test_connect_with_server_with_user_and_port_should_pass_user_and_port_to_net_ssh
61
62
  server = server("jamis@capistrano:1235")
62
- Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis", :port => 1235)).returns(success = Object.new)
63
+ Net::SSH.expects(:start).with(server.host, "jamis", @options.merge(:port => 1235)).returns(success = Object.new)
64
+ assert_equal success, Capistrano::SSH.connect(server)
65
+ end
66
+
67
+ def test_connect_with_server_with_other_ssh_options_should_pass_ssh_options_to_net_ssh
68
+ server = server("jamis@capistrano:1235", :ssh_options => { :keys => %w(some_valid_key), :auth_methods => %w(a_method), :hmac => 'none' })
69
+ Net::SSH.expects(:start).with(server.host, "jamis", @options.merge(:port => 1235, :keys => %w(some_valid_key), :auth_methods => %w(a_method), :hmac => 'none' )).returns(success = Object.new)
63
70
  assert_equal success, Capistrano::SSH.connect(server)
64
71
  end
65
72
 
66
73
  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)
74
+ ssh_options = { :username => "JamisMan", :port => 8125, :config => false }
75
+ Net::SSH.expects(:start).with(@server.host, "JamisMan", @options.merge(:port => 8125, :config => false)).returns(success = Object.new)
69
76
  assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options})
70
77
  end
71
78
 
72
79
  def test_connect_with_options_and_ssh_options_should_see_options_override_ssh_options
73
80
  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})
81
+ Net::SSH.expects(:start).with(@server.host, "jamis", @options.merge(:port => 1235, :forward_agent => true)).returns(success = Object.new)
82
+ assert_equal success, Capistrano::SSH.connect(@server, :ssh_options => ssh_options, :user => "jamis", :port => 1235)
83
+ end
84
+
85
+ def test_connect_with_verbose_option_should_set_verbose_option_on_ssh
86
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).returns(success = Object.new)
87
+ assert_equal success, Capistrano::SSH.connect(@server, :verbose => 0)
88
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:verbose => :debug)).returns(success = Object.new)
89
+ assert_equal success, Capistrano::SSH.connect(@server, :verbose => 1)
90
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:verbose => :debug)).returns(success = Object.new)
91
+ assert_equal success, Capistrano::SSH.connect(@server, :verbose => 2)
76
92
  end
77
93
 
78
94
  def test_connect_with_ssh_options_should_see_server_options_override_ssh_options
79
95
  ssh_options = { :username => "JamisMan", :port => 8125, :forward_agent => true }
80
96
  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)
97
+ Net::SSH.expects(:start).with(server.host, "jamis", @options.merge(:port => 1235, :forward_agent => true, :config => false)).returns(success = Object.new)
82
98
  assert_equal success, Capistrano::SSH.connect(server, {:ssh_options => ssh_options})
83
99
  end
84
100
 
85
101
  def test_connect_should_add_xserver_accessor_to_connection
86
- Net::SSH.expects(:start).with(@server.host, @options).returns(success = Object.new)
102
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options).returns(success = Object.new)
87
103
  assert_equal success, Capistrano::SSH.connect(@server)
88
104
  assert success.respond_to?(:xserver)
89
105
  assert success.respond_to?(:xserver)
@@ -91,7 +107,7 @@ class SSHTest < Test::Unit::TestCase
91
107
  end
92
108
 
93
109
  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)
110
+ Net::SSH.expects(:start).with(@server.host, "default-user", @options.merge(:auth_methods => %w(publickey))).raises(Net::SSH::AuthenticationFailed)
95
111
  assert_raises(Net::SSH::AuthenticationFailed) { Capistrano::SSH.connect(@server, :ssh_options => { :auth_methods => %w(publickey) }) }
96
112
  end
97
113
  end
@@ -1,6 +1,9 @@
1
- require "#{File.dirname(__FILE__)}/utils"
1
+ require "utils"
2
2
  require 'capistrano/task_definition'
3
3
 
4
+ # Silences the wanrnings raised in the two deprecation tests
5
+ $VERBOSE = nil
6
+
4
7
  class TaskDefinitionTest < Test::Unit::TestCase
5
8
  def setup
6
9
  @namespace = namespace
@@ -22,6 +25,19 @@ class TaskDefinitionTest < Test::Unit::TestCase
22
25
  assert_equal "default", task.fully_qualified_name
23
26
  end
24
27
 
28
+ def test_name_should_change_task_name
29
+ task = new_task(:foo)
30
+ task.name = :bar
31
+
32
+ assert_equal :bar, task.name
33
+ end
34
+
35
+ def test_raise_an_exception_when_task_names_can_not_be_converted
36
+ task = new_task('valid task name')
37
+
38
+ assert_raises(ArgumentError) { task.name = ['invalid task name'] }
39
+ end
40
+
25
41
  def test_fqn_in_namespace_when_default_should_be_namespace_fqn
26
42
  ns = namespace("outer:inner")
27
43
  task = new_task(:default, ns)
@@ -98,4 +114,4 @@ class TaskDefinitionTest < Test::Unit::TestCase
98
114
  task = new_task(:testing, @namespace, :desc => "Take file.txt and copy it. Then do something else.")
99
115
  assert_equal "Take file.txt and copy it.", task.brief_description
100
116
  end
101
- end
117
+ end
@@ -0,0 +1,168 @@
1
+ require 'utils'
2
+ require 'capistrano/transfer'
3
+
4
+ class TransferTest < Test::Unit::TestCase
5
+ def test_class_process_should_delegate_to_instance_process
6
+ Capistrano::Transfer.expects(:new).with(:up, "from", "to", %w(a b c), {}).returns(mock('transfer', :process! => nil)).yields
7
+ yielded = false
8
+ Capistrano::Transfer.process(:up, "from", "to", %w(a b c), {}) { yielded = true }
9
+ assert yielded
10
+ end
11
+
12
+ def test_default_transport_is_sftp
13
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [])
14
+ assert_equal :sftp, transfer.transport
15
+ end
16
+
17
+ def test_active_is_true_when_any_sftp_transfers_are_active
18
+ returns = [false, false, true]
19
+ sessions = [session('app1', :sftp), session('app2', :sftp), session('app3', :sftp)].each { |s| s.xsftp.expects(:upload).returns(stub('operation', :active? => returns.shift)) }
20
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :sftp)
21
+ assert_equal true, transfer.active?
22
+ end
23
+
24
+ def test_active_is_false_when_all_sftp_transfers_are_not_active
25
+ sessions = [session('app1', :sftp), session('app2', :sftp)].each { |s| s.xsftp.expects(:upload).returns(stub('operation', :active? => false)) }
26
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :sftp)
27
+ assert_equal false, transfer.active?
28
+ end
29
+
30
+ def test_active_is_true_when_any_scp_transfers_are_active
31
+ returns = [false, false, true]
32
+ sessions = [session('app1', :scp), session('app2', :scp), session('app3', :scp)].each do |s|
33
+ channel = stub('channel', :[]= => nil, :active? => returns.shift)
34
+ s.scp.expects(:upload).returns(channel)
35
+ end
36
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :scp)
37
+ assert_equal true, transfer.active?
38
+ end
39
+
40
+ def test_active_is_false_when_all_scp_transfers_are_not_active
41
+ sessions = [session('app1', :scp), session('app2', :scp), session('app3', :scp)].each do |s|
42
+ channel = stub('channel', :[]= => nil, :active? => false)
43
+ s.scp.expects(:upload).returns(channel)
44
+ end
45
+ transfer = Capistrano::Transfer.new(:up, "from", "to", sessions, :via => :scp)
46
+ assert_equal false, transfer.active?
47
+ end
48
+
49
+ [:up, :down].each do |direction|
50
+ define_method("test_sftp_#{direction}load_from_file_to_file_should_normalize_from_and_to") do
51
+ sessions = [session('app1', :sftp), session('app2', :sftp)]
52
+
53
+ sessions.each do |session|
54
+ session.xsftp.expects("#{direction}load".to_sym).with("from-#{session.xserver.host}", "to-#{session.xserver.host}",
55
+ :properties => { :server => session.xserver, :host => session.xserver.host })
56
+ end
57
+
58
+ transfer = Capistrano::Transfer.new(direction, "from-$CAPISTRANO:HOST$", "to-$CAPISTRANO:HOST$", sessions)
59
+ end
60
+
61
+ define_method("test_scp_#{direction}load_from_file_to_file_should_normalize_from_and_to") do
62
+ sessions = [session('app1', :scp), session('app2', :scp)]
63
+
64
+ sessions.each do |session|
65
+ session.scp.expects("#{direction}load".to_sym).returns({}).with("from-#{session.xserver.host}", "to-#{session.xserver.host}", :via => :scp)
66
+ end
67
+
68
+ transfer = Capistrano::Transfer.new(direction, "from-$CAPISTRANO:HOST$", "to-$CAPISTRANO:HOST$", sessions, :via => :scp)
69
+ end
70
+ end
71
+
72
+ def test_sftp_upload_from_IO_to_file_should_clone_the_IO_for_each_connection
73
+ sessions = [session('app1', :sftp), session('app2', :sftp)]
74
+ io = StringIO.new("from here")
75
+
76
+ sessions.each do |session|
77
+ session.xsftp.expects(:upload).with do |from, to, opts|
78
+ from != io && from.is_a?(StringIO) && from.string == io.string &&
79
+ to == "/to/here-#{session.xserver.host}" &&
80
+ opts[:properties][:server] == session.xserver &&
81
+ opts[:properties][:host] == session.xserver.host
82
+ end
83
+ end
84
+
85
+ transfer = Capistrano::Transfer.new(:up, StringIO.new("from here"), "/to/here-$CAPISTRANO:HOST$", sessions)
86
+ end
87
+
88
+ def test_scp_upload_from_IO_to_file_should_clone_the_IO_for_each_connection
89
+ sessions = [session('app1', :scp), session('app2', :scp)]
90
+ io = StringIO.new("from here")
91
+
92
+ sessions.each do |session|
93
+ channel = mock('channel')
94
+ channel.expects(:[]=).with(:server, session.xserver)
95
+ channel.expects(:[]=).with(:host, session.xserver.host)
96
+ session.scp.expects(:upload).returns(channel).with do |from, to, opts|
97
+ from != io && from.is_a?(StringIO) && from.string == io.string &&
98
+ to == "/to/here-#{session.xserver.host}"
99
+ end
100
+ end
101
+
102
+ transfer = Capistrano::Transfer.new(:up, StringIO.new("from here"), "/to/here-$CAPISTRANO:HOST$", sessions, :via => :scp)
103
+ end
104
+
105
+ def test_process_should_block_until_transfer_is_no_longer_active
106
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [])
107
+ transfer.expects(:process_iteration).times(4).yields.returns(true,true,true,false)
108
+ transfer.expects(:active?).times(4)
109
+ transfer.process!
110
+ end
111
+
112
+ def test_errors_raised_for_a_sftp_session_should_abort_session_and_continue_with_remaining_sessions
113
+ s = session('app1')
114
+ error = ExceptionWithSession.new(s)
115
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [])
116
+ transfer.expects(:process_iteration).raises(error).times(3).returns(true, false)
117
+ txfr = mock('transfer', :abort! => true)
118
+ txfr.expects(:[]=).with(:failed, true)
119
+ txfr.expects(:[]=).with(:error, error)
120
+ transfer.expects(:session_map).returns(s => txfr)
121
+ transfer.process!
122
+ end
123
+
124
+ def test_errors_raised_for_a_scp_session_should_abort_session_and_continue_with_remaining_sessions
125
+ s = session('app1')
126
+ error = ExceptionWithSession.new(s)
127
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [], :via => :scp)
128
+ transfer.expects(:process_iteration).raises(error).times(3).returns(true, false)
129
+ txfr = mock('channel', :close => true)
130
+ txfr.expects(:[]=).with(:failed, true)
131
+ txfr.expects(:[]=).with(:error, error)
132
+ transfer.expects(:session_map).returns(s => txfr)
133
+ transfer.process!
134
+ end
135
+
136
+ def test_uploading_a_non_existing_file_should_raise_an_understandable_error
137
+ s = session('app1')
138
+ error = Capistrano::Processable::SessionAssociation.on(ArgumentError.new('expected a file to upload'), s)
139
+ transfer = Capistrano::Transfer.new(:up, "from", "to", [], :via => :scp)
140
+ transfer.expects(:process_iteration).raises(error)
141
+ assert_raise(ArgumentError, 'expected a file to upload') { transfer.process! }
142
+ end
143
+
144
+ private
145
+
146
+ class ExceptionWithSession < ::Exception
147
+ attr_reader :session
148
+
149
+ def initialize(session)
150
+ @session = session
151
+ super()
152
+ end
153
+ end
154
+
155
+ def session(host, mode=nil)
156
+ session = stub('session', :xserver => stub('server', :host => host))
157
+ case mode
158
+ when :sftp
159
+ sftp = stub('sftp')
160
+ session.expects(:sftp).with(false).returns(sftp)
161
+ sftp.expects(:connect).yields(sftp).returns(sftp)
162
+ session.stubs(:xsftp).returns(sftp)
163
+ when :scp
164
+ session.stubs(:scp).returns(stub('scp'))
165
+ end
166
+ session
167
+ end
168
+ end
data/test/utils.rb CHANGED
@@ -1,42 +1,37 @@
1
- unless defined?(TestExtensions)
2
- $:.unshift "#{File.dirname(__FILE__)}/../lib"
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
3
 
4
- begin
5
- require 'rubygems'
6
- gem 'mocha'
7
- rescue LoadError
8
- end
9
-
10
- require 'test/unit'
11
- require 'mocha'
12
- require 'capistrano/server_definition'
4
+ require 'test/unit'
5
+ require 'mocha'
13
6
 
14
- module TestExtensions
15
- def server(host, options={})
16
- Capistrano::ServerDefinition.new(host, options)
17
- end
7
+ require 'capistrano/server_definition'
8
+ require 'pry'
18
9
 
19
- def namespace(fqn=nil)
20
- space = stub(:roles => {}, :fully_qualified_name => fqn, :default_task => nil)
21
- yield(space) if block_given?
22
- space
23
- end
10
+ module TestExtensions
11
+ def server(host, options={})
12
+ Capistrano::ServerDefinition.new(host, options)
13
+ end
24
14
 
25
- def role(space, name, *args)
26
- opts = args.last.is_a?(Hash) ? args.pop : {}
27
- space.roles[name] ||= []
28
- space.roles[name].concat(args.map { |h| Capistrano::ServerDefinition.new(h, opts) })
29
- end
15
+ def namespace(fqn=nil)
16
+ space = stub(:roles => {}, :fully_qualified_name => fqn, :default_task => nil)
17
+ yield(space) if block_given?
18
+ space
19
+ end
30
20
 
31
- def new_task(name, namespace=@namespace, options={}, &block)
32
- block ||= Proc.new {}
33
- task = Capistrano::TaskDefinition.new(name, namespace, options, &block)
34
- assert_equal block, task.body
35
- return task
36
- end
21
+ def role(space, name, *args)
22
+ opts = args.last.is_a?(Hash) ? args.pop : {}
23
+ space.roles[name] ||= []
24
+ space.roles[name].concat(args.map { |h| Capistrano::ServerDefinition.new(h, opts) })
37
25
  end
38
26
 
39
- class Test::Unit::TestCase
40
- include TestExtensions
27
+ def new_task(name, namespace=@namespace, options={}, &block)
28
+ block ||= Proc.new {}
29
+ task = Capistrano::TaskDefinition.new(name, namespace, options, &block)
30
+ assert_equal block, task.body
31
+ return task
41
32
  end
42
33
  end
34
+
35
+ class Test::Unit::TestCase
36
+ include TestExtensions
37
+ end