diff options
author | Jamis Buck <jamis@37signals.com> | 2008-03-22 07:24:16 -0600 |
---|---|---|
committer | Jamis Buck <jamis@37signals.com> | 2008-03-22 07:24:16 -0600 |
commit | 14d2ac33d10f69314febfc28b456e3cf92f72b12 (patch) | |
tree | eaf2d8c045a21dbab575cfc5c15b5a3f23df5458 | |
parent | c3e39e668936f22f348138a9b857631e6ac99ef8 (diff) | |
download | net-ssh-14d2ac33d10f69314febfc28b456e3cf92f72b12.tar.gz |
more documentation for the testing system
-rw-r--r-- | lib/net/ssh/test/kex.rb | 10 | ||||
-rw-r--r-- | lib/net/ssh/test/local_packet.rb | 20 | ||||
-rw-r--r-- | lib/net/ssh/test/packet.rb | 34 | ||||
-rw-r--r-- | lib/net/ssh/test/remote_packet.rb | 14 |
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! |