summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2008-03-22 07:24:16 -0600
committerJamis Buck <jamis@37signals.com>2008-03-22 07:24:16 -0600
commit14d2ac33d10f69314febfc28b456e3cf92f72b12 (patch)
treeeaf2d8c045a21dbab575cfc5c15b5a3f23df5458
parentc3e39e668936f22f348138a9b857631e6ac99ef8 (diff)
downloadnet-ssh-14d2ac33d10f69314febfc28b456e3cf92f72b12.tar.gz
more documentation for the testing system
-rw-r--r--lib/net/ssh/test/kex.rb10
-rw-r--r--lib/net/ssh/test/local_packet.rb20
-rw-r--r--lib/net/ssh/test/packet.rb34
-rw-r--r--lib/net/ssh/test/remote_packet.rb14
4 files changed, 76 insertions, 2 deletions
diff --git a/lib/net/ssh/test/kex.rb b/lib/net/ssh/test/kex.rb
index a38a003..9e34e42 100644
--- a/lib/net/ssh/test/kex.rb
+++ b/lib/net/ssh/test/kex.rb
@@ -7,13 +7,23 @@ require 'net/ssh/transport/kex'
module Net; module SSH; module Test
+ # An implementation of a key-exchange strategy specifically for unit tests.
+ # (This strategy would never really work against a real SSH server--it makes
+ # too many assumptions about the server's response.)
+ #
+ # This registers itself with the transport key-exchange system as the
+ # "test" algorithm.
class Kex
include Net::SSH::Transport::Constants
+ # Creates a new instance of the testing key-exchange algorithm with the
+ # given arguments.
def initialize(algorithms, connection, data)
@connection = connection
end
+ # Exchange keys with the server. This returns a hash of constant values,
+ # and does not actually exchange keys.
def exchange_keys
result = Net::SSH::Buffer.from(:byte, NEWKEYS)
@connection.send_message(result)
diff --git a/lib/net/ssh/test/local_packet.rb b/lib/net/ssh/test/local_packet.rb
index d659f94..a85c02f 100644
--- a/lib/net/ssh/test/local_packet.rb
+++ b/lib/net/ssh/test/local_packet.rb
@@ -3,11 +3,31 @@ require 'net/ssh/test/packet'
module Net; module SSH; module Test
+ # This is a specialization of Net::SSH::Test::Packet for representing mock
+ # packets that are sent from the local (client) host. These are created
+ # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
+ # of the sends_* methods.
class LocalPacket < Packet
+ attr_reader :init
+
+ # Extend the default Net::SSH::Test::Packet constructor to also accept an
+ # optional block, which is used to finalize the initialization of the
+ # packet when #process is first called.
+ def initialize(type, *args, &block)
+ super(type, *args)
+ @init = block
+ end
+
+ # Returns +true+; this is a local packet.
def local?
true
end
+ # Called by Net::SSH::Test::Extensions::PacketStream#test_enqueue_packet
+ # to mimic remote processing of a locally-sent packet. It compares the
+ # packet it was given with the contents of this LocalPacket's data, to see
+ # if what was sent matches what was scripted. If it differs in any way,
+ # an exception is raised.
def process(packet)
@init.call(Net::SSH::Packet.new(packet.to_s)) if @init
type = packet.read_byte
diff --git a/lib/net/ssh/test/packet.rb b/lib/net/ssh/test/packet.rb
index e69081d..0853003 100644
--- a/lib/net/ssh/test/packet.rb
+++ b/lib/net/ssh/test/packet.rb
@@ -3,28 +3,58 @@ require 'net/ssh/transport/constants'
module Net; module SSH; module Test
+ # This is an abstract class, not to be instantiated directly, subclassed by
+ # Net::SSH::Test::LocalPacket and Net::SSH::Test::RemotePacket. It implements
+ # functionality common to those subclasses.
+ #
+ # These packets are not true packets, in that they don't represent what was
+ # actually sent between the hosst; rather, they represent what was expected
+ # to be sent, as dictated by the script (Net::SSH::Test::Script). Thus,
+ # though they are defined with data elements, these data elements are used
+ # to either validate data that was sent by the local host (Net::SSH::Test::LocalPacket)
+ # or to mimic the sending of data by the remote host (Net::SSH::Test::RemotePacket).
class Packet
include Net::SSH::Transport::Constants
include Net::SSH::Connection::Constants
- def initialize(type, *args, &init)
+ # Ceate a new packet of the given +type+, and with +args+ being a list of
+ # data elements in the order expected for packets of the given +type+
+ # (see #types).
+ def initialize(type, *args)
@type = self.class.const_get(type.to_s.upcase)
@data = args
- @init = init
end
+ # The default for +remote?+ is false. Subclasses should override as necessary.
def remote?
false
end
+ # The default for +local?+ is false. Subclasses should override as necessary.
def local?
false
end
+ # Instantiates the packets data elements. When the packet was first defined,
+ # some elements may not have been fully realized, and were described as
+ # Proc objects rather than atomic types. This invokes those Proc objects
+ # and replaces them with their returned values. This allows for values
+ # like Net::SSH::Test::Channel#remote_id to be used in scripts before
+ # the remote_id is known (since it is only known after a channel has been
+ # confirmed open).
def instantiate!
@data.map! { |i| i.respond_to?(:call) ? i.call : i }
end
+ # Returns an array of symbols describing the data elements for packets of
+ # the same type as this packet. These types are used to either validate
+ # sent packets (Net::SSH::Test::LocalPacket) or build received packets
+ # (Net::SSH::Test::RemotePacket).
+ #
+ # Not all packet types are defined here. As new packet types are required
+ # (e.g., a unit test needs to test that the remote host sent a packet that
+ # is not implemented here), the description of that packet should be
+ # added. Unsupported packet types will otherwise raise an exception.
def types
@types ||= case @type
when KEXINIT then
diff --git a/lib/net/ssh/test/remote_packet.rb b/lib/net/ssh/test/remote_packet.rb
index 5aeab76..c09d750 100644
--- a/lib/net/ssh/test/remote_packet.rb
+++ b/lib/net/ssh/test/remote_packet.rb
@@ -3,15 +3,29 @@ require 'net/ssh/test/packet'
module Net; module SSH; module Test
+ # This is a specialization of Net::SSH::Test::Packet for representing mock
+ # packets that are received by the local (client) host. These are created
+ # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
+ # of the gets_* methods.
class RemotePacket < Packet
+ # Returns +true+; this is a remote packet.
def remote?
true
end
+ # The #process method should only be called on Net::SSH::Test::LocalPacket
+ # packets; if it is attempted on a remote packet, then it is an expectation
+ # mismatch (a remote packet was received when a local packet was expected
+ # to be sent). This will happen when either your test script
+ # (Net::SSH::Test::Script) or your program are wrong.
def process(packet)
raise "received packet type #{packet.read_byte} and was not expecting any packet"
end
+ # Returns this remote packet as a string, suitable for parsing by
+ # Net::SSH::Transport::PacketStream and friends. When a remote packet is
+ # received, this method is called and the result concatenated onto the
+ # input buffer for the packet stream.
def to_s
@to_s ||= begin
instantiate!