File Manager
Viewing File: test_session.rb
require "common"
class SessionTest < Net::SFTP::TestCase
include Net::SFTP::Constants
include Net::SFTP::Constants::OpenFlags
include Net::SFTP::Constants::PacketTypes
(1..6).each do |version|
define_method("test_server_reporting_version_#{version}_should_cause_version_#{version}_to_be_used") do
expect_sftp_session :server_version => version
assert_scripted { sftp.connect! }
assert_equal version, sftp.protocol.version
end
end
def test_v1_open_read_only_that_succeeds_should_invoke_callback
expect_open("/path/to/file", "r", nil, :server_version => 1)
assert_successful_open("/path/to/file")
end
def test_v1_open_read_only_that_fails_should_invoke_callback
expect_open("/path/to/file", "r", nil, :server_version => 1, :fail => 2)
assert_command_with_callback(:open, "/path/to/file") do |response|
assert !response.ok?
assert_equal 2, response.code
end
end
def test_v1_open_write_only_that_succeeds_should_invoke_callback
expect_open("/path/to/file", "w", nil, :server_version => 1)
assert_successful_open("/path/to/file", "w")
end
def test_v1_open_read_write_that_succeeds_should_invoke_callback
expect_open("/path/to/file", "rw", nil, :server_version => 1)
assert_successful_open("/path/to/file", "r+")
end
def test_v1_open_append_that_succeeds_should_invoke_callback
expect_open("/path/to/file", "a", nil, :server_version => 1)
assert_successful_open("/path/to/file", "a")
end
def test_v1_open_with_permissions_should_specify_permissions
expect_open("/path/to/file", "r", 0765, :server_version => 1)
assert_successful_open("/path/to/file", "r", :permissions => 0765)
end
def test_v4_open_with_permissions_should_specify_permissions
expect_open("/path/to/file", "r", 0765, :server_version => 4)
assert_successful_open("/path/to/file", "r", :permissions => 0765)
end
def test_v5_open_read_only_shuld_invoke_callback
expect_open("/path/to/file", "r", 0765, :server_version => 5)
assert_successful_open("/path/to/file", "r", :permissions => 0765)
end
def test_v6_open_with_permissions_should_specify_permissions
expect_open("/path/to/file", "r", 0765, :server_version => 6)
assert_successful_open("/path/to/file", "r", :permissions => 0765)
end
def test_open_bang_should_block_and_return_handle
expect_open("/path/to/file", "r", nil)
handle = assert_synchronous_command(:open!, "/path/to/file", "r")
assert_equal "handle", handle
end
def test_open_bang_should_block_and_raise_exception_on_error
expect_open("/path/to/file", "r", nil, :fail => 5)
assert_raises(Net::SFTP::StatusException) do
assert_synchronous_command(:open!, "/path/to/file", "r")
end
end
def test_close_should_send_close_request_and_invoke_callback
expect_sftp_session do |channel|
channel.sends_packet(FXP_CLOSE, :long, 0, :string, "handle")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:close, "handle") { |r| assert r.ok? }
end
def test_close_bang_should_block_and_return_response
expect_sftp_session do |channel|
channel.sends_packet(FXP_CLOSE, :long, 0, :string, "handle")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:close!, "handle")
assert response.ok?
end
def test_read_should_send_read_request_and_invoke_callback
expect_sftp_session do |channel|
channel.sends_packet(FXP_READ, :long, 0, :string, "handle", :int64, 512123, :long, 1024)
channel.gets_packet(FXP_DATA, :long, 0, :string, "this is some data!")
end
assert_command_with_callback(:read, "handle", 512123, 1024) do |response|
assert response.ok?
assert_equal "this is some data!", response[:data]
end
end
def test_read_bang_should_block_and_return_data
expect_sftp_session do |channel|
channel.sends_packet(FXP_READ, :long, 0, :string, "handle", :int64, 512123, :long, 1024)
channel.gets_packet(FXP_DATA, :long, 0, :string, "this is some data!")
end
data = assert_synchronous_command(:read!, "handle", 512123, 1024)
assert_equal "this is some data!", data
end
def test_read_bang_should_block_and_return_nil_on_eof
expect_sftp_session do |channel|
channel.sends_packet(FXP_READ, :long, 0, :string, "handle", :int64, 512123, :long, 1024)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 1)
end
data = assert_synchronous_command(:read!, "handle", 512123, 1024)
assert_nil data
end
def test_write_should_send_write_request_and_invoke_callback
expect_sftp_session do |channel|
channel.sends_packet(FXP_WRITE, :long, 0, :string, "handle", :int64, 512123, :string, "this is some data!")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:write, "handle", 512123, "this is some data!") do |response|
assert response.ok?
end
end
def test_write_bang_should_block_and_return_response
expect_sftp_session do |channel|
channel.sends_packet(FXP_WRITE, :long, 0, :string, "handle", :int64, 512123, :string, "this is some data!")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:write!, "handle", 512123, "this is some data!")
assert response.ok?
end
def test_v1_lstat_should_send_lstat_request_and_invoke_callback
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_LSTAT, :long, 0, :string, "/path/to/file")
channel.gets_packet(FXP_ATTRS, :long, 0, :long, 0xF, :int64, 123456, :long, 1, :long, 2, :long, 0765, :long, 123456789, :long, 234567890)
end
assert_command_with_callback(:lstat, "/path/to/file") do |response|
assert response.ok?
assert_equal 123456, response[:attrs].size
assert_equal 1, response[:attrs].uid
assert_equal 2, response[:attrs].gid
assert_equal 0765, response[:attrs].permissions
assert_equal 123456789, response[:attrs].atime
assert_equal 234567890, response[:attrs].mtime
end
end
def test_v4_lstat_should_send_default_flags_parameter
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_LSTAT, :long, 0, :string, "/path/to/file", :long, 0x800001fd)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:lstat, "/path/to/file")
end
def test_v4_lstat_should_honor_flags_parameter
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_LSTAT, :long, 0, :string, "/path/to/file", :long, 0x1)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:lstat, "/path/to/file", 0x1)
end
def test_lstat_bang_should_block_and_return_attrs
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_LSTAT, :long, 0, :string, "/path/to/file")
channel.gets_packet(FXP_ATTRS, :long, 0, :long, 0xF, :int64, 123456, :long, 1, :long, 2, :long, 0765, :long, 123456789, :long, 234567890)
end
attrs = assert_synchronous_command(:lstat!, "/path/to/file")
assert_equal 123456, attrs.size
assert_equal 1, attrs.uid
assert_equal 2, attrs.gid
assert_equal 0765, attrs.permissions
assert_equal 123456789, attrs.atime
assert_equal 234567890, attrs.mtime
end
def test_v1_fstat_should_send_fstat_request_and_invoke_callback
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_FSTAT, :long, 0, :string, "handle")
channel.gets_packet(FXP_ATTRS, :long, 0, :long, 0xF, :int64, 123456, :long, 1, :long, 2, :long, 0765, :long, 123456789, :long, 234567890)
end
assert_command_with_callback(:fstat, "handle") do |response|
assert response.ok?
assert_equal 123456, response[:attrs].size
assert_equal 1, response[:attrs].uid
assert_equal 2, response[:attrs].gid
assert_equal 0765, response[:attrs].permissions
assert_equal 123456789, response[:attrs].atime
assert_equal 234567890, response[:attrs].mtime
end
end
def test_v4_fstat_should_send_default_flags_parameter
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_FSTAT, :long, 0, :string, "handle", :long, 0x800001fd)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:fstat, "handle")
end
def test_v4_fstat_should_honor_flags_parameter
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_FSTAT, :long, 0, :string, "handle", :long, 0x1)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:fstat, "handle", 0x1)
end
def test_fstat_bang_should_block_and_return_attrs
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_FSTAT, :long, 0, :string, "handle")
channel.gets_packet(FXP_ATTRS, :long, 0, :long, 0xF, :int64, 123456, :long, 1, :long, 2, :long, 0765, :long, 123456789, :long, 234567890)
end
attrs = assert_synchronous_command(:fstat!, "handle")
assert_equal 123456, attrs.size
assert_equal 1, attrs.uid
assert_equal 2, attrs.gid
assert_equal 0765, attrs.permissions
assert_equal 123456789, attrs.atime
assert_equal 234567890, attrs.mtime
end
def test_v1_setstat_should_send_v1_attributes
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_SETSTAT, :long, 0, :string, "/path/to/file", :long, 0xc, :long, 0765, :long, 1234567890, :long, 2345678901)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:setstat, "/path/to/file", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901)
end
def test_v4_setstat_should_send_v4_attributes
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_SETSTAT, :long, 0, :string, "/path/to/file", :long, 0x2c, :byte, 1, :long, 0765, :int64, 1234567890, :int64, 2345678901)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:setstat, "/path/to/file", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901)
end
def test_v6_setstat_should_send_v6_attributes
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_SETSTAT, :long, 0, :string, "/path/to/file", :long, 0x102c, :byte, 1, :long, 0765, :int64, 1234567890, :int64, 2345678901, :string, "text/plain")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:setstat, "/path/to/file", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901, :mime_type => "text/plain")
end
def test_setstat_bang_should_block_and_return_response
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_SETSTAT, :long, 0, :string, "/path/to/file", :long, 0xc, :long, 0765, :long, 1234567890, :long, 2345678901)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:setstat!, "/path/to/file", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901)
assert response.ok?
end
def test_v1_fsetstat_should_send_v1_attributes
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_FSETSTAT, :long, 0, :string, "handle", :long, 0xc, :long, 0765, :long, 1234567890, :long, 2345678901)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:fsetstat, "handle", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901)
end
def test_v4_fsetstat_should_send_v4_attributes
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_FSETSTAT, :long, 0, :string, "handle", :long, 0x2c, :byte, 1, :long, 0765, :int64, 1234567890, :int64, 2345678901)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:fsetstat, "handle", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901)
end
def test_v6_fsetstat_should_send_v6_attributes
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_FSETSTAT, :long, 0, :string, "handle", :long, 0x102c, :byte, 1, :long, 0765, :int64, 1234567890, :int64, 2345678901, :string, "text/plain")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:fsetstat, "handle", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901, :mime_type => "text/plain")
end
def test_fsetstat_bang_should_block_and_return_response
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_FSETSTAT, :long, 0, :string, "handle", :long, 0xc, :long, 0765, :long, 1234567890, :long, 2345678901)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:fsetstat!, "handle", :permissions => 0765, :atime => 1234567890, :mtime => 2345678901)
assert response.ok?
end
def test_opendir_should_send_opendir_request_and_invoke_callback
expect_sftp_session do |channel|
channel.sends_packet(FXP_OPENDIR, :long, 0, :string, "/path/to/dir")
channel.gets_packet(FXP_HANDLE, :long, 0, :string, "handle")
end
assert_command_with_callback(:opendir, "/path/to/dir")
end
def test_opendir_bang_should_block_and_return_handle
expect_sftp_session do |channel|
channel.sends_packet(FXP_OPENDIR, :long, 0, :string, "/path/to/dir")
channel.gets_packet(FXP_HANDLE, :long, 0, :string, "handle")
end
handle = assert_synchronous_command(:opendir!, "/path/to/dir")
assert_equal "handle", handle
end
def test_readdir_should_send_readdir_request_and_invoke_callback
expect_sftp_session do |channel|
channel.sends_packet(FXP_READDIR, :long, 0, :string, "handle")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 1)
end
assert_command_with_callback(:readdir, "handle") { |r| assert r.eof? }
end
def test_readdir_bang_should_block_and_return_names_array
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_READDIR, :long, 0, :string, "handle")
channel.gets_packet(FXP_NAME, :long, 0, :long, 2,
:string, "first", :string, "longfirst", :long, 0x0,
:string, "next", :string, "longnext", :long, 0x0)
end
names = assert_synchronous_command(:readdir!, "handle")
assert_equal 2, names.length
assert_equal %w(first next), names.map { |n| n.name }
end
def test_remove_should_send_remove_packet
expect_sftp_session do |channel|
channel.sends_packet(FXP_REMOVE, :long, 0, :string, "/path/to/file")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:remove, "/path/to/file")
end
def test_remove_bang_should_block_and_return_response
expect_sftp_session do |channel|
channel.sends_packet(FXP_REMOVE, :long, 0, :string, "/path/to/file")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:remove!, "/path/to/file")
assert response.ok?
end
def test_mkdir_should_send_mkdir_packet
expect_sftp_session do |channel|
channel.sends_packet(FXP_MKDIR, :long, 0, :string, "/path/to/dir", :long, 0x4, :byte, 1, :long, 0765)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:mkdir, "/path/to/dir", :permissions => 0765)
end
def test_mkdir_bang_should_block_and_return_response
expect_sftp_session do |channel|
channel.sends_packet(FXP_MKDIR, :long, 0, :string, "/path/to/dir", :long, 0x4, :byte, 1, :long, 0765)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:mkdir!, "/path/to/dir", :permissions => 0765)
assert response.ok?
end
def test_rmdir_should_send_rmdir_packet
expect_sftp_session do |channel|
channel.sends_packet(FXP_RMDIR, :long, 0, :string, "/path/to/dir")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:rmdir, "/path/to/dir")
end
def test_rmdir_bang_should_block_and_return_response
expect_sftp_session do |channel|
channel.sends_packet(FXP_RMDIR, :long, 0, :string, "/path/to/dir")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:rmdir!, "/path/to/dir")
assert response.ok?
end
def test_realpath_should_send_realpath_packet
expect_sftp_session do |channel|
channel.sends_packet(FXP_REALPATH, :long, 0, :string, "/path/to/dir")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:realpath, "/path/to/dir")
end
def test_realpath_bang_should_block_and_return_names_item
expect_sftp_session do |channel|
channel.sends_packet(FXP_REALPATH, :long, 0, :string, "/path/to/dir")
channel.gets_packet(FXP_NAME, :long, 0, :long, 1, :string, "dir", :long, 0x0, :long, 2)
end
name = assert_synchronous_command(:realpath!, "/path/to/dir")
assert_equal "dir", name.name
end
def test_v1_stat_should_send_stat_request_and_invoke_callback
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_STAT, :long, 0, :string, "/path/to/file")
channel.gets_packet(FXP_ATTRS, :long, 0, :long, 0xF, :int64, 123456, :long, 1, :long, 2, :long, 0765, :long, 123456789, :long, 234567890)
end
assert_command_with_callback(:stat, "/path/to/file") do |response|
assert response.ok?
assert_equal 123456, response[:attrs].size
assert_equal 1, response[:attrs].uid
assert_equal 2, response[:attrs].gid
assert_equal 0765, response[:attrs].permissions
assert_equal 123456789, response[:attrs].atime
assert_equal 234567890, response[:attrs].mtime
end
end
def test_v4_stat_should_send_default_flags_parameter
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_STAT, :long, 0, :string, "/path/to/file", :long, 0x800001fd)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:stat, "/path/to/file")
end
def test_v4_stat_should_honor_flags_parameter
expect_sftp_session :server_version => 4 do |channel|
channel.sends_packet(FXP_STAT, :long, 0, :string, "/path/to/file", :long, 0x1)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:stat, "/path/to/file", 0x1)
end
def test_stat_bang_should_block_and_return_attrs
expect_sftp_session :server_version => 1 do |channel|
channel.sends_packet(FXP_STAT, :long, 0, :string, "/path/to/file")
channel.gets_packet(FXP_ATTRS, :long, 0, :long, 0xF, :int64, 123456, :long, 1, :long, 2, :long, 0765, :long, 123456789, :long, 234567890)
end
attrs = assert_synchronous_command(:stat!, "/path/to/file")
assert_equal 123456, attrs.size
assert_equal 1, attrs.uid
assert_equal 2, attrs.gid
assert_equal 0765, attrs.permissions
assert_equal 123456789, attrs.atime
assert_equal 234567890, attrs.mtime
end
def test_v1_rename_should_be_unimplemented
assert_not_implemented 1, :rename, "from", "to"
end
def test_v2_rename_should_send_rename_packet
expect_sftp_session :server_version => 2 do |channel|
channel.sends_packet(FXP_RENAME, :long, 0, :string, "from", :string, "to")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:rename, "from", "to")
end
def test_v5_rename_should_send_rename_packet_and_default_flags
expect_sftp_session :server_version => 5 do |channel|
channel.sends_packet(FXP_RENAME, :long, 0, :string, "from", :string, "to", :long, 0)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:rename, "from", "to")
end
def test_v5_rename_should_send_rename_packet_and_honor_flags
expect_sftp_session :server_version => 5 do |channel|
channel.sends_packet(FXP_RENAME, :long, 0, :string, "from", :string, "to", :long, 1)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:rename, "from", "to", 1)
end
def test_rename_bang_should_block_and_return_response
expect_sftp_session :server_version => 2 do |channel|
channel.sends_packet(FXP_RENAME, :long, 0, :string, "from", :string, "to")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:rename!, "from", "to")
assert response.ok?
end
def test_v2_readlink_should_be_unimplemented
assert_not_implemented 2, :readlink, "/path/to/link"
end
def test_v3_readlink_should_send_readlink_packet
expect_sftp_session :server_version => 3 do |channel|
channel.sends_packet(FXP_READLINK, :long, 0, :string, "/path/to/link")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 2)
end
assert_command_with_callback(:readlink, "/path/to/link")
end
def test_readlink_bang_should_block_and_return_name
expect_sftp_session :server_version => 3 do |channel|
channel.sends_packet(FXP_READLINK, :long, 0, :string, "/path/to/link")
channel.gets_packet(FXP_NAME, :long, 0, :long, 1, :string, "target", :string, "longtarget", :long, 0x0)
end
name = assert_synchronous_command(:readlink!, "/path/to/link")
assert_equal "target", name.name
end
def test_v2_symlink_should_be_unimplemented
assert_not_implemented 2, :symlink, "/path/to/source", "/path/to/link"
end
def test_v3_symlink_should_send_symlink_packet
expect_sftp_session :server_version => 3 do |channel|
channel.sends_packet(FXP_SYMLINK, :long, 0, :string, "/path/to/source", :string, "/path/to/link")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:symlink, "/path/to/source", "/path/to/link")
end
def test_v6_symlink_should_send_link_packet
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_LINK, :long, 0, :string, "/path/to/link", :string, "/path/to/source", :bool, true)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:symlink, "/path/to/link", "/path/to/source")
end
def test_symlink_bang_should_block_and_return_response
expect_sftp_session :server_version => 3 do |channel|
channel.sends_packet(FXP_SYMLINK, :long, 0, :string, "/path/to/source", :string, "/path/to/link")
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:symlink!, "/path/to/source", "/path/to/link")
assert response.ok?
end
def test_v5_link_should_be_unimplemented
assert_not_implemented 5, :link, "/path/to/source", "/path/to/link", true
end
def test_v6_link_should_send_link_packet
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_LINK, :long, 0, :string, "/path/to/link", :string, "/path/to/source", :bool, true)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:link, "/path/to/link", "/path/to/source", true)
end
def test_link_bang_should_block_and_return_response
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_LINK, :long, 0, :string, "/path/to/link", :string, "/path/to/source", :bool, true)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:link!, "/path/to/link", "/path/to/source", true)
assert response.ok?
end
def test_v5_block_should_be_unimplemented
assert_not_implemented 5, :block, "handle", 12345, 67890, 0xabcd
end
def test_v6_block_should_send_block_packet
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_BLOCK, :long, 0, :string, "handle", :int64, 12345, :int64, 67890, :long, 0xabcd)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:block, "handle", 12345, 67890, 0xabcd)
end
def test_block_bang_should_block_and_return_response
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_BLOCK, :long, 0, :string, "handle", :int64, 12345, :int64, 67890, :long, 0xabcd)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:block!, "handle", 12345, 67890, 0xabcd)
assert response.ok?
end
def test_v5_unblock_should_be_unimplemented
assert_not_implemented 5, :unblock, "handle", 12345, 67890
end
def test_v6_unblock_should_send_block_packet
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_UNBLOCK, :long, 0, :string, "handle", :int64, 12345, :int64, 67890)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
assert_command_with_callback(:unblock, "handle", 12345, 67890)
end
def test_unblock_bang_should_block_and_return_response
expect_sftp_session :server_version => 6 do |channel|
channel.sends_packet(FXP_UNBLOCK, :long, 0, :string, "handle", :int64, 12345, :int64, 67890)
channel.gets_packet(FXP_STATUS, :long, 0, :long, 0)
end
response = assert_synchronous_command(:unblock!, "handle", 12345, 67890)
assert response.ok?
end
private
def assert_not_implemented(server_version, command, *args)
expect_sftp_session :server_version => 1
sftp.connect!
assert_raises(NotImplementedError) { sftp.send(command, *args) }
end
def assert_command_with_callback(command, *args)
called = false
assert_scripted_command do
sftp.send(command, *args) do |response|
called = true
yield response if block_given?
end
end
assert called, "expected callback to be invoked, but it wasn't"
end
def assert_synchronous_command(command, *args)
assert_scripted_command do
sequence = [:start]
result = sftp.send(command, *args) do |response|
sequence << :done
yield response if block_given?
end
sequence << :after
assert_equal [:start, :done, :after], sequence, "expected #{command} to be synchronous"
return result
end
end
def assert_successful_open(*args)
assert_command_with_callback(:open, *args) do |response|
assert response.ok?
assert_equal "handle", response[:handle]
end
end
def expect_open(path, mode, perms, options={})
version = options[:server_version] || 6
fail = options.delete(:fail)
attrs = [:long, perms ? 0x4 : 0]
attrs += [:byte, 1] if version >= 4
attrs += [:long, perms] if perms
expect_sftp_session(options) do |channel|
if version >= 5
flags, access = case mode
when "r" then
[FV5::OPEN_EXISTING, ACE::Mask::READ_DATA | ACE::Mask::READ_ATTRIBUTES]
when "w" then
[FV5::CREATE_TRUNCATE, ACE::Mask::WRITE_DATA | ACE::Mask::WRITE_ATTRIBUTES]
when "rw" then
[FV5::OPEN_OR_CREATE, ACE::Mask::READ_DATA | ACE::Mask::READ_ATTRIBUTES | ACE::Mask::WRITE_DATA | ACE::Mask::WRITE_ATTRIBUTES]
when "a" then
[FV5::OPEN_OR_CREATE | FV5::APPEND_DATA, ACE::Mask::WRITE_DATA | ACE::Mask::WRITE_ATTRIBUTES | ACE::Mask::APPEND_DATA]
else raise ArgumentError, "unsupported mode #{mode.inspect}"
end
channel.sends_packet(FXP_OPEN, :long, 0, :string, path, :long, access, :long, flags, *attrs)
else
flags = case mode
when "r" then FV1::READ
when "w" then FV1::WRITE | FV1::TRUNC | FV1::CREAT
when "rw" then FV1::WRITE | FV1::READ
when "a" then FV1::APPEND | FV1::WRITE | FV1::CREAT
else raise ArgumentError, "unsupported mode #{mode.inspect}"
end
channel.sends_packet(FXP_OPEN, :long, 0, :string, path, :long, flags, *attrs)
end
if fail
channel.gets_packet(FXP_STATUS, :long, 0, :long, fail)
else
channel.gets_packet(FXP_HANDLE, :long, 0, :string, "handle")
end
end
end
end