summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2008-03-29 22:56:05 -0600
committerJamis Buck <jamis@37signals.com>2008-03-29 22:56:05 -0600
commit2ea62eb4cd9dbc82f8f24536d44318f55962998d (patch)
treefe4e6736793104c992e616bc3ac9db405adc304d
parent7f67b8f7e27d72073277b5cd2120631929ca39e7 (diff)
downloadnet-ssh-multi-2ea62eb4cd9dbc82f8f24536d44318f55962998d.tar.gz
first pass at tests
-rw-r--r--lib/net/ssh/multi/channel.rb4
-rw-r--r--test/channel_test.rb161
-rw-r--r--test/common.rb2
-rw-r--r--test/multi_test.rb20
-rw-r--r--test/server_test.rb229
-rw-r--r--test/test_all.rb3
6 files changed, 417 insertions, 2 deletions
diff --git a/lib/net/ssh/multi/channel.rb b/lib/net/ssh/multi/channel.rb
index c82ded1..8d33fa3 100644
--- a/lib/net/ssh/multi/channel.rb
+++ b/lib/net/ssh/multi/channel.rb
@@ -17,11 +17,11 @@ module Net; module SSH; module Multi
end
def [](key)
- @properties[key.to_sym]
+ @properties[key]
end
def []=(key, value)
- @properties[key.to_sym] = value
+ @properties[key] = value
end
def exec(command, &block)
diff --git a/test/channel_test.rb b/test/channel_test.rb
new file mode 100644
index 0000000..c271361
--- /dev/null
+++ b/test/channel_test.rb
@@ -0,0 +1,161 @@
+require 'common'
+require 'net/ssh/multi/channel'
+
+class ChannelTest < Test::Unit::TestCase
+ def test_each_should_iterate_over_each_component_channel
+ channels = [c1 = mock('channel'), c2 = mock('channel'), c3 = mock('channel')]
+ channel = Net::SSH::Multi::Channel.new(mock('session'), channels)
+ result = []
+ channel.each { |c| result << c }
+ assert_equal channels, result
+ end
+
+ def test_property_accessors
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [])
+ channel[:foo] = "hello"
+ assert_equal "hello", channel[:foo]
+ channel['bar'] = "goodbye"
+ assert_equal "goodbye", channel['bar']
+ assert_nil channel[:bar]
+ assert_nil channel['foo']
+ end
+
+ def test_exec_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:exec).with('ls -l').yields(c1)
+ c2.expects(:exec).with('ls -l').yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.exec('ls -l') { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_subsystem_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:subsystem).with('sftp').yields(c1)
+ c2.expects(:subsystem).with('sftp').yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.subsystem('sftp') { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_request_pty_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:request_pty).with(:foo => 5).yields(c1)
+ c2.expects(:request_pty).with(:foo => 5).yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.request_pty(:foo => 5) { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_send_data_should_delegate_to_component_channels
+ c1, c2 = mock('channel'), mock('channel')
+ c1.expects(:send_data).with("hello\n")
+ c2.expects(:send_data).with("hello\n")
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.send_data("hello\n")
+ end
+
+ def test_active_should_be_true_if_all_component_channels_are_active
+ c1, c2, c3 = stub('channel', :active? => true), stub('channel', :active? => true), stub('channel', :active? => true)
+ channel = Net::SSH::Multi::Channel.new(stub('session'), [c1, c2, c3])
+ assert channel.active?
+ end
+
+ def test_active_should_be_true_if_any_component_channels_are_active
+ c1, c2, c3 = stub('channel', :active? => true), stub('channel', :active? => false), stub('channel', :active? => false)
+ channel = Net::SSH::Multi::Channel.new(stub('session'), [c1, c2, c3])
+ assert channel.active?
+ end
+
+ def test_active_should_be_false_if_no_component_channels_are_active
+ c1, c2, c3 = stub('channel', :active? => false), stub('channel', :active? => false), stub('channel', :active? => false)
+ channel = Net::SSH::Multi::Channel.new(stub('session'), [c1, c2, c3])
+ assert !channel.active?
+ end
+
+ def test_wait_should_block_until_active_is_false
+ channel = Net::SSH::Multi::Channel.new(MockSession.new, [])
+ channel.expects(:active?).times(4).returns(true,true,true,false)
+ assert_equal channel, channel.wait
+ end
+
+ def test_close_should_delegate_to_component_channels
+ c1, c2 = mock('channel'), mock('channel')
+ c1.expects(:close)
+ c2.expects(:close)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.close
+ end
+
+ def test_eof_bang_should_delegate_to_component_channels
+ c1, c2 = mock('channel'), mock('channel')
+ c1.expects(:eof!)
+ c2.expects(:eof!)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.eof!
+ end
+
+ def test_on_data_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:on_data).yields(c1)
+ c2.expects(:on_data).yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.on_data { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_on_extended_data_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:on_extended_data).yields(c1)
+ c2.expects(:on_extended_data).yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.on_extended_data { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_on_process_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:on_process).yields(c1)
+ c2.expects(:on_process).yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.on_process { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_on_close_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:on_close).yields(c1)
+ c2.expects(:on_close).yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.on_close { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_on_eof_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:on_eof).yields(c1)
+ c2.expects(:on_eof).yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.on_eof { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ def test_on_request_should_delegate_to_component_channels
+ c1, c2, results = mock('channel'), mock('channel'), []
+ c1.expects(:on_request).with("exit-status").yields(c1)
+ c2.expects(:on_request).with("exit-status").yields(c2)
+ channel = Net::SSH::Multi::Channel.new(mock('session'), [c1, c2])
+ assert_equal channel, channel.on_request("exit-status") { |c| results << c }
+ assert_equal [c1, c2], results
+ end
+
+ private
+
+ class MockSession
+ def loop
+ while true do
+ return if !yield(self)
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/test/common.rb b/test/common.rb
new file mode 100644
index 0000000..dd4f074
--- /dev/null
+++ b/test/common.rb
@@ -0,0 +1,2 @@
+require 'test/unit'
+require 'mocha' \ No newline at end of file
diff --git a/test/multi_test.rb b/test/multi_test.rb
new file mode 100644
index 0000000..0a5d5bb
--- /dev/null
+++ b/test/multi_test.rb
@@ -0,0 +1,20 @@
+require 'common'
+require 'net/ssh/multi'
+
+class MultiTest < Test::Unit::TestCase
+ def test_start_with_block_should_yield_session_and_then_close
+ Net::SSH::Multi::Session.any_instance.expects(:loop)
+ Net::SSH::Multi::Session.any_instance.expects(:close)
+ yielded = false
+ Net::SSH::Multi.start do |session|
+ yielded = true
+ assert_instance_of Net::SSH::Multi::Session, session
+ end
+ end
+
+ def test_start_without_block_should_return_open_session
+ Net::SSH::Multi::Session.any_instance.expects(:loop).never
+ Net::SSH::Multi::Session.any_instance.expects(:close).never
+ assert_instance_of Net::SSH::Multi::Session, Net::SSH::Multi.start
+ end
+end \ No newline at end of file
diff --git a/test/server_test.rb b/test/server_test.rb
new file mode 100644
index 0000000..b89066f
--- /dev/null
+++ b/test/server_test.rb
@@ -0,0 +1,229 @@
+require 'common'
+require 'net/ssh/multi/server'
+
+class ServerTest < Test::Unit::TestCase
+ def test_accessor_without_properties_should_access_empty_hash
+ assert_nil server('host', 'user')[:foo]
+ end
+
+ def test_accessor_with_properties_should_access_properties
+ assert_equal "hello", server('host', 'user', :properties => { :foo => "hello" })[:foo]
+ end
+
+ def test_port_should_return_22_by_default
+ assert_equal 22, server('host', 'user').port
+ end
+
+ def test_port_should_return_given_port_when_present
+ assert_equal 1234, server('host', 'user', :port => 1234).port
+ end
+
+ def test_equivalence_when_host_and_user_and_port_match
+ s1 = server('host', 'user', :port => 1234)
+ s2 = server('host', 'user', :port => 1234)
+ assert s1.eql?(s2)
+ assert_equal s1.hash, s2.hash
+ assert s1 == s2
+ end
+
+ def test_equivalence_when_host_mismatch
+ s1 = server('host1', 'user', :port => 1234)
+ s2 = server('host2', 'user', :port => 1234)
+ assert !s1.eql?(s2)
+ assert_not_equal s1.hash, s2.hash
+ assert s1 != s2
+ end
+
+ def test_equivalence_when_port_mismatch
+ s1 = server('host', 'user', :port => 1234)
+ s2 = server('host', 'user', :port => 1235)
+ assert !s1.eql?(s2)
+ assert_not_equal s1.hash, s2.hash
+ assert s1 != s2
+ end
+
+ def test_equivalence_when_user_mismatch
+ s1 = server('host', 'user1', :port => 1234)
+ s2 = server('host', 'user2', :port => 1234)
+ assert !s1.eql?(s2)
+ assert_not_equal s1.hash, s2.hash
+ assert s1 != s2
+ end
+
+ def test_to_s_should_include_user_and_host
+ assert_equal "user@host", server('host', 'user').to_s
+ end
+
+ def test_to_s_should_include_user_and_host_and_port_when_port_is_given
+ assert_equal "user@host:1234", server('host', 'user', :port => 1234).to_s
+ end
+
+ def test_gateway_should_be_nil_by_default
+ assert_nil server('host', 'user').gateway
+ end
+
+ def test_gateway_should_be_set_with_the_via_value
+ gateway = mock('gateway')
+ assert_equal gateway, server('host', 'user', :via => gateway).gateway
+ end
+
+ def test_session_with_default_argument_should_not_instantiate_session
+ assert_nil server('host', 'user').session
+ end
+
+ def test_session_with_true_argument_should_instantiate_and_cache_session
+ session = {}
+ srv = server('host', 'user', :port => 1234)
+ Net::SSH.expects(:start).with('host', 'user', {:port => 1234}).once.returns(session)
+ assert_equal session, srv.session(true)
+ assert_equal session, srv.session(true)
+ assert_equal session, srv.session
+ end
+
+ def test_session_via_gateway_with_true_argument_should_instantiate_and_cache_session
+ session = {}
+ gateway = mock('gateway')
+ srv = server('host', 'user', :port => 1234, :via => gateway)
+ gateway.expects(:ssh).with('host', 'user', {:port => 1234}).once.returns(session)
+ assert_equal session, srv.session(true)
+ assert_equal session, srv.session(true)
+ assert_equal session, srv.session
+ end
+
+ def test_session_that_cannot_authenticate_adds_host_to_exception_message
+ srv = server('host', 'user')
+ Net::SSH.expects(:start).raises(Net::SSH::AuthenticationFailed.new('user'))
+
+ begin
+ srv.session(true)
+ flunk
+ rescue Net::SSH::AuthenticationFailed => e
+ assert_equal "user@host", e.message
+ end
+ end
+
+ def test_close_channels_when_session_is_not_open_should_not_do_anything
+ assert_nothing_raised { server('host', 'user').close_channels }
+ end
+
+ def test_close_channels_when_session_is_open_should_iterate_over_open_channels_and_close_them
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ c1 = mock('channel', :close => nil)
+ c2 = mock('channel', :close => nil)
+ c3 = mock('channel', :close => nil)
+ session.expects(:channels).returns(1 => c1, 2 => c2, 3 => c3)
+ assert_equal session, srv.session(true)
+ srv.close_channels
+ end
+
+ def test_close_when_session_is_not_open_should_not_do_anything
+ assert_nothing_raised { server('host', 'user').close }
+ end
+
+ def test_close_when_session_is_open_should_close_transport_layer
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ session.expects(:transport).returns(mock('transport', :close => nil))
+ assert_equal session, srv.session(true)
+ srv.close
+ end
+
+ def test_busy_should_be_false_when_session_is_not_open
+ assert !server('host', 'user').busy?
+ end
+
+ def test_busy_should_be_false_when_session_is_not_busy
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ session.expects(:busy?).returns(false)
+ srv.session(true)
+ assert !srv.busy?
+ end
+
+ def test_busy_should_be_true_when_session_is_busy
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ session.expects(:busy?).returns(true)
+ srv.session(true)
+ assert srv.busy?
+ end
+
+ def test_preprocess_should_be_true_when_session_is_not_open
+ assert_equal true, server('host', 'user').preprocess
+ end
+
+ def test_preprocess_should_return_result_of_session_preprocess
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ session.expects(:preprocess).returns(:result).yields(session)
+ called = nil
+ srv.session(true)
+ assert_equal :result, srv.preprocess { |s| called = s }
+ assert_equal session, called
+ end
+
+ def test_readers_should_return_empty_array_when_session_is_not_open
+ assert_equal [], server('host', 'user').readers
+ end
+
+ def test_readers_should_return_all_listeners_when_session_is_open
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ session.expects(:listeners).returns(1 => 2, 3 => 4, 5 => 6, 7 => 8)
+ srv.session(true)
+ assert_equal [1, 3, 5, 7], srv.readers.sort
+ end
+
+ def test_writers_should_return_empty_array_when_session_is_not_open
+ assert_equal [], server('host', 'user').writers
+ end
+
+ def test_writers_should_return_all_listeners_that_are_pending_writes_when_session_is_open
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ listeners = { writer(:ready) => 1, writer(:reader) => 2,
+ writer(:reader) => 3, writer(:idle) => 4, writer(:ready) => 5 }
+ session.expects(:listeners).returns(listeners)
+ srv.session(true)
+ assert_equal 2, srv.writers.length
+ end
+
+ def test_postprocess_should_return_true_when_session_is_not_open
+ assert_equal true, server('host', 'user').postprocess([], [])
+ end
+
+ def test_postprocess_should_call_session_postprocess_with_ios_belonging_to_session
+ srv = server('host', 'user')
+ session = {}
+ Net::SSH.expects(:start).returns(session)
+ session.expects(:listeners).returns(1 => 2, 3 => 4, 5 => 6, 7 => 8)
+ session.expects(:postprocess).with([1,3], [7]).returns(:result)
+ srv.session(true)
+ assert_equal :result, srv.postprocess([1,11,3], [18,14,7,12])
+ end
+
+ private
+
+ def server(host, user, options={})
+ Net::SSH::Multi::Server.new(host, user, options)
+ end
+
+ def writer(mode)
+ case mode
+ when :ready then
+ stub('io', :pending_write? => true)
+ when :idle then
+ stub('io', :pending_write? => false)
+ else
+ stub('io')
+ end
+ end
+end \ No newline at end of file
diff --git a/test/test_all.rb b/test/test_all.rb
new file mode 100644
index 0000000..c8b4e29
--- /dev/null
+++ b/test/test_all.rb
@@ -0,0 +1,3 @@
+Dir["#{File.dirname(__FILE__)}/**/*_test.rb"].each do |file|
+ load(file)
+end \ No newline at end of file