require 'common' require 'net/ssh/multi/session' class SessionTest < Minitest::Test def setup @session = Net::SSH::Multi::Session.new end def test_group_should_fail_when_given_both_mapping_and_block assert_raises(ArgumentError) do @session.group(:app => mock('server')) { |s| } end end def test_group_with_block_should_use_groups_within_block_and_restore_on_exit @session.open_groups.concat([:first, :second]) assert_equal [:first, :second], @session.open_groups yielded = nil @session.group(:third, :fourth) do |s| yielded = s assert_equal [:first, :second, :third, :fourth], @session.open_groups end assert_equal [:first, :second], @session.open_groups assert_equal @session, yielded end def test_group_with_mapping_should_append_new_servers_to_specified_and_open_groups s1, s2, s3, s4 = @session.use('h1', 'h2', 'h3', 'h4') @session.group :second => s1 @session.open_groups.concat([:first, :second]) @session.group %w(third fourth) => [s2, s3], :fifth => s1, :sixth => [s4] assert_equal [s1, s2, s3, s4], @session.groups[:first].sort assert_equal [s1, s2, s3, s4], @session.groups[:second].sort assert_equal [s2, s3], @session.groups[:third].sort assert_equal [s2, s3], @session.groups[:fourth].sort assert_equal [s1], @session.groups[:fifth].sort assert_equal [s4], @session.groups[:sixth].sort end def test_via_should_instantiate_and_set_default_gateway Net::SSH::Gateway.expects(:new).with('host', 'user', :a => :b).returns(:gateway) assert_equal @session, @session.via('host', 'user', :a => :b) assert_equal :gateway, @session.default_gateway end def test_use_should_add_new_server_to_server_list @session.open_groups.concat([:first, :second]) server = @session.use('user@host', :a => :b) assert_equal [server], @session.servers assert_equal 'host', server.host assert_equal 'user', server.user assert_equal({:a => :b}, server.options) assert_nil server.gateway end def test_use_with_open_groups_should_add_new_server_to_server_list_and_groups @session.open_groups.concat([:first, :second]) server = @session.use('host') assert_equal [server], @session.groups[:first].sort assert_equal [server], @session.groups[:second].sort end def test_use_with_default_gateway_should_set_gateway_on_server Net::SSH::Gateway.expects(:new).with('host', 'user', {}).returns(:gateway) @session.via('host', 'user') server = @session.use('host2') assert_equal :gateway, server.gateway end def test_use_with_duplicate_server_will_not_add_server_twice s1, s2 = @session.use('host', 'host') assert_equal 1, @session.servers.length assert_equal s1.object_id, s2.object_id end def test_with_should_yield_new_subsession_with_servers_for_criteria yielded = nil @session.expects(:servers_for).with(:app, :web).returns([:servers]) result = @session.with(:app, :web) do |s| yielded = s end assert_equal result, yielded assert_equal [:servers], yielded.servers end def test_servers_for_with_unknown_constraint_should_raise_error assert_raises(ArgumentError) do @session.servers_for(:app => { :all => :foo }) end end def test_with_with_constraints_should_build_subsession_with_matching_servers conditions = { :app => { :only => { :primary => true }, :except => { :backup => true } } } @session.expects(:servers_for).with(conditions).returns([:servers]) assert_equal [:servers], @session.with(conditions).servers end def test_on_should_return_subsession_containing_only_the_given_servers s1, s2 = @session.use('h1', 'h2') subsession = @session.on(s1, s2) assert_equal [s1, s2], subsession.servers end def test_on_should_yield_subsession_if_block_is_given s1 = @session.use('h1') yielded = nil result = @session.on(s1) do |s| yielded = s assert_equal [s1], s.servers end assert_equal result, yielded end def test_servers_for_should_return_all_servers_if_no_arguments srv1, srv2, srv3 = @session.use('h1', 'h2', 'h3') assert_equal [srv1, srv2, srv3], @session.servers_for.sort end def test_servers_for_should_return_servers_only_for_given_group srv1, srv2, srv3 = @session.use('h1', 'h2', 'h3') @session.group :app => [srv1, srv2], :db => [srv3] assert_equal [srv1, srv2], @session.servers_for(:app).sort end def test_servers_for_should_not_return_duplicate_servers srv1, srv2, srv3 = @session.use('h1', 'h2', 'h3') @session.group :app => [srv1, srv2], :db => [srv2, srv3] assert_equal [srv1, srv2, srv3], @session.servers_for(:app, :db).sort end def test_servers_for_should_correctly_apply_only_and_except_constraints srv1, srv2, srv3 = @session.use('h1', :properties => {:a => 1}), @session.use('h2', :properties => {:a => 1, :b => 2}), @session.use('h3') @session.group :app => [srv1, srv2, srv3] assert_equal [srv1], @session.servers_for(:app => {:only => {:a => 1}, :except => {:b => 2}}) end def test_close_should_close_server_sessions srv1, srv2 = @session.use('h1', 'h2') srv1.expects(:close_channels) srv2.expects(:close_channels) srv1.expects(:close) srv2.expects(:close) @session.close end def test_close_should_shutdown_default_gateway gateway = mock('gateway') gateway.expects(:shutdown!) Net::SSH::Gateway.expects(:new).returns(gateway) @session.via('host', 'user') @session.close end def test_loop_should_loop_until_process_is_false @session.expects(:process).with(5).times(4).returns(true,true,true,false).yields yielded = false @session.loop(5) { yielded = true } assert yielded end def test_preprocess_should_immediately_return_false_if_block_returns_false srv = @session.use('h1') srv.expects(:preprocess).never assert_equal false, @session.preprocess { false } end def test_preprocess_should_call_preprocess_on_component_servers srv = @session.use('h1') srv.expects(:preprocess) assert_equal :hello, @session.preprocess { :hello } end def test_preprocess_should_succeed_even_without_block srv = @session.use('h1') srv.expects(:preprocess) assert_equal true, @session.preprocess end def test_postprocess_should_call_postprocess_on_component_servers srv = @session.use('h1') srv.expects(:postprocess).with([:a], [:b]) assert_equal true, @session.postprocess([:a], [:b]) end def test_process_should_return_false_if_preprocess_returns_false assert_equal false, @session.process { false } end def test_process_should_call_select_on_combined_readers_and_writers_from_all_servers @session.expects(:postprocess).with([:b, :c], [:a, :c]) srv1, srv2, srv3 = @session.use('h1', 'h2', 'h3') srv1.expects(:readers).returns([:a]) srv1.expects(:writers).returns([:a]) srv2.expects(:readers).returns([]) srv2.expects(:writers).returns([]) srv3.expects(:readers).returns([:b, :c]) srv3.expects(:writers).returns([:c]) IO.expects(:select).with([:a, :b, :c], [:a, :c], nil, 5).returns([[:b, :c], [:a, :c]]) @session.process(5) end def test_process_should_pass_minimum_keepalive_interval_as_io_select_timeout @session.use('h1', :keepalive => true) @session.use('h2', :keepalive_interval => 1) @session.use('h3', :keepalive => true, :keepalive_interval => 2) @session.use('h4', :keepalive => true, :keepalive_interval => 3) IO.expects(:select).with([], [], nil, 2) @session.process end def test_process_should_pass_wait_as_io_select_timeout_if_provided_and_minimum @session.use('h1', :keepalive => true, :keepalive_interval => 1) IO.expects(:select).with([], [], nil, 1) @session.process(2) end def test_process_should_pass_nil_as_io_select_timeout_by_default @session.use('h1') IO.expects(:select).with([], [], nil, nil) @session.process end end