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.
Files changed (77) hide show
  1. data/doc/LICENSE-BSD +27 -0
  2. data/doc/LICENSE-GPL +280 -0
  3. data/doc/LICENSE-RUBY +56 -0
  4. data/examples/asynchronous.rb +57 -0
  5. data/examples/ssh-service.rb +31 -0
  6. data/examples/synchronous.rb +120 -0
  7. data/lib/net/sftp.rb +39 -0
  8. data/lib/net/sftp/errors.rb +25 -0
  9. data/lib/net/sftp/operations/abstract.rb +103 -0
  10. data/lib/net/sftp/operations/close.rb +31 -0
  11. data/lib/net/sftp/operations/errors.rb +76 -0
  12. data/lib/net/sftp/operations/fsetstat.rb +36 -0
  13. data/lib/net/sftp/operations/fstat.rb +32 -0
  14. data/lib/net/sftp/operations/lstat.rb +31 -0
  15. data/lib/net/sftp/operations/mkdir.rb +33 -0
  16. data/lib/net/sftp/operations/open.rb +32 -0
  17. data/lib/net/sftp/operations/opendir.rb +32 -0
  18. data/lib/net/sftp/operations/read.rb +84 -0
  19. data/lib/net/sftp/operations/readdir.rb +55 -0
  20. data/lib/net/sftp/operations/realpath.rb +37 -0
  21. data/lib/net/sftp/operations/remove.rb +31 -0
  22. data/lib/net/sftp/operations/rename.rb +32 -0
  23. data/lib/net/sftp/operations/rmdir.rb +31 -0
  24. data/lib/net/sftp/operations/services.rb +42 -0
  25. data/lib/net/sftp/operations/setstat.rb +33 -0
  26. data/lib/net/sftp/operations/stat.rb +31 -0
  27. data/lib/net/sftp/operations/write.rb +63 -0
  28. data/lib/net/sftp/protocol/01/attributes.rb +146 -0
  29. data/lib/net/sftp/protocol/01/impl.rb +251 -0
  30. data/lib/net/sftp/protocol/01/packet-assistant.rb +82 -0
  31. data/lib/net/sftp/protocol/01/services.rb +47 -0
  32. data/lib/net/sftp/protocol/02/impl.rb +39 -0
  33. data/lib/net/sftp/protocol/02/packet-assistant.rb +32 -0
  34. data/lib/net/sftp/protocol/02/services.rb +44 -0
  35. data/lib/net/sftp/protocol/03/impl.rb +42 -0
  36. data/lib/net/sftp/protocol/03/packet-assistant.rb +35 -0
  37. data/lib/net/sftp/protocol/03/services.rb +44 -0
  38. data/lib/net/sftp/protocol/04/attributes.rb +227 -0
  39. data/lib/net/sftp/protocol/04/impl.rb +134 -0
  40. data/lib/net/sftp/protocol/04/packet-assistant.rb +51 -0
  41. data/lib/net/sftp/protocol/04/services.rb +44 -0
  42. data/lib/net/sftp/protocol/05/services.rb +44 -0
  43. data/lib/net/sftp/protocol/constants.rb +60 -0
  44. data/lib/net/sftp/protocol/driver.rb +232 -0
  45. data/lib/net/sftp/protocol/packet-assistant.rb +84 -0
  46. data/lib/net/sftp/protocol/services.rb +55 -0
  47. data/lib/net/sftp/session.rb +215 -0
  48. data/lib/net/sftp/version.rb +25 -0
  49. data/test/ALL-TESTS.rb +21 -0
  50. data/test/operations/tc_abstract.rb +124 -0
  51. data/test/operations/tc_close.rb +40 -0
  52. data/test/operations/tc_fsetstat.rb +48 -0
  53. data/test/operations/tc_fstat.rb +40 -0
  54. data/test/operations/tc_lstat.rb +40 -0
  55. data/test/operations/tc_mkdir.rb +48 -0
  56. data/test/operations/tc_open.rb +42 -0
  57. data/test/operations/tc_opendir.rb +40 -0
  58. data/test/operations/tc_read.rb +103 -0
  59. data/test/operations/tc_readdir.rb +88 -0
  60. data/test/operations/tc_realpath.rb +54 -0
  61. data/test/operations/tc_remove.rb +40 -0
  62. data/test/operations/tc_rmdir.rb +40 -0
  63. data/test/operations/tc_setstat.rb +48 -0
  64. data/test/operations/tc_stat.rb +40 -0
  65. data/test/operations/tc_write.rb +91 -0
  66. data/test/protocol/01/tc_attributes.rb +138 -0
  67. data/test/protocol/01/tc_impl.rb +294 -0
  68. data/test/protocol/01/tc_packet_assistant.rb +81 -0
  69. data/test/protocol/02/tc_impl.rb +41 -0
  70. data/test/protocol/02/tc_packet_assistant.rb +31 -0
  71. data/test/protocol/03/tc_impl.rb +48 -0
  72. data/test/protocol/03/tc_packet_assistant.rb +34 -0
  73. data/test/protocol/04/tc_attributes.rb +174 -0
  74. data/test/protocol/04/tc_impl.rb +102 -0
  75. data/test/protocol/04/tc_packet_assistant.rb +41 -0
  76. data/test/protocol/tc_driver.rb +219 -0
  77. 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