net-sftp 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/LICENSE-BSD +27 -0
- data/doc/LICENSE-GPL +280 -0
- data/doc/LICENSE-RUBY +56 -0
- data/examples/asynchronous.rb +57 -0
- data/examples/ssh-service.rb +31 -0
- data/examples/synchronous.rb +120 -0
- data/lib/net/sftp.rb +39 -0
- data/lib/net/sftp/errors.rb +25 -0
- data/lib/net/sftp/operations/abstract.rb +103 -0
- data/lib/net/sftp/operations/close.rb +31 -0
- data/lib/net/sftp/operations/errors.rb +76 -0
- data/lib/net/sftp/operations/fsetstat.rb +36 -0
- data/lib/net/sftp/operations/fstat.rb +32 -0
- data/lib/net/sftp/operations/lstat.rb +31 -0
- data/lib/net/sftp/operations/mkdir.rb +33 -0
- data/lib/net/sftp/operations/open.rb +32 -0
- data/lib/net/sftp/operations/opendir.rb +32 -0
- data/lib/net/sftp/operations/read.rb +84 -0
- data/lib/net/sftp/operations/readdir.rb +55 -0
- data/lib/net/sftp/operations/realpath.rb +37 -0
- data/lib/net/sftp/operations/remove.rb +31 -0
- data/lib/net/sftp/operations/rename.rb +32 -0
- data/lib/net/sftp/operations/rmdir.rb +31 -0
- data/lib/net/sftp/operations/services.rb +42 -0
- data/lib/net/sftp/operations/setstat.rb +33 -0
- data/lib/net/sftp/operations/stat.rb +31 -0
- data/lib/net/sftp/operations/write.rb +63 -0
- data/lib/net/sftp/protocol/01/attributes.rb +146 -0
- data/lib/net/sftp/protocol/01/impl.rb +251 -0
- data/lib/net/sftp/protocol/01/packet-assistant.rb +82 -0
- data/lib/net/sftp/protocol/01/services.rb +47 -0
- data/lib/net/sftp/protocol/02/impl.rb +39 -0
- data/lib/net/sftp/protocol/02/packet-assistant.rb +32 -0
- data/lib/net/sftp/protocol/02/services.rb +44 -0
- data/lib/net/sftp/protocol/03/impl.rb +42 -0
- data/lib/net/sftp/protocol/03/packet-assistant.rb +35 -0
- data/lib/net/sftp/protocol/03/services.rb +44 -0
- data/lib/net/sftp/protocol/04/attributes.rb +227 -0
- data/lib/net/sftp/protocol/04/impl.rb +134 -0
- data/lib/net/sftp/protocol/04/packet-assistant.rb +51 -0
- data/lib/net/sftp/protocol/04/services.rb +44 -0
- data/lib/net/sftp/protocol/05/services.rb +44 -0
- data/lib/net/sftp/protocol/constants.rb +60 -0
- data/lib/net/sftp/protocol/driver.rb +232 -0
- data/lib/net/sftp/protocol/packet-assistant.rb +84 -0
- data/lib/net/sftp/protocol/services.rb +55 -0
- data/lib/net/sftp/session.rb +215 -0
- data/lib/net/sftp/version.rb +25 -0
- data/test/ALL-TESTS.rb +21 -0
- data/test/operations/tc_abstract.rb +124 -0
- data/test/operations/tc_close.rb +40 -0
- data/test/operations/tc_fsetstat.rb +48 -0
- data/test/operations/tc_fstat.rb +40 -0
- data/test/operations/tc_lstat.rb +40 -0
- data/test/operations/tc_mkdir.rb +48 -0
- data/test/operations/tc_open.rb +42 -0
- data/test/operations/tc_opendir.rb +40 -0
- data/test/operations/tc_read.rb +103 -0
- data/test/operations/tc_readdir.rb +88 -0
- data/test/operations/tc_realpath.rb +54 -0
- data/test/operations/tc_remove.rb +40 -0
- data/test/operations/tc_rmdir.rb +40 -0
- data/test/operations/tc_setstat.rb +48 -0
- data/test/operations/tc_stat.rb +40 -0
- data/test/operations/tc_write.rb +91 -0
- data/test/protocol/01/tc_attributes.rb +138 -0
- data/test/protocol/01/tc_impl.rb +294 -0
- data/test/protocol/01/tc_packet_assistant.rb +81 -0
- data/test/protocol/02/tc_impl.rb +41 -0
- data/test/protocol/02/tc_packet_assistant.rb +31 -0
- data/test/protocol/03/tc_impl.rb +48 -0
- data/test/protocol/03/tc_packet_assistant.rb +34 -0
- data/test/protocol/04/tc_attributes.rb +174 -0
- data/test/protocol/04/tc_impl.rb +102 -0
- data/test/protocol/04/tc_packet_assistant.rb +41 -0
- data/test/protocol/tc_driver.rb +219 -0
- metadata +137 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
module Net ; module SFTP ; module Protocol
|
18
|
+
|
19
|
+
# This is the abstract base class for all packet assistant classes used by
|
20
|
+
# the supported SFTP protocol versions.
|
21
|
+
class PacketAssistant
|
22
|
+
|
23
|
+
# A helper method for defining a new packet type. The +name+ is the name
|
24
|
+
# of the packet (and of the corresponding method that is created), and the
|
25
|
+
# arguments are symbols representing the types of each element in the
|
26
|
+
# packet. The supported types are:
|
27
|
+
#
|
28
|
+
# * :long
|
29
|
+
# * :int64
|
30
|
+
# * :short
|
31
|
+
# * :byte
|
32
|
+
# * :string
|
33
|
+
# * :attrs
|
34
|
+
# * :write
|
35
|
+
#
|
36
|
+
# The :attrs and :write types both simply convert the argument to a string.
|
37
|
+
#
|
38
|
+
# The method that is created always supports an +id+ parameter in the
|
39
|
+
# first position, which if null will default to the next available request
|
40
|
+
# id. The method returns a tuple consisting of the request id, and a string
|
41
|
+
# consisting of the arguments formatted according to the packet's
|
42
|
+
# description.
|
43
|
+
def self.packet( name, *args )
|
44
|
+
body = ""
|
45
|
+
args.each do |arg|
|
46
|
+
body << "b.write"
|
47
|
+
case arg
|
48
|
+
when :long, :int64, :short, :byte
|
49
|
+
body << "_#{arg} args.shift.to_i"
|
50
|
+
when :string
|
51
|
+
body << "_#{arg} args.shift.to_s"
|
52
|
+
when :attrs, :write
|
53
|
+
body << " args.shift.to_s"
|
54
|
+
end
|
55
|
+
body << "\n"
|
56
|
+
end
|
57
|
+
class_eval <<-EOF, __FILE__, __LINE__+1
|
58
|
+
def #{name}( id, *args )
|
59
|
+
b = buffers.writer
|
60
|
+
id ||= driver.next_request_id
|
61
|
+
b.write_long id
|
62
|
+
#{body}
|
63
|
+
[ id, b.to_s ]
|
64
|
+
end
|
65
|
+
EOF
|
66
|
+
end
|
67
|
+
|
68
|
+
# The buffer factory in use by this packet assistant, used to build the
|
69
|
+
# packets.
|
70
|
+
attr_reader :buffers
|
71
|
+
|
72
|
+
# The protocol driver that will be used to obtain request ids.
|
73
|
+
attr_reader :driver
|
74
|
+
|
75
|
+
# Create a new PacketAssistant, which will use the given buffer factory and
|
76
|
+
# SFTP protocol driver.
|
77
|
+
def initialize( buffers, driver )
|
78
|
+
@buffers = buffers
|
79
|
+
@driver = driver
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end ; end ; end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
module Net ; module SFTP ; module Protocol
|
18
|
+
|
19
|
+
def register_services( container )
|
20
|
+
container.namespace_define :protocol do |ns|
|
21
|
+
|
22
|
+
# The maximum version of the SFTP protocol supported by this
|
23
|
+
# implementation. Clients may set this to a lower value to force the
|
24
|
+
# usage of a specific SFTP version. It should _not_ be set higher than
|
25
|
+
# the value that is given below.
|
26
|
+
ns.version { 5 }
|
27
|
+
|
28
|
+
# A proc object that, when invoked, returns a dispatcher object capable
|
29
|
+
# of handling the requested protocol version.
|
30
|
+
ns.dispatcher_factory do |c,|
|
31
|
+
lambda do |version, extensions|
|
32
|
+
version = "%02d" % version
|
33
|
+
c.require "net/sftp/protocol/#{version}/services",
|
34
|
+
"#{self}::V_#{version}"
|
35
|
+
impl = c["v_#{version}".to_sym][:impl]
|
36
|
+
impl.extensions = extensions
|
37
|
+
impl
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# The driver service that manages the SFTP protocol-level communications
|
42
|
+
ns.driver do |c,p|
|
43
|
+
require 'net/sftp/protocol/driver'
|
44
|
+
Driver.new( c[:connection][:driver],
|
45
|
+
c[:transport][:buffers],
|
46
|
+
c[:version],
|
47
|
+
c[:dispatcher_factory],
|
48
|
+
c[:log_for, p] )
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
module_function :register_services
|
54
|
+
|
55
|
+
end ; end ; end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
require 'net/sftp/errors'
|
18
|
+
require 'net/sftp/protocol/constants'
|
19
|
+
|
20
|
+
module Net ; module SFTP
|
21
|
+
|
22
|
+
# Represents a single SFTP session, running atop an SSH session.
|
23
|
+
class Session
|
24
|
+
include Protocol::Constants
|
25
|
+
|
26
|
+
# The status of the last synchronously executed operation. This is either
|
27
|
+
# +nil+, or an object that responds to <tt>:code</tt>, <tt>:message</tt>,
|
28
|
+
# and <tt>:language</tt>.
|
29
|
+
attr_accessor :status
|
30
|
+
|
31
|
+
# Create a new SFTP session on top of the given SSH session.
|
32
|
+
def initialize( session )
|
33
|
+
@session = session
|
34
|
+
@log = @session.registry.log_for( "sftp.session" )
|
35
|
+
|
36
|
+
@session.registry.namespace_define :sftp do |ns|
|
37
|
+
ns.require "net/sftp/protocol/services", "Net::SFTP::Protocol"
|
38
|
+
ns.require "net/sftp/operations/services", "Net::SFTP::Operations"
|
39
|
+
|
40
|
+
# register a reference to myself for other services to be able to
|
41
|
+
# access me.
|
42
|
+
ns.session( :pipeline => [] ) { self }
|
43
|
+
|
44
|
+
@driver = ns.protocol.driver
|
45
|
+
@driver.on_open do |d|
|
46
|
+
d.on_attrs &method( :do_attrs )
|
47
|
+
d.on_data &method( :do_data )
|
48
|
+
d.on_handle &method( :do_handle )
|
49
|
+
d.on_name &method( :do_name )
|
50
|
+
d.on_status &method( :do_status )
|
51
|
+
|
52
|
+
if block_given?
|
53
|
+
begin
|
54
|
+
yield self
|
55
|
+
ensure
|
56
|
+
d.close
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
@operations = ns.operations
|
62
|
+
end
|
63
|
+
|
64
|
+
@requests = Hash.new
|
65
|
+
|
66
|
+
@session.loop if block_given?
|
67
|
+
end
|
68
|
+
|
69
|
+
#--
|
70
|
+
# ====================================================================
|
71
|
+
# QUERIES/GETTERS/SETTERS/ACTIONS
|
72
|
+
# ====================================================================
|
73
|
+
#++
|
74
|
+
|
75
|
+
# Return the state of the SFTP connection. (See
|
76
|
+
# Net::SFTP::Protocol::Driver#state.)
|
77
|
+
def state
|
78
|
+
@driver.state
|
79
|
+
end
|
80
|
+
|
81
|
+
# Closes the SFTP connection, but leaves the SSH connection open.
|
82
|
+
def close_channel
|
83
|
+
@driver.close
|
84
|
+
end
|
85
|
+
|
86
|
+
# Closes the underlying SSH connection.
|
87
|
+
def close
|
88
|
+
@session.close
|
89
|
+
end
|
90
|
+
|
91
|
+
# Registers the given handler with the given request id. This is used
|
92
|
+
# internally by the operations, so that the session knows who to delegate
|
93
|
+
# a response to that has been received from the server.
|
94
|
+
def register( id, handler )
|
95
|
+
@requests[ id ] = handler
|
96
|
+
end
|
97
|
+
|
98
|
+
# Delegates to Net::SSH::Session#loop. Causes the underlying SSH
|
99
|
+
# connection to process events as long as the given block returns +true+,
|
100
|
+
# or (if no block is given) until there are no more open channels.
|
101
|
+
def loop( &block )
|
102
|
+
@session.loop( &block )
|
103
|
+
end
|
104
|
+
|
105
|
+
# Waits for the underlying driver to reach a state of :open (or :closed).
|
106
|
+
# This makes it easier to use the SFTP routines synchronously without using
|
107
|
+
# the block form:
|
108
|
+
#
|
109
|
+
# sftp = Net::SFTP::Session.new( ssh_session )
|
110
|
+
# sftp.connect
|
111
|
+
# puts sftp.realpath( "." )
|
112
|
+
#
|
113
|
+
# Without the call to #connect, the call to #realpath would fail because
|
114
|
+
# the SFTP protocol has not yet been negotiated and no underlying driver has
|
115
|
+
# been selected.
|
116
|
+
#
|
117
|
+
# If no block is given, it teturns +self+, so it can be chained easily to
|
118
|
+
# other method calls. If a block _is_ given, the session is yielded to the
|
119
|
+
# block as soon as the driver successfully reports it's state as +open+,
|
120
|
+
# with the session's channel being closed automatically when the block
|
121
|
+
# finishes.
|
122
|
+
#
|
123
|
+
# require 'net/ssh'
|
124
|
+
# require 'net/sftp'
|
125
|
+
#
|
126
|
+
# Net::SSH.start( 'localhost' ) do |session|
|
127
|
+
# session.sftp.connect do |sftp|
|
128
|
+
# puts sftp.realpath( "." )
|
129
|
+
# end
|
130
|
+
# end
|
131
|
+
def connect
|
132
|
+
@session.loop do
|
133
|
+
@driver.state != :open &&
|
134
|
+
@driver.state != :closed
|
135
|
+
end
|
136
|
+
if @driver.state == :open && block_given?
|
137
|
+
begin
|
138
|
+
yield self
|
139
|
+
ensure
|
140
|
+
close_channel
|
141
|
+
end
|
142
|
+
else
|
143
|
+
self
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
#--
|
148
|
+
# ====================================================================
|
149
|
+
# CALLBACKS
|
150
|
+
# ====================================================================
|
151
|
+
#++
|
152
|
+
|
153
|
+
# Invoked by the underlying SFTP protocol layer when a SFTP data packet
|
154
|
+
# is received.
|
155
|
+
def do_data( driver, id, data )
|
156
|
+
@requests.delete( id ).do_data( data )
|
157
|
+
end
|
158
|
+
|
159
|
+
# Invoked by the underlying SFTP protocol layer when a SFTP status packet
|
160
|
+
# is received.
|
161
|
+
def do_status( driver, id, code, message, language )
|
162
|
+
@requests.delete( id ).do_status( code, message, language )
|
163
|
+
end
|
164
|
+
|
165
|
+
# Invoked by the underlying SFTP protocol layer when a SFTP handle packet
|
166
|
+
# is received.
|
167
|
+
def do_handle( driver, id, handle )
|
168
|
+
@requests.delete( id ).do_handle( handle )
|
169
|
+
end
|
170
|
+
|
171
|
+
# Invoked by the underlying SFTP protocol layer when a SFTP name packet
|
172
|
+
# is received.
|
173
|
+
def do_name( driver, id, items )
|
174
|
+
@requests.delete( id ).do_name( items )
|
175
|
+
end
|
176
|
+
|
177
|
+
# Invoked by the underlying SFTP protocol layer when a SFTP attrs packet
|
178
|
+
# is received.
|
179
|
+
def do_attrs( driver, id, attributes )
|
180
|
+
@requests.delete( id ).do_attrs( attributes )
|
181
|
+
end
|
182
|
+
|
183
|
+
#--
|
184
|
+
# ====================================================================
|
185
|
+
# DELEGATION
|
186
|
+
# ====================================================================
|
187
|
+
#++
|
188
|
+
|
189
|
+
# Delegates the message to the operation that has been registered with
|
190
|
+
# the given name. If no such operation exists, control is passed to the
|
191
|
+
# superclass' implementation of #method_missing.
|
192
|
+
def method_missing( sym, *args, &block )
|
193
|
+
if @operations.has_key?( sym )
|
194
|
+
@operations[ sym ].execute( *args, &block )
|
195
|
+
else
|
196
|
+
super
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns +true+ if the object responds to the given symbol, or if there is
|
201
|
+
# an operation registered under the given symbol.
|
202
|
+
def respond_to?( sym )
|
203
|
+
super || @operations.has_key?( sym )
|
204
|
+
end
|
205
|
+
|
206
|
+
# Returns +true+ if the underlying driver responds to the given symbol. This
|
207
|
+
# can be used by clients to determine whether the SFTP protocol version in
|
208
|
+
# use supports a particular operation.
|
209
|
+
def support?( sym )
|
210
|
+
@driver.respond_to?( sym )
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
end ; end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
module Net ; module SFTP ; module Version
|
18
|
+
|
19
|
+
MAJOR = 0
|
20
|
+
MINOR = 5
|
21
|
+
TINY = 0
|
22
|
+
|
23
|
+
STRING = [MAJOR,MINOR,TINY].join('.')
|
24
|
+
|
25
|
+
end ; end ; end
|
data/test/ALL-TESTS.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
$:.unshift "../lib"
|
18
|
+
|
19
|
+
$run_integration_tests = ARGV.include?( "-i" )
|
20
|
+
|
21
|
+
Dir["**/tc_*.rb"].each { |f| load f }
|
@@ -0,0 +1,124 @@
|
|
1
|
+
#--
|
2
|
+
# =============================================================================
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# This source file is distributed as part of the Net::SFTP Secure FTP Client
|
7
|
+
# library for Ruby. This file (and the library as a whole) may be used only as
|
8
|
+
# allowed by either the BSD license, or the Ruby license (or, by association
|
9
|
+
# with the Ruby license, the GPL). See the "doc" subdirectory of the Net::SFTP
|
10
|
+
# distribution for the texts of these licenses.
|
11
|
+
# -----------------------------------------------------------------------------
|
12
|
+
# net-sftp website: http://net-ssh.rubyforge.org/sftp
|
13
|
+
# project website : http://rubyforge.org/projects/net-ssh
|
14
|
+
# =============================================================================
|
15
|
+
#++
|
16
|
+
|
17
|
+
$:.unshift "../../lib"
|
18
|
+
|
19
|
+
require 'test/unit'
|
20
|
+
require 'net/sftp/operations/abstract'
|
21
|
+
require 'flexmock'
|
22
|
+
|
23
|
+
class TC_Operations_Abstract < Test::Unit::TestCase
|
24
|
+
|
25
|
+
class Subclass < Net::SFTP::Operations::Abstract
|
26
|
+
attr_reader :args
|
27
|
+
|
28
|
+
def perform( *args )
|
29
|
+
@args = args
|
30
|
+
14
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup
|
35
|
+
@log = FlexMock.new
|
36
|
+
@log.mock_handle( :debug )
|
37
|
+
@log.mock_handle( :debug? )
|
38
|
+
|
39
|
+
@session = FlexMock.new
|
40
|
+
@session.mock_handle( :status= )
|
41
|
+
@session.mock_handle( :register )
|
42
|
+
@session.mock_handle( :loop )
|
43
|
+
|
44
|
+
@driver = FlexMock.new
|
45
|
+
|
46
|
+
@operation = Subclass.new( @log, @session, @driver )
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_execute_no_block
|
50
|
+
reg_args = nil
|
51
|
+
@session.mock_handle( :register ) { |*a| reg_args = a }
|
52
|
+
|
53
|
+
@operation.execute( :foo, :bar )
|
54
|
+
|
55
|
+
assert_equal 1, @session.mock_count( :register )
|
56
|
+
assert_equal 1, @session.mock_count( :loop )
|
57
|
+
assert_equal [ 14, @operation ], reg_args
|
58
|
+
assert_equal [ :foo, :bar ], @operation.args
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_execute_with_block
|
62
|
+
reg_args = nil
|
63
|
+
@session.mock_handle( :register ) { |*a| reg_args = a }
|
64
|
+
|
65
|
+
@operation.execute( :foo, :bar ) { }
|
66
|
+
|
67
|
+
assert_equal 1, @session.mock_count( :register )
|
68
|
+
assert_equal 0, @session.mock_count( :loop )
|
69
|
+
assert_equal [ 14, @operation ], reg_args
|
70
|
+
assert_equal [ :foo, :bar ], @operation.args
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_do_status_bad
|
74
|
+
assert_raise( Net::SFTP::Operations::StatusException ) do
|
75
|
+
@operation.do_status( 5, nil, nil )
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_status_ok
|
80
|
+
status = nil
|
81
|
+
@operation.execute( :foo, :bar ) { |s| status = s }
|
82
|
+
assert_nothing_raised { @operation.do_status( 0, "hello", "world" ) }
|
83
|
+
assert_equal 0, status.code
|
84
|
+
assert_equal "hello", status.message
|
85
|
+
assert_equal "world", status.language
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_do_handle
|
89
|
+
status = nil
|
90
|
+
handle = nil
|
91
|
+
@operation.execute( :foo, :bar ) { |s,h| status, handle = s, h }
|
92
|
+
@operation.do_handle( "foo" )
|
93
|
+
assert_equal 0, status.code
|
94
|
+
assert_equal "foo", handle
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_do_data
|
98
|
+
status = nil
|
99
|
+
data = nil
|
100
|
+
@operation.execute( :foo, :bar ) { |s,d| status, data = s, d }
|
101
|
+
@operation.do_data( "foo" )
|
102
|
+
assert_equal 0, status.code
|
103
|
+
assert_equal "foo", data
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_do_name
|
107
|
+
status = nil
|
108
|
+
name = nil
|
109
|
+
@operation.execute( :foo, :bar ) { |s,n| status, name = s, n }
|
110
|
+
@operation.do_name( "foo" )
|
111
|
+
assert_equal 0, status.code
|
112
|
+
assert_equal "foo", name
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_do_attrs
|
116
|
+
status = nil
|
117
|
+
attrs = nil
|
118
|
+
@operation.execute( :foo, :bar ) { |s,a| status, attrs = s, a }
|
119
|
+
@operation.do_attrs( "foo" )
|
120
|
+
assert_equal 0, status.code
|
121
|
+
assert_equal "foo", attrs
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|