1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

make tests pass

This commit is contained in:
Jamis Buck 2008-08-21 14:29:28 -06:00
parent c70e595c36
commit 5d76e1d2c0
5 changed files with 66 additions and 65 deletions

View file

@ -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]

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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"