net-sftp 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,48 @@
|
|
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
|
+
$:.unshift File.join( File.dirname( __FILE__ ), ".." )
|
19
|
+
|
20
|
+
require '02/tc_impl.rb'
|
21
|
+
require 'net/sftp/protocol/03/impl'
|
22
|
+
|
23
|
+
class TC_03_Impl < TC_02_Impl
|
24
|
+
|
25
|
+
def impl_class
|
26
|
+
Net::SFTP::Protocol::V_03::Impl
|
27
|
+
end
|
28
|
+
|
29
|
+
operation :readlink
|
30
|
+
|
31
|
+
operation :symlink
|
32
|
+
|
33
|
+
def test_do_status_with_callback
|
34
|
+
buffer = Net::SSH::Util::ReaderBuffer.new( "\0\0\0\1\0\0\0\2" +
|
35
|
+
"\0\0\0\1a\0\0\0\1b" )
|
36
|
+
called = false
|
37
|
+
@impl.on_status do |d,i,c,a,b|
|
38
|
+
called = true
|
39
|
+
assert_equal 1, i
|
40
|
+
assert_equal 2, c
|
41
|
+
assert_equal "a", a
|
42
|
+
assert_equal "b", b
|
43
|
+
end
|
44
|
+
@impl.do_status nil, buffer
|
45
|
+
assert called
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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
|
+
$:.unshift File.join( File.dirname( __FILE__ ), ".." )
|
19
|
+
|
20
|
+
require '02/tc_packet_assistant'
|
21
|
+
require 'net/sftp/protocol/03/packet-assistant'
|
22
|
+
|
23
|
+
class TC_03_PacketAssistant < TC_02_PacketAssistant
|
24
|
+
|
25
|
+
def packet_assistant_class
|
26
|
+
Net::SFTP::Protocol::V_03::PacketAssistant
|
27
|
+
end
|
28
|
+
|
29
|
+
packet :readlink, [ "a path" ], "\0\0\0\6a path"
|
30
|
+
|
31
|
+
packet :symlink, [ "from path", "to path" ],
|
32
|
+
"\0\0\0\11from path\0\0\0\7to path"
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,174 @@
|
|
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/protocol/04/attributes'
|
21
|
+
|
22
|
+
require 'net/ssh'
|
23
|
+
require 'net/ssh/util/buffer'
|
24
|
+
|
25
|
+
class TC_04_Attributes < Test::Unit::TestCase
|
26
|
+
|
27
|
+
class Buffers
|
28
|
+
def writer
|
29
|
+
Net::SSH::Util::WriterBuffer.new
|
30
|
+
end
|
31
|
+
def reader( text )
|
32
|
+
Net::SSH::Util::ReaderBuffer.new( text )
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup
|
37
|
+
@factory = Net::SFTP::Protocol::V_04::Attributes.init( Buffers.new )
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_empty
|
41
|
+
empty = @factory.empty
|
42
|
+
assert_equal 1, empty.type
|
43
|
+
assert_nil empty.size
|
44
|
+
assert_nil empty.owner
|
45
|
+
assert_nil empty.group
|
46
|
+
assert_nil empty.permissions
|
47
|
+
assert_nil empty.atime
|
48
|
+
assert_nil empty.atime_nseconds
|
49
|
+
assert_nil empty.ctime
|
50
|
+
assert_nil empty.ctime_nseconds
|
51
|
+
assert_nil empty.mtime
|
52
|
+
assert_nil empty.mtime_nseconds
|
53
|
+
assert_nil empty.acl
|
54
|
+
assert_nil empty.extended
|
55
|
+
assert_equal "\0\0\0\0\1", empty.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_from_buffer_empty
|
59
|
+
buffer = @factory.buffers.reader( "\0\0\0\0\2" )
|
60
|
+
attrs = @factory.from_buffer( buffer )
|
61
|
+
assert_equal 2, attrs.type
|
62
|
+
assert_nil attrs.size
|
63
|
+
assert_nil attrs.owner
|
64
|
+
assert_nil attrs.group
|
65
|
+
assert_nil attrs.permissions
|
66
|
+
assert_nil attrs.atime
|
67
|
+
assert_nil attrs.atime_nseconds
|
68
|
+
assert_nil attrs.ctime
|
69
|
+
assert_nil attrs.ctime_nseconds
|
70
|
+
assert_nil attrs.mtime
|
71
|
+
assert_nil attrs.mtime_nseconds
|
72
|
+
assert_nil attrs.acl
|
73
|
+
assert_nil attrs.extended
|
74
|
+
assert_equal "\0\0\0\0\2", attrs.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
ACL = Net::SFTP::Protocol::V_04::Attributes::ACL
|
78
|
+
ATTRIBUTES =
|
79
|
+
[ [ 0x00000001, "\1\2\3\4\5\6\7\10", :size, 0x0102030405060708 ],
|
80
|
+
[ 0x00000080, "\0\0\0\1a\0\0\0\1b", :owner, "a" ],
|
81
|
+
[ 0x00000080, "\0\0\0\1a\0\0\0\1b", :group, "b" ],
|
82
|
+
[ 0x00000004, "\21\22\23\24", :permissions, 0x11121314 ],
|
83
|
+
[ 0x00000138,
|
84
|
+
"\1\1\1\1\1\1\1\1\0\1\2\3" +
|
85
|
+
"\2\2\2\2\2\2\2\2\4\5\6\7" +
|
86
|
+
"\3\3\3\3\3\3\3\3\2\4\6\10", :atime_nseconds, 0x00010203 ],
|
87
|
+
[ 0x00000008, "\1\2\3\4\1\2\3\4", :atime, 0x0102030401020304 ],
|
88
|
+
[ 0x00000010, "\4\3\4\3\4\3\4\3", :ctime, 0x0403040304030403 ],
|
89
|
+
[ 0x00000020, "\4\3\2\1\4\3\2\1", :mtime, 0x0403020104030201 ],
|
90
|
+
[ 0x00000040, "\0\0\0\46\0\0\0\2\0\0\0\1\0\0\0\2\0\0\0\3\0\0\0\1a" +
|
91
|
+
"\0\0\0\4\0\0\0\5\0\0\0\6\0\0\0\1b", :acl,
|
92
|
+
[ ACL.new( 1, 2, 3, "a" ), ACL.new( 4, 5, 6, "b" ) ] ],
|
93
|
+
[ 0x80000000,
|
94
|
+
"\0\0\0\4" +
|
95
|
+
"\0\0\0\01a\0\0\0\01b" +
|
96
|
+
"\0\0\0\01c\0\0\0\01d" +
|
97
|
+
"\0\0\0\01e\0\0\0\01f" +
|
98
|
+
"\0\0\0\01g\0\0\0\01h",
|
99
|
+
:extended,
|
100
|
+
{ "a" => "b", "c" => "d", "e" => "f", "g" => "h" } ] ]
|
101
|
+
|
102
|
+
# find all possible combinations of the elements of ATTRIBUTES
|
103
|
+
# (i.e., 'n' choose k, for k in [1..ATTRIBUTES.length]).
|
104
|
+
def self.choose( from, k )
|
105
|
+
result = []
|
106
|
+
( from.length - k + 1 ).times do |i|
|
107
|
+
if i+1 < from.length && k > 1
|
108
|
+
choose( from[i+1..-1], k-1 ).each do |chosen|
|
109
|
+
result << [ from[i], *chosen ]
|
110
|
+
end
|
111
|
+
else
|
112
|
+
result << [ from[i] ]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
result
|
116
|
+
end
|
117
|
+
|
118
|
+
method_id = 0
|
119
|
+
ATTRIBUTES.length.times do |k|
|
120
|
+
choose( ATTRIBUTES, k+1 ).each do |attrs|
|
121
|
+
vars = attrs.map { |a| a[2] }.join( "_" )
|
122
|
+
define_method( "test_attributes_#{vars}_%03d" % method_id ) do
|
123
|
+
flags = 0
|
124
|
+
buffer = "\1"
|
125
|
+
attrs.each do |a|
|
126
|
+
if ( flags & a[0] ) == 0
|
127
|
+
flags |= a[0]
|
128
|
+
buffer += a[1]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
buffer = [ flags, buffer ].pack( "NA*" )
|
132
|
+
input = @factory.buffers.reader( buffer )
|
133
|
+
obj = @factory.from_buffer( input )
|
134
|
+
assert_equal 1, obj.type, vars
|
135
|
+
flags = 0
|
136
|
+
attrs.each do |a|
|
137
|
+
if ( flags & a[0] ) == 0
|
138
|
+
assert_equal a[3], obj.__send__( a[2] ), a[2]
|
139
|
+
flags |= a[0]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
assert_equal buffer, obj.to_s, vars
|
143
|
+
end
|
144
|
+
method_id += 1
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
require 'etc'
|
149
|
+
[
|
150
|
+
[ { :type => 3 }, :type, 3 ],
|
151
|
+
[ { :size => 1000 }, :size, 1000, :permissions ],
|
152
|
+
[ { :owner => ENV['USER'] }, :owner, ENV['USER'] ],
|
153
|
+
[ { :group => 'root' }, :group, 'root' ],
|
154
|
+
[ { :uid => Etc.getpwnam(ENV['USER']).uid }, :owner, ENV['USER'] ],
|
155
|
+
[ { :gid => Etc.getgrnam('root').gid }, :group, 'root' ],
|
156
|
+
[ { :permissions => 0600 }, :permissions, 0600 ],
|
157
|
+
[ { :atime => 1 }, :atime, 1 ],
|
158
|
+
[ { :atime_nseconds => 2 }, :atime_nseconds, 2 ],
|
159
|
+
[ { :ctime => 1 }, :ctime, 1 ],
|
160
|
+
[ { :ctime_nseconds => 2 }, :ctime_nseconds, 2 ],
|
161
|
+
[ { :mtime => 1 }, :mtime, 1 ],
|
162
|
+
[ { :mtime_nseconds => 2 }, :mtime_nseconds, 2 ],
|
163
|
+
[ { :acl => [ ACL.new(1,2,3,4), ACL.new(5,6,7,8) ] },
|
164
|
+
:acl, [ ACL.new(1,2,3,4), ACL.new(5,6,7,8) ] ],
|
165
|
+
[ { :extended => { "foo" => "bar" } }, :extended, { "foo" => "bar" } ]
|
166
|
+
].each do |fixture|
|
167
|
+
define_method( "test_from_hash_#{fixture[1]}" ) do
|
168
|
+
attrs = @factory.from_hash( fixture[0] )
|
169
|
+
assert_equal fixture[2], attrs.__send__( fixture[1] )
|
170
|
+
assert_nil attrs.__send__( fixture[3] || :size )
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
@@ -0,0 +1,102 @@
|
|
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
|
+
$:.unshift File.join( File.dirname( __FILE__ ), ".." )
|
19
|
+
|
20
|
+
require 'net/sftp/protocol/04/impl'
|
21
|
+
require '03/tc_impl'
|
22
|
+
|
23
|
+
class TC_04_Impl < TC_03_Impl
|
24
|
+
|
25
|
+
def impl_class
|
26
|
+
Net::SFTP::Protocol::V_04::Impl
|
27
|
+
end
|
28
|
+
|
29
|
+
unless defined?( IO_FLAGS_V4 )
|
30
|
+
IO_FLAGS_V4 = [ IO::RDONLY, IO::WRONLY, IO::RDWR, IO::APPEND ]
|
31
|
+
OTHER_FLAGS_V4 = [ 0, IO::CREAT, IO::TRUNC, IO::EXCL ]
|
32
|
+
FLAG_MAP_V4 = { IO::RDONLY => 2, IO::WRONLY => 1, IO::RDWR => 3,
|
33
|
+
IO::APPEND => 11, IO::CREAT => 3, IO::TRUNC => 4 }
|
34
|
+
ACCESS_MAP_V4 = { IO::RDONLY => 0x81, IO::WRONLY => 0x102,
|
35
|
+
IO::RDWR => 0x183, IO::APPEND => 0x106 }
|
36
|
+
|
37
|
+
IO_FLAGS_V4.each do |flag|
|
38
|
+
OTHER_FLAGS_V4.each do |oflag|
|
39
|
+
[ nil, 0400 ].each do |mode|
|
40
|
+
define_method( "test_open_#{flag}_#{oflag}_#{mode||"nil"}" ) do
|
41
|
+
return if oflag == IO::EXCL
|
42
|
+
@assistant.mock_handle( :open ) { |*a| [ a[0], a[1..-1] ] }
|
43
|
+
args = [ 14, "a path", flag | oflag ]
|
44
|
+
args << mode if mode
|
45
|
+
assert_equal 14, @impl.open( *args )
|
46
|
+
assert_equal 1, @assistant.mock_count( :open )
|
47
|
+
assert_equal( ( mode || 0660 ), @permissions )
|
48
|
+
sftp_flag = FLAG_MAP_V4[flag] |
|
49
|
+
( oflag == 0 ? 0 : FLAG_MAP_V4[oflag] )
|
50
|
+
access_flag = ACCESS_MAP_V4[flag]
|
51
|
+
assert_equal Net::SFTP::Protocol::Constants::FXP_OPEN,
|
52
|
+
@sent_data.first[0]
|
53
|
+
assert_equal [ "a path", access_flag, sftp_flag ],
|
54
|
+
@sent_data.first[1][0,3]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_stat_flags
|
62
|
+
@assistant.mock_handle( :stat ) { |*a| [ a[0], a[1..-1] ] }
|
63
|
+
id = @impl.stat( 14, :a, :b )
|
64
|
+
assert_equal 14, id
|
65
|
+
assert_equal 1, @assistant.mock_count( :stat )
|
66
|
+
assert_equal 1, @driver.mock_count( :send_data )
|
67
|
+
assert_equal [
|
68
|
+
[ Net::SFTP::Protocol::Constants::FXP_STAT, [ :a, :b ]] ], @sent_data
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_lstat_flags
|
72
|
+
@assistant.mock_handle( :lstat ) { |*a| [ a[0], a[1..-1] ] }
|
73
|
+
id = @impl.lstat( 14, :a, :b )
|
74
|
+
assert_equal 14, id
|
75
|
+
assert_equal 1, @assistant.mock_count( :lstat )
|
76
|
+
assert_equal 1, @driver.mock_count( :send_data )
|
77
|
+
assert_equal [
|
78
|
+
[ Net::SFTP::Protocol::Constants::FXP_LSTAT, [ :a, :b ]] ], @sent_data
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_fstat_flags
|
82
|
+
@assistant.mock_handle( :fstat ) { |*a| [ a[0], a[1..-1] ] }
|
83
|
+
id = @impl.fstat( 14, :a, :b )
|
84
|
+
assert_equal 14, id
|
85
|
+
assert_equal 1, @assistant.mock_count( :fstat )
|
86
|
+
assert_equal 1, @driver.mock_count( :send_data )
|
87
|
+
assert_equal [
|
88
|
+
[ Net::SFTP::Protocol::Constants::FXP_FSTAT, [ :a, :b ]] ], @sent_data
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_rename_flags
|
92
|
+
@assistant.mock_handle( :rename ) { |*a| [ a[0], a[1..-1] ] }
|
93
|
+
id = @impl.rename( 14, :a, :b, :c )
|
94
|
+
assert_equal 14, id
|
95
|
+
assert_equal 1, @assistant.mock_count( :rename )
|
96
|
+
assert_equal 1, @driver.mock_count( :send_data )
|
97
|
+
assert_equal [
|
98
|
+
[ Net::SFTP::Protocol::Constants::FXP_RENAME, [ :a, :b, :c ]] ],
|
99
|
+
@sent_data
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,41 @@
|
|
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
|
+
$:.unshift File.join( File.dirname( __FILE__ ), ".." )
|
19
|
+
|
20
|
+
require '03/tc_packet_assistant'
|
21
|
+
require 'net/sftp/protocol/04/packet-assistant'
|
22
|
+
|
23
|
+
class TC_04_PacketAssistant < TC_03_PacketAssistant
|
24
|
+
|
25
|
+
def packet_assistant_class
|
26
|
+
Net::SFTP::Protocol::V_04::PacketAssistant
|
27
|
+
end
|
28
|
+
|
29
|
+
packet :open, [ "a path", 1, 2, "attrs" ],
|
30
|
+
"\0\0\0\6a path\0\0\0\1\0\0\0\2attrs"
|
31
|
+
|
32
|
+
packet :rename, [ "old name", "new name", 1 ],
|
33
|
+
"\0\0\0\10old name\0\0\0\10new name\0\0\0\1"
|
34
|
+
|
35
|
+
packet :stat, [ "a path", 1 ], "\0\0\0\6a path\0\0\0\1"
|
36
|
+
|
37
|
+
packet :lstat, [ "a path", 1 ], "\0\0\0\6a path\0\0\0\1"
|
38
|
+
|
39
|
+
packet :fstat, [ "handle", 1 ], "\0\0\0\6handle\0\0\0\1"
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,219 @@
|
|
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/protocol/driver'
|
21
|
+
require 'net/ssh/util/buffer'
|
22
|
+
require 'flexmock'
|
23
|
+
|
24
|
+
class TC_Protocol_Driver < Test::Unit::TestCase
|
25
|
+
|
26
|
+
class Buffers
|
27
|
+
def writer
|
28
|
+
Net::SSH::Util::WriterBuffer.new
|
29
|
+
end
|
30
|
+
def reader( text )
|
31
|
+
Net::SSH::Util::ReaderBuffer.new( text )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def reader( text )
|
36
|
+
Net::SSH::Util::ReaderBuffer.new( text )
|
37
|
+
end
|
38
|
+
|
39
|
+
def force_state( state )
|
40
|
+
@driver.instance_eval { @state = state }
|
41
|
+
end
|
42
|
+
|
43
|
+
def setup
|
44
|
+
@channel = FlexMock.new
|
45
|
+
@channel.mock_handle( :close )
|
46
|
+
@channel.mock_handle( :subsystem )
|
47
|
+
@channel.mock_handle( :on_success )
|
48
|
+
@channel.mock_handle( :on_data )
|
49
|
+
@channel.mock_handle( :send_data )
|
50
|
+
|
51
|
+
@connection = FlexMock.new
|
52
|
+
@connection.mock_handle( :open_channel ) { @channel }
|
53
|
+
|
54
|
+
@log = FlexMock.new
|
55
|
+
@log.mock_handle( :debug? )
|
56
|
+
@log.mock_handle( :debug )
|
57
|
+
@log.mock_handle( :info? )
|
58
|
+
@log.mock_handle( :info )
|
59
|
+
|
60
|
+
@dispatchers = FlexMock.new
|
61
|
+
|
62
|
+
@dispatcher = FlexMock.new
|
63
|
+
|
64
|
+
@dispatchers.mock_handle( :[] ) do |v,e|
|
65
|
+
@version = v
|
66
|
+
@extensions = e
|
67
|
+
@dispatcher
|
68
|
+
end
|
69
|
+
|
70
|
+
@driver = Net::SFTP::Protocol::Driver.new( @connection, Buffers.new, 5,
|
71
|
+
@dispatchers, @log )
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_initial_state
|
75
|
+
assert_equal :unconfirmed, @driver.state
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_close
|
79
|
+
@driver.close
|
80
|
+
assert_equal 1, @channel.mock_count( :close )
|
81
|
+
assert_equal :closed, @driver.state
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_next_request_id
|
85
|
+
assert_equal 0, @driver.next_request_id
|
86
|
+
assert_equal 1, @driver.next_request_id
|
87
|
+
assert_equal 2, @driver.next_request_id
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_do_confirm_bad_state
|
91
|
+
force_state :bogus
|
92
|
+
assert_raise( Net::SFTP::Bug ) { @driver.do_confirm @channel }
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_do_confirm
|
96
|
+
force_state :unconfirmed
|
97
|
+
@channel.mock_handle( :subsystem ) { |a| assert_equal "sftp", a }
|
98
|
+
@driver.do_confirm @channel
|
99
|
+
assert_equal 1, @channel.mock_count( :subsystem )
|
100
|
+
assert_equal 1, @channel.mock_count( :on_success )
|
101
|
+
assert_equal 1, @channel.mock_count( :on_data )
|
102
|
+
assert_equal :init, @driver.state
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_do_success_bad_state
|
106
|
+
force_state :bogus
|
107
|
+
assert_raise( Net::SFTP::Bug ) { @driver.do_success @channel }
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_do_success
|
111
|
+
force_state :init
|
112
|
+
packet = nil
|
113
|
+
@channel.mock_handle( :send_data ) { |p| packet = p }
|
114
|
+
@driver.do_success @channel
|
115
|
+
assert_equal 1, @channel.mock_count( :send_data )
|
116
|
+
assert_equal "\0\0\0\5\1\0\0\0\5", packet.to_s
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_version_bad_state
|
120
|
+
force_state :bogus
|
121
|
+
assert_raise( Net::SFTP::Bug ) { @driver.do_version nil }
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_version_server_higher
|
125
|
+
force_state :version
|
126
|
+
@driver.do_version reader( "\0\0\0\7" )
|
127
|
+
assert_equal 5, @version
|
128
|
+
assert_equal Hash.new, @extensions
|
129
|
+
assert_equal :open, @driver.state
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_version_server_lower
|
133
|
+
force_state :version
|
134
|
+
@driver.do_version reader( "\0\0\0\3" )
|
135
|
+
assert_equal 3, @version
|
136
|
+
assert_equal Hash.new, @extensions
|
137
|
+
assert_equal :open, @driver.state
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_version_extensions
|
141
|
+
force_state :version
|
142
|
+
@driver.do_version reader( "\0\0\0\3\0\0\0\1a\0\0\0\1b\0\0\0\1c\0\0\0\1d" )
|
143
|
+
assert_equal( {"a"=>"b","c"=>"d"}, @extensions )
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_version_with_on_open
|
147
|
+
force_state :version
|
148
|
+
called = false
|
149
|
+
@driver.on_open { called = true }
|
150
|
+
@driver.do_version reader( "\0\0\0\3" )
|
151
|
+
assert called
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_do_data_version
|
155
|
+
force_state :version
|
156
|
+
@driver.do_data( nil, "\0\0\0\5\2\0\0\0\3" )
|
157
|
+
assert_equal 1, @dispatchers.mock_count( :[] )
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_do_dispatch
|
161
|
+
# define the dispatcher
|
162
|
+
force_state :version
|
163
|
+
@driver.do_version reader( "\0\0\0\3" )
|
164
|
+
|
165
|
+
channel = type = content = 0
|
166
|
+
@dispatcher.mock_handle( :dispatch ) { |c,t,n|
|
167
|
+
channel, type, content = c,t,n }
|
168
|
+
@driver.do_data( nil, "\0\0\0\5\7\0\0\0\0" )
|
169
|
+
assert_equal 1, @dispatcher.mock_count(:dispatch)
|
170
|
+
assert_nil channel
|
171
|
+
assert_equal 7, type
|
172
|
+
assert_equal "\0\0\0\0", content.to_s
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_do_dispatch_multipass
|
176
|
+
# define the dispatcher
|
177
|
+
force_state :version
|
178
|
+
@driver.do_version reader( "\0\0\0\3" )
|
179
|
+
|
180
|
+
channel = type = content = 0
|
181
|
+
@dispatcher.mock_handle( :dispatch ) { |c,t,n|
|
182
|
+
channel, type, content = c,t,n }
|
183
|
+
@driver.do_data( nil, "\0\0\0\5\7\0\0" )
|
184
|
+
|
185
|
+
assert_equal 0, @dispatcher.mock_count(:dispatch)
|
186
|
+
assert_equal 0, channel
|
187
|
+
assert_equal 0, type
|
188
|
+
assert_equal 0, content
|
189
|
+
|
190
|
+
@driver.do_data( nil, "\0\0" )
|
191
|
+
|
192
|
+
assert_equal 1, @dispatcher.mock_count(:dispatch)
|
193
|
+
assert_nil channel
|
194
|
+
assert_equal 7, type
|
195
|
+
assert_equal "\0\0\0\0", content.to_s
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_method_missing_found
|
199
|
+
force_state :version
|
200
|
+
@driver.do_version reader( "\0\0\0\3" )
|
201
|
+
|
202
|
+
def @dispatcher.respond_to?(sym)
|
203
|
+
super || sym == :foo
|
204
|
+
end
|
205
|
+
|
206
|
+
@dispatcher.mock_handle( :foo )
|
207
|
+
assert @driver.respond_to?( :foo )
|
208
|
+
|
209
|
+
@driver.foo
|
210
|
+
|
211
|
+
assert_equal 1, @dispatcher.mock_count( :foo )
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_method_missing_not_found
|
215
|
+
assert !@driver.respond_to?( :foo )
|
216
|
+
assert_raise( NoMethodError ) { @driver.foo }
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|