1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
|
require 'common'
require 'net/ssh/transport/session'
# mocha adds #verify to Object, which throws off the host-key-verifier part of
# these tests.
# can't use .include? because ruby18 uses strings and ruby19 uses symbols :/
if Object.instance_methods.any? { |v| v.to_sym == :verify }
Object.send(:undef_method, :verify)
end
module Transport
class TestSession < Test::Unit::TestCase
include Net::SSH::Transport::Constants
def test_constructor_defaults
assert_equal "net.ssh.test", session.host
assert_equal 22, session.port
assert_instance_of Net::SSH::Verifiers::Lenient, session.host_key_verifier
end
def test_paranoid_true_uses_lenient_verifier
assert_instance_of Net::SSH::Verifiers::Lenient, session(:paranoid => true).host_key_verifier
end
def test_paranoid_very_uses_strict_verifier
assert_instance_of Net::SSH::Verifiers::Strict, session(:paranoid => :very).host_key_verifier
end
def test_paranoid_secure_uses_secure_verifier
assert_instance_of Net::SSH::Verifiers::Secure, session(:paranoid => :secure).host_key_verifier
end
def test_paranoid_false_uses_null_verifier
assert_instance_of Net::SSH::Verifiers::Null, session(:paranoid => false).host_key_verifier
end
def test_unknown_paranoid_value_raises_exception_if_value_does_not_respond_to_verify
assert_raises(ArgumentError) { session(:paranoid => :bogus).host_key_verifier }
end
def test_paranoid_value_responding_to_verify_should_pass_muster
object = stub("thingy", :verify => true)
assert_equal object, session(:paranoid => object).host_key_verifier
end
def test_host_as_string_should_return_host_and_ip_when_port_is_default
session!
socket.stubs(:peer_ip).returns("1.2.3.4")
assert_equal "net.ssh.test,1.2.3.4", session.host_as_string
end
def test_host_as_string_should_return_host_and_ip_with_port_when_port_is_not_default
session(:port => 1234) # force session to be instantiated
socket.stubs(:peer_ip).returns("1.2.3.4")
assert_equal "[net.ssh.test]:1234,[1.2.3.4]:1234", session.host_as_string
end
def test_host_as_string_should_return_only_host_when_host_is_ip
session!(:host => "1.2.3.4")
socket.stubs(:peer_ip).returns("1.2.3.4")
assert_equal "1.2.3.4", session.host_as_string
end
def test_host_as_string_should_return_only_host_and_port_when_host_is_ip_and_port_is_not_default
session!(:host => "1.2.3.4", :port => 1234)
socket.stubs(:peer_ip).returns("1.2.3.4")
assert_equal "[1.2.3.4]:1234", session.host_as_string
end
def test_close_should_cleanup_and_close_socket
session!
socket.expects(:cleanup)
socket.expects(:close)
session.close
end
def test_service_request_should_return_buffer
assert_equal "\005\000\000\000\004sftp", session.service_request('sftp').to_s
end
def test_rekey_when_kex_is_pending_should_do_nothing
algorithms.stubs(:pending? => true)
algorithms.expects(:rekey!).never
session.rekey!
end
def test_rekey_when_no_kex_is_pending_should_initiate_rekey_and_block_until_it_completes
algorithms.stubs(:pending? => false)
algorithms.expects(:rekey!)
session.expects(:wait).yields
algorithms.expects(:initialized?).returns(true)
session.rekey!
end
def test_rekey_as_needed_when_kex_is_pending_should_do_nothing
session!
algorithms.stubs(:pending? => true)
socket.expects(:if_needs_rekey?).never
session.rekey_as_needed
end
def test_rekey_as_needed_when_no_kex_is_pending_and_no_rekey_is_needed_should_do_nothing
session!
algorithms.stubs(:pending? => false)
socket.stubs(:if_needs_rekey? => false)
session.expects(:rekey!).never
session.rekey_as_needed
end
def test_rekey_as_needed_when_no_kex_is_pending_and_rekey_is_needed_should_initiate_rekey_and_block
session!
algorithms.stubs(:pending? => false)
socket.expects(:if_needs_rekey?).yields
session.expects(:rekey!)
session.rekey_as_needed
end
def test_peer_should_return_hash_of_info_about_peer
session!
socket.stubs(:peer_ip => "1.2.3.4")
assert_equal({:ip => "1.2.3.4", :port => 22, :host => "net.ssh.test", :canonized => "net.ssh.test,1.2.3.4"}, session.peer)
end
def test_next_message_should_block_until_next_message_is_available
session.expects(:poll_message).with(:block)
session.next_message
end
def test_poll_message_should_query_next_packet_using_the_given_blocking_parameter
session!
socket.expects(:next_packet).with(:blocking_parameter).returns(nil)
session.poll_message(:blocking_parameter)
end
def test_poll_message_should_default_to_non_blocking
session!
socket.expects(:next_packet).with(:nonblock).returns(nil)
session.poll_message
end
def test_poll_message_should_silently_handle_disconnect_packets
session!
socket.expects(:next_packet).returns(P(:byte, DISCONNECT, :long, 1, :string, "testing", :string, ""))
assert_raises(Net::SSH::Disconnect) { session.poll_message }
end
def test_poll_message_should_silently_handle_ignore_packets
session!
socket.expects(:next_packet).times(2).returns(P(:byte, IGNORE, :string, "test"), nil)
assert_nil session.poll_message
end
def test_poll_message_should_silently_handle_unimplemented_packets
session!
socket.expects(:next_packet).times(2).returns(P(:byte, UNIMPLEMENTED, :long, 15), nil)
assert_nil session.poll_message
end
def test_poll_message_should_silently_handle_debug_packets_with_always_display
session!
socket.expects(:next_packet).times(2).returns(P(:byte, DEBUG, :bool, true, :string, "testing", :string, ""), nil)
assert_nil session.poll_message
end
def test_poll_message_should_silently_handle_debug_packets_without_always_display
session!
socket.expects(:next_packet).times(2).returns(P(:byte, DEBUG, :bool, false, :string, "testing", :string, ""), nil)
assert_nil session.poll_message
end
def test_poll_message_should_silently_handle_kexinit_packets
session!
packet = P(:byte, KEXINIT, :raw, "lasdfalksdjfa;slkdfja;slkfjsdfaklsjdfa;df")
socket.expects(:next_packet).times(2).returns(packet, nil)
algorithms.expects(:accept_kexinit).with(packet)
assert_nil session.poll_message
end
def test_poll_message_should_return_other_packets
session!
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
socket.expects(:next_packet).returns(packet)
assert_equal packet, session.poll_message
end
def test_poll_message_should_enqueue_packets_when_algorithm_disallows_packet
session!
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
algorithms.stubs(:allow?).with(packet).returns(false)
socket.expects(:next_packet).times(2).returns(packet, nil)
assert_nil session.poll_message
assert_equal [packet], session.queue
end
def test_poll_message_should_read_from_queue_when_next_in_queue_is_allowed_and_consume_queue_is_true
session!
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
session.push(packet)
socket.expects(:next_packet).never
assert_equal packet, session.poll_message
assert session.queue.empty?
end
def test_poll_message_should_not_read_from_queue_when_next_in_queue_is_not_allowed
session!
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
algorithms.stubs(:allow?).with(packet).returns(false)
session.push(packet)
socket.expects(:next_packet).returns(nil)
assert_nil session.poll_message
assert_equal [packet], session.queue
end
def test_poll_message_should_not_read_from_queue_when_consume_queue_is_false
session!
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
session.push(packet)
socket.expects(:next_packet).returns(nil)
assert_nil session.poll_message(:nonblock, false)
assert_equal [packet], session.queue
end
def test_wait_with_block_should_return_immediately_if_block_returns_truth
session.expects(:poll_message).never
session.wait { true }
end
def test_wait_should_not_consume_queue_on_reads
n = 0
session.expects(:poll_message).with(:nonblock, false).returns(nil)
session.wait { (n += 1) > 1 }
end
def test_wait_without_block_should_return_after_first_read
session.expects(:poll_message).returns(nil)
session.wait
end
def test_wait_should_enqueue_packets
session!
p1 = P(:byte, SERVICE_REQUEST, :string, "test")
p2 = P(:byte, SERVICE_ACCEPT, :string, "test")
socket.expects(:next_packet).times(2).returns(p1, p2)
n = 0
session.wait { (n += 1) > 2 }
assert_equal [p1, p2], session.queue
end
def test_push_should_enqueue_packet
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
session.push(packet)
assert_equal [packet], session.queue
end
def test_send_message_should_delegate_to_socket
session!
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
socket.expects(:send_packet).with(packet)
session.send_message(packet)
end
def test_enqueue_message_should_delegate_to_socket
session!
packet = P(:byte, SERVICE_ACCEPT, :string, "test")
socket.expects(:enqueue_packet).with(packet)
session.enqueue_message(packet)
end
def test_configure_client_should_pass_options_to_socket_client_state
session.configure_client :compression => :standard
assert_equal :standard, socket.client.compression
end
def test_configure_server_should_pass_options_to_socket_server_state
session.configure_server :compression => :standard
assert_equal :standard, socket.server.compression
end
def test_hint_should_set_hint_on_socket
assert !socket.hints[:authenticated]
session.hint :authenticated
assert socket.hints[:authenticated]
end
private
def socket
@socket ||= stub("socket", :hints => {})
end
def server_version
@server_version ||= stub("server_version")
end
def algorithms
@algorithms ||= stub("algorithms", :initialized? => true, :allow? => true)
end
def session(options={})
@session ||= begin
host = options.delete(:host) || "net.ssh.test"
TCPSocket.stubs(:open).with(host, options[:port] || 22).returns(socket)
Net::SSH::Transport::ServerVersion.stubs(:new).returns(server_version)
Net::SSH::Transport::Algorithms.stubs(:new).returns(algorithms)
Net::SSH::Transport::Session.new(host, options)
end
end
# a simple alias to make the tests more self-documenting. the bang
# version makes it look more like the session is being instantiated
alias session! session
end
end
|