2007-03-02 12:15:11 -05:00
|
|
|
require "#{File.dirname(__FILE__)}/../../utils"
|
|
|
|
require 'capistrano/configuration/actions/invocation'
|
|
|
|
|
2007-03-04 13:19:26 -05:00
|
|
|
class ConfigurationActionsInvocationTest < Test::Unit::TestCase
|
2007-03-02 12:15:11 -05:00
|
|
|
class MockConfig
|
|
|
|
attr_reader :options
|
|
|
|
|
|
|
|
def initialize
|
|
|
|
@options = {}
|
|
|
|
end
|
|
|
|
|
|
|
|
def [](*args)
|
|
|
|
@options[*args]
|
|
|
|
end
|
|
|
|
|
2007-05-31 22:56:42 -04:00
|
|
|
def set(name, value)
|
|
|
|
@options[name] = value
|
|
|
|
end
|
|
|
|
|
2007-03-02 12:15:11 -05:00
|
|
|
def fetch(*args)
|
|
|
|
@options.fetch(*args)
|
|
|
|
end
|
|
|
|
|
|
|
|
include Capistrano::Configuration::Actions::Invocation
|
|
|
|
end
|
|
|
|
|
|
|
|
def setup
|
|
|
|
@config = MockConfig.new
|
|
|
|
@original_io_proc = MockConfig.default_io_proc
|
|
|
|
@config.stubs(:logger).returns(stub_everything)
|
|
|
|
end
|
|
|
|
|
|
|
|
def teardown
|
|
|
|
MockConfig.default_io_proc = @original_io_proc
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_run_options_should_be_passed_to_execute_on_servers
|
|
|
|
@config.expects(:execute_on_servers).with(:foo => "bar")
|
|
|
|
@config.run "ls", :foo => "bar"
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_run_without_block_should_use_default_io_proc
|
2007-05-09 00:45:54 -04:00
|
|
|
@config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| server(s) })
|
2007-05-09 00:02:50 -04:00
|
|
|
@config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
|
2007-03-02 12:15:11 -05:00
|
|
|
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) })
|
2007-05-09 00:02:50 -04:00
|
|
|
@config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
|
2007-03-02 12:15:11 -05:00
|
|
|
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
|
|
|
|
|
2007-06-05 12:10:01 -04:00
|
|
|
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"))
|
2007-05-31 22:56:42 -04:00
|
|
|
end
|
|
|
|
|
2007-06-05 12:10:01 -04:00
|
|
|
def test_add_default_command_options_should_merge_default_environment_as_env
|
2007-05-31 22:56:42 -04:00
|
|
|
@config[:default_environment][:bang] = "baz"
|
2007-06-05 12:10:01 -04:00
|
|
|
assert_equal({:foo => "bar", :env => { :bang => "baz" }}, @config.add_default_command_options(:foo => "bar"))
|
2007-05-31 22:56:42 -04:00
|
|
|
end
|
|
|
|
|
2007-06-05 12:10:01 -04:00
|
|
|
def test_add_default_command_options_should_merge_env_with_default_environment
|
2007-05-31 22:56:42 -04:00
|
|
|
@config[:default_environment][:bang] = "baz"
|
|
|
|
@config[:default_environment][:bacon] = "crunchy"
|
2007-06-05 12:10:01 -04:00
|
|
|
assert_equal({:foo => "bar", :env => { :bang => "baz", :bacon => "chunky", :flip => "flop" }}, @config.add_default_command_options(:foo => "bar", :env => {:bacon => "chunky", :flip => "flop"}))
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_add_default_command_options_should_use_default_shell_if_present
|
|
|
|
@config.set :default_shell, "/bin/bash"
|
|
|
|
assert_equal({:foo => "bar", :shell => "/bin/bash"}, @config.add_default_command_options(:foo => "bar"))
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_add_default_command_options_should_use_shell_in_preference_of_default_shell
|
|
|
|
@config.set :default_shell, "/bin/bash"
|
|
|
|
assert_equal({:foo => "bar", :shell => "/bin/sh"}, @config.add_default_command_options(:foo => "bar", :shell => "/bin/sh"))
|
2007-05-31 22:56:42 -04:00
|
|
|
end
|
|
|
|
|
2007-03-02 12:15:11 -05:00
|
|
|
def test_default_io_proc_should_log_stdout_arguments_as_info
|
|
|
|
ch = { :host => "capistrano",
|
2007-05-09 00:45:54 -04:00
|
|
|
:server => server("capistrano"),
|
2007-03-02 12:15:11 -05:00
|
|
|
:options => { :logger => mock("logger") } }
|
|
|
|
ch[:options][:logger].expects(:info).with("data stuff", "out :: capistrano")
|
|
|
|
MockConfig.default_io_proc[ch, :out, "data stuff"]
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_default_io_proc_should_log_stderr_arguments_as_important
|
|
|
|
ch = { :host => "capistrano",
|
2007-05-09 00:45:54 -04:00
|
|
|
:server => server("capistrano"),
|
2007-03-02 12:15:11 -05:00
|
|
|
:options => { :logger => mock("logger") } }
|
|
|
|
ch[:options][:logger].expects(:important).with("data stuff", "err :: capistrano")
|
|
|
|
MockConfig.default_io_proc[ch, :err, "data stuff"]
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_sudo_should_default_to_sudo
|
2007-09-01 10:56:00 -04:00
|
|
|
@config.expects(:run).with("sudo -p 'sudo password: ' ls", {})
|
2007-03-02 12:15:11 -05:00
|
|
|
@config.sudo "ls"
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_sudo_should_use_sudo_variable_definition
|
2007-09-01 10:56:00 -04:00
|
|
|
@config.expects(:run).with("/opt/local/bin/sudo -p 'sudo password: ' ls", {})
|
2007-03-02 12:15:11 -05:00
|
|
|
@config.options[:sudo] = "/opt/local/bin/sudo"
|
|
|
|
@config.sudo "ls"
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_sudo_should_interpret_as_option_as_user
|
2007-09-01 10:56:00 -04:00
|
|
|
@config.expects(:run).with("sudo -p 'sudo password: ' -u app ls", {})
|
2007-03-02 12:15:11 -05:00
|
|
|
@config.sudo "ls", :as => "app"
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_sudo_should_pass_options_through_to_run
|
2007-09-01 10:56:00 -04:00
|
|
|
@config.expects(:run).with("sudo -p 'sudo password: ' ls", :foo => "bar")
|
2007-03-02 12:15:11 -05:00
|
|
|
@config.sudo "ls", :foo => "bar"
|
|
|
|
end
|
|
|
|
|
2007-09-01 10:56:00 -04:00
|
|
|
def test_sudo_should_interpret_sudo_prompt_variable_as_custom_prompt
|
|
|
|
@config.set :sudo_prompt, "give it to me: "
|
|
|
|
@config.expects(:run).with("sudo -p 'give it to me: ' ls", {})
|
|
|
|
@config.sudo "ls"
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_sudo_behavior_callback_should_send_password_when_prompted_with_default_sudo_prompt
|
2007-03-02 12:15:11 -05:00
|
|
|
ch = mock("channel")
|
|
|
|
ch.expects(:send_data).with("g00b3r\n")
|
|
|
|
@config.options[:password] = "g00b3r"
|
2007-09-01 10:56:00 -04:00
|
|
|
@config.sudo_behavior_callback(nil)[ch, nil, "sudo password: "]
|
2007-03-02 12:15:11 -05:00
|
|
|
end
|
|
|
|
|
2007-09-01 10:56:00 -04:00
|
|
|
def test_sudo_behavior_callback_should_send_password_when_prompted_with_custom_sudo_prompt
|
2007-04-05 01:19:54 -04:00
|
|
|
ch = mock("channel")
|
|
|
|
ch.expects(:send_data).with("g00b3r\n")
|
2007-09-01 10:56:00 -04:00
|
|
|
@config.set :sudo_prompt, "give it to me: "
|
2007-04-05 01:19:54 -04:00
|
|
|
@config.options[:password] = "g00b3r"
|
2007-09-01 10:56:00 -04:00
|
|
|
@config.sudo_behavior_callback(nil)[ch, nil, "give it to me: "]
|
2007-04-05 01:19:54 -04:00
|
|
|
end
|
|
|
|
|
2007-03-02 12:15:11 -05:00
|
|
|
def test_sudo_behavior_callback_with_incorrect_password_on_first_prompt
|
|
|
|
ch = mock("channel")
|
|
|
|
ch.stubs(:[]).with(:host).returns("capistrano")
|
2007-05-09 00:45:54 -04:00
|
|
|
ch.stubs(:[]).with(:server).returns(server("capistrano"))
|
2007-03-02 12:15:11 -05:00
|
|
|
@config.expects(:reset!).with(:password)
|
|
|
|
@config.sudo_behavior_callback(nil)[ch, nil, "blah blah try again blah blah"]
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_sudo_behavior_callback_with_incorrect_password_on_subsequent_prompts
|
|
|
|
callback = @config.sudo_behavior_callback(nil)
|
|
|
|
|
|
|
|
ch = mock("channel")
|
|
|
|
ch.stubs(:[]).with(:host).returns("capistrano")
|
2007-05-09 00:45:54 -04:00
|
|
|
ch.stubs(:[]).with(:server).returns(server("capistrano"))
|
2007-03-02 12:15:11 -05:00
|
|
|
ch2 = mock("channel")
|
|
|
|
ch2.stubs(:[]).with(:host).returns("cap2")
|
2007-05-09 00:45:54 -04:00
|
|
|
ch2.stubs(:[]).with(:server).returns(server("cap2"))
|
2007-03-02 12:15:11 -05:00
|
|
|
|
|
|
|
@config.expects(:reset!).with(:password).times(2)
|
|
|
|
|
|
|
|
callback[ch, nil, "blah blah try again blah blah"]
|
|
|
|
callback[ch2, nil, "blah blah try again blah blah"] # shouldn't call reset!
|
|
|
|
callback[ch, nil, "blah blah try again blah blah"]
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_sudo_behavior_callback_should_defer_to_fallback_for_other_output
|
|
|
|
callback = @config.sudo_behavior_callback(inspectable_proc)
|
|
|
|
|
|
|
|
a = mock("channel", :called => true)
|
|
|
|
b = mock("stream", :called => true)
|
|
|
|
c = mock("data", :called => true)
|
|
|
|
|
|
|
|
callback[a, b, c]
|
|
|
|
end
|
|
|
|
|
2007-03-04 13:19:26 -05:00
|
|
|
def test_invoke_command_should_default_to_run
|
2007-03-02 16:33:27 -05:00
|
|
|
@config.expects(:run).with("ls", :once => true)
|
2007-03-04 13:19:26 -05:00
|
|
|
@config.invoke_command("ls", :once => true)
|
2007-03-02 16:33:27 -05:00
|
|
|
end
|
|
|
|
|
2007-03-04 13:19:26 -05:00
|
|
|
def test_invoke_command_should_delegate_to_method_identified_by_via
|
2007-03-02 16:33:27 -05:00
|
|
|
@config.expects(:foobar).with("ls", :once => true)
|
2007-03-04 13:19:26 -05:00
|
|
|
@config.invoke_command("ls", :once => true, :via => :foobar)
|
2007-03-02 16:33:27 -05:00
|
|
|
end
|
|
|
|
|
2007-03-02 12:15:11 -05:00
|
|
|
private
|
|
|
|
|
|
|
|
def inspectable_proc
|
|
|
|
Proc.new do |ch, stream, data|
|
|
|
|
ch.called
|
|
|
|
stream.called
|
|
|
|
data.called
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def prepare_command(command, sessions, options)
|
|
|
|
a = mock("channel", :called => true)
|
|
|
|
b = mock("stream", :called => true)
|
|
|
|
c = mock("data", :called => true)
|
|
|
|
Capistrano::Command.expects(:process).with(command, sessions, options).yields(a, b, c)
|
|
|
|
end
|
|
|
|
end
|