mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
make tests pass
This commit is contained in:
parent
c70e595c36
commit
5d76e1d2c0
5 changed files with 66 additions and 65 deletions
|
@ -142,7 +142,13 @@ module Capistrano
|
||||||
# * +data+: (optional), a string to be sent to the command via it's stdin
|
# * +data+: (optional), a string to be sent to the command via it's stdin
|
||||||
# * +env+: (optional), a string or hash to be interpreted as environment
|
# * +env+: (optional), a string or hash to be interpreted as environment
|
||||||
# variables that should be defined for this command invocation.
|
# variables that should be defined for this command invocation.
|
||||||
def initialize(tree, sessions, options={})
|
def initialize(tree, sessions, options={}, &block)
|
||||||
|
if String === tree
|
||||||
|
tree = Tree.new(nil) { |t| t.else(tree, &block) }
|
||||||
|
elsif block
|
||||||
|
raise ArgumentError, "block given with tree argument"
|
||||||
|
end
|
||||||
|
|
||||||
@tree = tree
|
@tree = tree
|
||||||
@sessions = sessions
|
@sessions = sessions
|
||||||
@options = options
|
@options = options
|
||||||
|
@ -160,9 +166,10 @@ module Capistrano
|
||||||
logger.trace "command finished" if logger
|
logger.trace "command finished" if logger
|
||||||
|
|
||||||
if (failed = @channels.select { |ch| ch[:status] != 0 }).any?
|
if (failed = @channels.select { |ch| ch[:status] != 0 }).any?
|
||||||
hosts = failed.map { |ch| ch[:server] }
|
commands = failed.inject({}) { |map, ch| (map[ch[:command]] ||= []) << ch[:server]; map }
|
||||||
error = CommandError.new("command #{command.inspect} failed on #{hosts.join(',')}")
|
message = commands.map { |command, list| "#{command.inspect} on #{list.join(',')}" }.join("; ")
|
||||||
error.hosts = hosts
|
error = CommandError.new("failed: #{message}")
|
||||||
|
error.hosts = commands.values.flatten
|
||||||
raise error
|
raise error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -207,6 +214,7 @@ module Capistrano
|
||||||
end
|
end
|
||||||
|
|
||||||
command_line = [environment, shell, cmd].compact.join(" ")
|
command_line = [environment, shell, cmd].compact.join(" ")
|
||||||
|
ch[:command] = command_line
|
||||||
|
|
||||||
ch.exec(command_line)
|
ch.exec(command_line)
|
||||||
ch.send_data(options[:data]) if options[:data]
|
ch.send_data(options[:data]) if options[:data]
|
||||||
|
|
|
@ -50,7 +50,7 @@ module Capistrano
|
||||||
# stdout), and the data that was received.
|
# stdout), and the data that was received.
|
||||||
def run(cmd, options={}, &block)
|
def run(cmd, options={}, &block)
|
||||||
block ||= self.class.default_io_proc
|
block ||= self.class.default_io_proc
|
||||||
tree = Command::Tree.new(self) { |t| t.else(cmd, block) }
|
tree = Command::Tree.new(self) { |t| t.else(cmd, &block) }
|
||||||
run_tree(tree, options)
|
run_tree(tree, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
require "utils"
|
require "utils"
|
||||||
require 'capistrano/command'
|
require 'capistrano/command'
|
||||||
|
require 'capistrano/configuration'
|
||||||
|
|
||||||
class CommandTest < Test::Unit::TestCase
|
class CommandTest < Test::Unit::TestCase
|
||||||
def test_command_should_open_channels_on_all_sessions
|
def test_command_should_open_channels_on_all_sessions
|
||||||
s1 = mock(:open_channel => nil)
|
s1, s2, s3 = mock_session, mock_session, mock_session
|
||||||
s2 = mock(:open_channel => nil)
|
assert_equal "ls", Capistrano::Command.new("ls", [s1, s2, s3]).tree.fallback.command
|
||||||
s3 = mock(:open_channel => nil)
|
|
||||||
assert_equal "ls", Capistrano::Command.new("ls", [s1, s2, s3]).command
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_command_with_newlines_should_be_properly_escaped
|
def test_command_with_newlines_should_be_properly_escaped
|
||||||
cmd = Capistrano::Command.new("ls\necho", [mock(:open_channel => nil)])
|
cmd = Capistrano::Command.new("ls\necho", [mock_session])
|
||||||
assert_equal "ls\\\necho", cmd.command
|
assert_equal "ls\\\necho", cmd.tree.fallback.command
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_command_with_windows_newlines_should_be_properly_escaped
|
def test_command_with_windows_newlines_should_be_properly_escaped
|
||||||
cmd = Capistrano::Command.new("ls\r\necho", [mock(:open_channel => nil)])
|
cmd = Capistrano::Command.new("ls\r\necho", [mock_session])
|
||||||
assert_equal "ls\\\necho", cmd.command
|
assert_equal "ls\\\necho", cmd.tree.fallback.command
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_command_with_pty_should_request_pty_and_register_success_callback
|
def test_command_with_pty_should_request_pty_and_register_success_callback
|
||||||
|
@ -76,25 +75,17 @@ class CommandTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_open_channel_should_set_host_key_on_channel
|
def test_open_channel_should_set_host_key_on_channel
|
||||||
session = mock(:xserver => server("capistrano"))
|
channel = nil
|
||||||
channel = stub_everything
|
session = setup_for_extracting_channel_action { |ch| channel = ch }
|
||||||
|
|
||||||
session.expects(:open_channel).yields(channel)
|
|
||||||
channel.expects(:[]=).with(:host, "capistrano")
|
|
||||||
channel.stubs(:[]).with(:host).returns("capistrano")
|
|
||||||
|
|
||||||
Capistrano::Command.new("ls", [session])
|
Capistrano::Command.new("ls", [session])
|
||||||
|
assert_equal "capistrano", channel[:host]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_open_channel_should_set_options_key_on_channel
|
def test_open_channel_should_set_options_key_on_channel
|
||||||
session = mock(:xserver => server("capistrano"))
|
channel = nil
|
||||||
channel = stub_everything
|
session = setup_for_extracting_channel_action { |ch| channel = ch }
|
||||||
|
|
||||||
session.expects(:open_channel).yields(channel)
|
|
||||||
channel.expects(:[]=).with(:options, {:data => "here we go"})
|
|
||||||
channel.stubs(:[]).with(:host).returns("capistrano")
|
|
||||||
|
|
||||||
Capistrano::Command.new("ls", [session], :data => "here we go")
|
Capistrano::Command.new("ls", [session], :data => "here we go")
|
||||||
|
assert_equal({ :data => 'here we go' }, channel[:options])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_successful_channel_should_send_command
|
def test_successful_channel_should_send_command
|
||||||
|
@ -157,17 +148,17 @@ class CommandTest < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_on_request_should_record_exit_status
|
def test_on_request_should_record_exit_status
|
||||||
data = mock(:read_long => 5)
|
data = mock(:read_long => 5)
|
||||||
session = setup_for_extracting_channel_action([:on_request, "exit-status"], data) do |ch|
|
channel = nil
|
||||||
ch.expects(:[]=).with(:status, 5)
|
session = setup_for_extracting_channel_action([:on_request, "exit-status"], data) { |ch| channel = ch }
|
||||||
end
|
|
||||||
Capistrano::Command.new("ls", [session])
|
Capistrano::Command.new("ls", [session])
|
||||||
|
assert_equal 5, channel[:status]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_on_close_should_set_channel_closed
|
def test_on_close_should_set_channel_closed
|
||||||
session = setup_for_extracting_channel_action(:on_close) do |ch|
|
channel = nil
|
||||||
ch.expects(:[]=).with(:closed, true)
|
session = setup_for_extracting_channel_action(:on_close) { |ch| channel = ch }
|
||||||
end
|
|
||||||
Capistrano::Command.new("ls", [session])
|
Capistrano::Command.new("ls", [session])
|
||||||
|
assert channel[:closed]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_stop_should_close_all_open_channels
|
def test_stop_should_close_all_open_channels
|
||||||
|
@ -228,10 +219,8 @@ class CommandTest < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_process_should_instantiate_command_and_process!
|
def test_process_should_instantiate_command_and_process!
|
||||||
cmd = mock("command", :process! => nil)
|
cmd = mock("command", :process! => nil)
|
||||||
Capistrano::Command.expects(:new).with("ls -l", %w(a b c), {:foo => "bar"}).yields(:command).returns(cmd)
|
Capistrano::Command.expects(:new).with("ls -l", %w(a b c), {:foo => "bar"}).returns(cmd)
|
||||||
parameter = nil
|
Capistrano::Command.process("ls -l", %w(a b c), :foo => "bar")
|
||||||
Capistrano::Command.process("ls -l", %w(a b c), :foo => "bar") { |cmd| parameter = cmd }
|
|
||||||
assert_equal :command, parameter
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_process_with_host_placeholder_should_substitute_placeholder_with_each_host
|
def test_process_with_host_placeholder_should_substitute_placeholder_with_each_host
|
||||||
|
@ -254,16 +243,20 @@ class CommandTest < Test::Unit::TestCase
|
||||||
stub('session', :open_channel => channel,
|
stub('session', :open_channel => channel,
|
||||||
:preprocess => true,
|
:preprocess => true,
|
||||||
:postprocess => true,
|
:postprocess => true,
|
||||||
:listeners => {})
|
:listeners => {},
|
||||||
|
:xserver => server("capistrano"))
|
||||||
|
end
|
||||||
|
|
||||||
|
class MockChannel < Hash
|
||||||
|
def close
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_channel(closed, status=nil)
|
def new_channel(closed, status=nil)
|
||||||
ch = mock("channel")
|
ch = MockChannel.new
|
||||||
ch.expects(:[]).with(:closed).returns(closed)
|
ch.update({ :closed => closed, :host => "capistrano", :server => server("capistrano") })
|
||||||
ch.expects(:[]).with(:status).returns(status) if status
|
ch[:status] = status if status
|
||||||
ch.expects(:close) unless closed
|
ch.expects(:close) unless closed
|
||||||
ch.stubs(:[]).with(:host).returns("capistrano")
|
|
||||||
ch.stubs(:[]).with(:server).returns(server("capistrano"))
|
|
||||||
ch
|
ch
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -271,11 +264,15 @@ class CommandTest < Test::Unit::TestCase
|
||||||
s = server("capistrano")
|
s = server("capistrano")
|
||||||
session = mock("session", :xserver => s)
|
session = mock("session", :xserver => s)
|
||||||
|
|
||||||
channel = stub_everything
|
channel = {}
|
||||||
session.expects(:open_channel).yields(channel)
|
session.expects(:open_channel).yields(channel)
|
||||||
|
|
||||||
channel.stubs(:[]).with(:server).returns(s)
|
channel.stubs(:on_data)
|
||||||
channel.stubs(:[]).with(:host).returns(s.host)
|
channel.stubs(:on_extended_data)
|
||||||
|
channel.stubs(:on_request)
|
||||||
|
channel.stubs(:on_close)
|
||||||
|
channel.stubs(:exec)
|
||||||
|
channel.stubs(:send_data)
|
||||||
|
|
||||||
if action
|
if action
|
||||||
action = Array(action)
|
action = Array(action)
|
||||||
|
|
|
@ -47,22 +47,6 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
|
||||||
@config.run "ls", :foo => "bar"
|
@config.run "ls", :foo => "bar"
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_run_without_block_should_use_default_io_proc
|
|
||||||
@config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| server(s) })
|
|
||||||
@config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
|
|
||||||
prepare_command("ls", [:s1, :s2, :s3], {:logger => @config.logger})
|
|
||||||
MockConfig.default_io_proc = inspectable_proc
|
|
||||||
@config.run "ls"
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_run_with_block_should_use_block
|
|
||||||
@config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| mock(:host => s) })
|
|
||||||
@config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
|
|
||||||
prepare_command("ls", [:s1, :s2, :s3], {:logger => @config.logger})
|
|
||||||
MockConfig.default_io_proc = Proc.new { |a,b,c| raise "shouldn't get here" }
|
|
||||||
@config.run("ls", &inspectable_proc)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_add_default_command_options_should_return_bare_options_if_there_is_no_env_or_shell_specified
|
def test_add_default_command_options_should_return_bare_options_if_there_is_no_env_or_shell_specified
|
||||||
assert_equal({:foo => "bar"}, @config.add_default_command_options(:foo => "bar"))
|
assert_equal({:foo => "bar"}, @config.add_default_command_options(:foo => "bar"))
|
||||||
end
|
end
|
||||||
|
@ -210,6 +194,11 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
|
||||||
a = mock("channel", :called => true)
|
a = mock("channel", :called => true)
|
||||||
b = mock("stream", :called => true)
|
b = mock("stream", :called => true)
|
||||||
c = mock("data", :called => true)
|
c = mock("data", :called => true)
|
||||||
Capistrano::Command.expects(:process).with(command, sessions, options).yields(a, b, c)
|
|
||||||
|
compare_args = Proc.new do |tree, sess, opts|
|
||||||
|
tree.fallback.command == command && sess == sessions && opts == options
|
||||||
|
end
|
||||||
|
|
||||||
|
Capistrano::Command.expects(:process).with(&compare_args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,14 @@ class ConfigurationTest < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_connections_execution_loading_namespaces_roles_and_variables_modules_should_integrate_correctly
|
def test_connections_execution_loading_namespaces_roles_and_variables_modules_should_integrate_correctly
|
||||||
Capistrano::SSH.expects(:connect).with { |s,c| s.host == "www.capistrano.test" && c == @config }.returns(:session)
|
Capistrano::SSH.expects(:connect).with { |s,c| s.host == "www.capistrano.test" && c == @config }.returns(:session)
|
||||||
Capistrano::Command.expects(:process).with("echo 'hello world'", [:session], :logger => @config.logger)
|
|
||||||
|
process_args = Proc.new do |tree, session, opts|
|
||||||
|
tree.fallback.command == "echo 'hello world'" &&
|
||||||
|
session == [:session] &&
|
||||||
|
opts == { :logger => @config.logger }
|
||||||
|
end
|
||||||
|
|
||||||
|
Capistrano::Command.expects(:process).with(&process_args)
|
||||||
|
|
||||||
@config.load do
|
@config.load do
|
||||||
role :test, "www.capistrano.test"
|
role :test, "www.capistrano.test"
|
||||||
|
|
Loading…
Reference in a new issue