net-scp 1.2.1 → 1.2.2.rc2
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +6 -0
- data/.travis.yml +4 -3
- data/Gemfile +15 -0
- data/README.rdoc +1 -1
- data/Rakefile +48 -26
- data/lib/net/scp.rb +8 -8
- data/lib/net/scp/download.rb +5 -5
- data/lib/net/scp/version.rb +63 -13
- data/net-scp-public_cert.pem +21 -0
- data/net-scp.gemspec +35 -56
- metadata +50 -59
- metadata.gz.sig +1 -1
- data/gem-public_cert.pem +0 -20
- data/test/common.rb +0 -153
- data/test/test_all.rb +0 -3
- data/test/test_download.rb +0 -197
- data/test/test_scp.rb +0 -60
- data/test/test_upload.rb +0 -269
metadata.gz.sig
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
�O���v}m���!��F1��u�:�:+�;icO'z�2�&x39�0�b��[��ۭ�{21�]�:2XL�Kf �������F�L�7�L��4��+�Rx�����
|
data/gem-public_cert.pem
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
2
|
-
MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQ8wDQYDVQQDDAZkZWxh
|
3
|
-
bm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
|
4
|
-
b20wHhcNMTQwNDMwMTczNjI2WhcNMTUwNDMwMTczNjI2WjBBMQ8wDQYDVQQDDAZk
|
5
|
-
ZWxhbm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
|
6
|
-
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdbeFjM67+Txrq
|
7
|
-
+8HaD4wKEiacRoB8ps17Vzt9TBUyoMMj5KTtFiptr/+ZTug/YdYBquMprPsKlYM2
|
8
|
-
NoG6BzvDcvQK1zrdHnyVosIDKAHk2wnyN/psZikS1bo9nUHCS5hJdPEnQZx/MxTZ
|
9
|
-
+GjuRsiBxPYBXnqObLhR83LBeWsauWTuo5gJt1DYxDTVrLoB+Z+ceMV+3vh0HBCb
|
10
|
-
iwegkx9GWG45h5wTksUIpzOMB3VsHGtGmBjCvdCgLJ2H6b8U9rmL7chunjdqfNf3
|
11
|
-
zPtnH32c/zrFzeWJTyH2s8Ia+3D6vum2xjjn8FnLg3V4zOf5x598GFBJYDQv7zX/
|
12
|
-
rV9eCzHDAgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFA+Buc8ySEw2qKnq
|
13
|
-
VH4wh8KAm6hUMAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAYsM0M42h
|
14
|
-
ZEUXvr/i18gkwHKLFDKDAcimgCoS5+syG6rkuSOnKGQolyKTNczNM4gWJJPH5aVq
|
15
|
-
mW2BtqpIom4YRYb9m3fDNNs6kcB5DedY9UPhVvJ8XTTB2YLxLql7UJid9ZOiqWzC
|
16
|
-
OTm06w7zkAT/ldt46p6BqyUy6PW4QMg0Bq7SMfRURVrp2lvhQvBdC7oDR9CGEBZC
|
17
|
-
/Ci++ZEh/QR9qy11AHciEIXnNkytidyZtLr4MWhtbV468y6shpPYdKU/uCINSgvt
|
18
|
-
FpMAM5Nit8L8nHwf3IIUPg7lsMCRzOkQ/FD87BI3V3SnFNoTCdGgnGj3jfW4zRlL
|
19
|
-
iFyareFPA84btQ==
|
20
|
-
-----END CERTIFICATE-----
|
data/test/common.rb
DELETED
@@ -1,153 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'mocha/setup'
|
3
|
-
|
4
|
-
begin
|
5
|
-
gem 'net-ssh', ">= 2.0.0"
|
6
|
-
require 'net/ssh'
|
7
|
-
rescue LoadError
|
8
|
-
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../net-ssh/lib"
|
9
|
-
|
10
|
-
begin
|
11
|
-
require 'net/ssh'
|
12
|
-
require 'net/ssh/version'
|
13
|
-
raise LoadError, "wrong version" unless Net::SSH::Version::STRING >= '1.99.0'
|
14
|
-
rescue LoadError => e
|
15
|
-
abort "could not load net/ssh v2 (#{e.inspect})"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
20
|
-
|
21
|
-
require 'net/scp'
|
22
|
-
require 'net/ssh/test'
|
23
|
-
|
24
|
-
class Net::SSH::Test::Channel
|
25
|
-
def gets_ok
|
26
|
-
gets_data "\0"
|
27
|
-
end
|
28
|
-
|
29
|
-
def sends_ok
|
30
|
-
sends_data "\0"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class Net::SCP::TestCase < Test::Unit::TestCase
|
35
|
-
include Net::SSH::Test
|
36
|
-
|
37
|
-
def default_test
|
38
|
-
# do nothing, this is just a hacky-hack to work around Test::Unit's
|
39
|
-
# insistence that all TestCase subclasses have at least one test
|
40
|
-
# method defined.
|
41
|
-
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
def prepare_file(path, contents="", mode=0666, mtime=Time.now, atime=Time.now)
|
46
|
-
entry = FileEntry.new(path, contents, mode, mtime, atime)
|
47
|
-
entry.stub!
|
48
|
-
entry
|
49
|
-
end
|
50
|
-
|
51
|
-
def prepare_directory(path, mode=0777, mtime=Time.now, atime=Time.now)
|
52
|
-
directory = DirectoryEntry.new(path, mode, mtime, atime)
|
53
|
-
yield directory if block_given?
|
54
|
-
directory.stub!
|
55
|
-
end
|
56
|
-
|
57
|
-
# The POSIX spec unfortunately allows all characters in file names except
|
58
|
-
# ASCII 0x00(NUL) and 0x2F(/)
|
59
|
-
#
|
60
|
-
# Ideally, we should be testing filenames with newlines, but Mocha doesn't
|
61
|
-
# like this at all, so we leave them out. However, the Shellwords module
|
62
|
-
# handles newlines just fine, so we can be reasonably confident that they
|
63
|
-
# will work in practice
|
64
|
-
def awful_file_name
|
65
|
-
(((0x00..0x7f).to_a - [0x00, 0x0a, 0x2f]).map { |n| n.chr }).join + '.txt'
|
66
|
-
end
|
67
|
-
|
68
|
-
def escaped_file_name
|
69
|
-
"\\\001\\\002\\\003\\\004\\\005\\\006\\\a\\\b\\\t\\\v\\\f\\\r\\\016\\\017\\\020\\\021\\\022\\\023\\\024\\\025\\\026\\\027\\\030\\\031\\\032\\\e\\\034\\\035\\\036\\\037\\ \\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+,-.0123456789:\\;\\<\\=\\>\\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\[\\\\\\]\\^_\\`abcdefghijklmnopqrstuvwxyz\\{\\|\\}\\~\\\177.txt"
|
70
|
-
end
|
71
|
-
|
72
|
-
class FileEntry
|
73
|
-
attr_reader :path, :contents, :mode, :mtime, :atime, :io
|
74
|
-
|
75
|
-
def initialize(path, contents, mode=0666, mtime=Time.now, atime=Time.now)
|
76
|
-
@path, @contents, @mode = path, contents, mode
|
77
|
-
@mtime, @atime = mtime, atime
|
78
|
-
end
|
79
|
-
|
80
|
-
def name
|
81
|
-
@name ||= File.basename(path)
|
82
|
-
end
|
83
|
-
|
84
|
-
def stub!
|
85
|
-
stat = Mocha::Mock.new("file::stat")
|
86
|
-
stat.stubs(:size => contents.length, :mode => mode, :mtime => mtime, :atime => atime, :directory? => false)
|
87
|
-
|
88
|
-
File.stubs(:stat).with(path).returns(stat)
|
89
|
-
File.stubs(:directory?).with(path).returns(false)
|
90
|
-
File.stubs(:file?).with(path).returns(true)
|
91
|
-
File.stubs(:open).with(path, "rb").returns(StringIO.new(contents))
|
92
|
-
|
93
|
-
@io = StringIO.new
|
94
|
-
File.stubs(:new).with(path, "wb", mode).returns(io)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
class DirectoryEntry
|
99
|
-
attr_reader :path, :mode, :mtime, :atime
|
100
|
-
attr_reader :entries
|
101
|
-
|
102
|
-
def initialize(path, mode=0777, mtime=Time.now, atime=Time.now)
|
103
|
-
@path, @mode = path, mode
|
104
|
-
@mtime, @atime = mtime, atime
|
105
|
-
@entries = []
|
106
|
-
end
|
107
|
-
|
108
|
-
def name
|
109
|
-
@name ||= File.basename(path)
|
110
|
-
end
|
111
|
-
|
112
|
-
def file(name, *args)
|
113
|
-
(entries << FileEntry.new(File.join(path, name), *args)).last
|
114
|
-
end
|
115
|
-
|
116
|
-
def directory(name, *args)
|
117
|
-
entry = DirectoryEntry.new(File.join(path, name), *args)
|
118
|
-
yield entry if block_given?
|
119
|
-
(entries << entry).last
|
120
|
-
end
|
121
|
-
|
122
|
-
def stub!
|
123
|
-
Dir.stubs(:mkdir).with { |*a| a.first == path }
|
124
|
-
|
125
|
-
stat = Mocha::Mock.new("file::stat")
|
126
|
-
stat.stubs(:size => 1024, :mode => mode, :mtime => mtime, :atime => atime, :directory? => true)
|
127
|
-
|
128
|
-
File.stubs(:stat).with(path).returns(stat)
|
129
|
-
File.stubs(:directory?).with(path).returns(true)
|
130
|
-
File.stubs(:file?).with(path).returns(false)
|
131
|
-
Dir.stubs(:entries).with(path).returns(%w(. ..) + entries.map { |e| e.name }.sort)
|
132
|
-
|
133
|
-
entries.each { |e| e.stub! }
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def expect_scp_session(arguments)
|
138
|
-
story do |session|
|
139
|
-
channel = session.opens_channel
|
140
|
-
channel.sends_exec "scp #{arguments}"
|
141
|
-
yield channel if block_given?
|
142
|
-
channel.sends_eof
|
143
|
-
channel.gets_exit_status
|
144
|
-
channel.gets_eof
|
145
|
-
channel.gets_close
|
146
|
-
channel.sends_close
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def scp(options={})
|
151
|
-
@scp ||= Net::SCP.new(connection(options))
|
152
|
-
end
|
153
|
-
end
|
data/test/test_all.rb
DELETED
data/test/test_download.rb
DELETED
@@ -1,197 +0,0 @@
|
|
1
|
-
require 'common'
|
2
|
-
|
3
|
-
class TestDownload < Net::SCP::TestCase
|
4
|
-
def test_download_file_should_transfer_file
|
5
|
-
file = prepare_file("/path/to/local.txt", "a" * 1234)
|
6
|
-
|
7
|
-
expect_scp_session "-f /path/to/remote.txt" do |channel|
|
8
|
-
simple_download(channel)
|
9
|
-
end
|
10
|
-
|
11
|
-
assert_scripted { scp.download!("/path/to/remote.txt", "/path/to/local.txt") }
|
12
|
-
assert_equal "a" * 1234, file.io.string
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_download_file_with_spaces_in_name_should_escape_remote_file_name
|
16
|
-
file = prepare_file("/path/to/local file.txt", "")
|
17
|
-
|
18
|
-
expect_scp_session "-f /path/to/remote\\ file.txt" do |channel|
|
19
|
-
channel.sends_ok
|
20
|
-
channel.gets_data "C0666 0 local file.txt\n"
|
21
|
-
channel.sends_ok
|
22
|
-
channel.gets_ok
|
23
|
-
channel.sends_ok
|
24
|
-
end
|
25
|
-
|
26
|
-
assert_scripted { scp.download!("/path/to/remote file.txt", "/path/to/local file.txt") }
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_download_file_with_metacharacters_in_name_should_escape_remote_file_name
|
30
|
-
file = prepare_file("/path/to/local/#{awful_file_name}", "")
|
31
|
-
|
32
|
-
expect_scp_session "-f /path/to/remote/#{escaped_file_name}" do |channel|
|
33
|
-
channel.sends_ok
|
34
|
-
channel.gets_data "C0666 0 #{awful_file_name}\n"
|
35
|
-
channel.sends_ok
|
36
|
-
channel.gets_ok
|
37
|
-
channel.sends_ok
|
38
|
-
end
|
39
|
-
|
40
|
-
assert_scripted { scp.download!("/path/to/remote/#{awful_file_name}", "/path/to/local/#{awful_file_name}") }
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_download_with_preserve_should_send_times
|
44
|
-
file = prepare_file("/path/to/local.txt", "a" * 1234, 0644, Time.at(1234567890, 123456), Time.at(12121212, 232323))
|
45
|
-
|
46
|
-
expect_scp_session "-f -p /path/to/remote.txt" do |channel|
|
47
|
-
channel.sends_ok
|
48
|
-
channel.gets_data "T1234567890 123456 12121212 232323\n"
|
49
|
-
simple_download(channel, 0644)
|
50
|
-
end
|
51
|
-
|
52
|
-
File.expects(:utime).with(Time.at(12121212, 232323), Time.at(1234567890, 123456), "/path/to/local.txt")
|
53
|
-
assert_scripted { scp.download!("/path/to/remote.txt", "/path/to/local.txt", :preserve => true) }
|
54
|
-
assert_equal "a" * 1234, file.io.string
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_download_with_error_should_respond_with_error_text
|
58
|
-
story do |session|
|
59
|
-
channel = session.opens_channel
|
60
|
-
channel.sends_exec "scp -f /path/to/remote.txt"
|
61
|
-
|
62
|
-
channel.sends_ok
|
63
|
-
channel.gets_data "\x01File not found: /path/to/remote.txt\n"
|
64
|
-
channel.sends_ok
|
65
|
-
|
66
|
-
channel.gets_eof
|
67
|
-
channel.gets_exit_status(1)
|
68
|
-
channel.gets_close
|
69
|
-
channel.sends_close
|
70
|
-
end
|
71
|
-
|
72
|
-
error = nil
|
73
|
-
assert_scripted do
|
74
|
-
begin
|
75
|
-
scp.download!("/path/to/remote.txt")
|
76
|
-
rescue
|
77
|
-
error = $!
|
78
|
-
end
|
79
|
-
end
|
80
|
-
assert_equal Net::SCP::Error, error.class
|
81
|
-
assert_equal "SCP did not finish successfully (1): File not found: /path/to/remote.txt\n", error.message
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_download_with_progress_callback_should_invoke_callback
|
85
|
-
prepare_file("/path/to/local.txt", "a" * 3000 + "b" * 3000 + "c" * 3000 + "d" * 3000)
|
86
|
-
|
87
|
-
expect_scp_session "-f /path/to/remote.txt" do |channel|
|
88
|
-
channel.sends_ok
|
89
|
-
channel.gets_data "C0666 12000 remote.txt\n"
|
90
|
-
channel.sends_ok
|
91
|
-
channel.gets_data "a" * 3000
|
92
|
-
channel.inject_remote_delay!
|
93
|
-
channel.gets_data "b" * 3000
|
94
|
-
channel.inject_remote_delay!
|
95
|
-
channel.gets_data "c" * 3000
|
96
|
-
channel.inject_remote_delay!
|
97
|
-
channel.gets_data "d" * 3000
|
98
|
-
channel.gets_ok
|
99
|
-
channel.sends_ok
|
100
|
-
end
|
101
|
-
|
102
|
-
calls = []
|
103
|
-
progress = Proc.new { |ch, *args| calls << args }
|
104
|
-
|
105
|
-
assert_scripted do
|
106
|
-
scp.download!("/path/to/remote.txt", "/path/to/local.txt", &progress)
|
107
|
-
end
|
108
|
-
|
109
|
-
assert_equal ["/path/to/local.txt", 0, 12000], calls.shift
|
110
|
-
assert_equal ["/path/to/local.txt", 3000, 12000], calls.shift
|
111
|
-
assert_equal ["/path/to/local.txt", 6000, 12000], calls.shift
|
112
|
-
assert_equal ["/path/to/local.txt", 9000, 12000], calls.shift
|
113
|
-
assert_equal ["/path/to/local.txt", 12000, 12000], calls.shift
|
114
|
-
assert calls.empty?
|
115
|
-
end
|
116
|
-
|
117
|
-
def test_download_io_with_recursive_should_raise_error
|
118
|
-
expect_scp_session "-f -r /path/to/remote.txt"
|
119
|
-
assert_raises(Net::SCP::Error) { scp.download!("/path/to/remote.txt", StringIO.new, :recursive => true) }
|
120
|
-
end
|
121
|
-
|
122
|
-
def test_download_io_with_preserve_should_ignore_preserve
|
123
|
-
expect_scp_session "-f -p /path/to/remote.txt" do |channel|
|
124
|
-
simple_download(channel)
|
125
|
-
end
|
126
|
-
|
127
|
-
io = StringIO.new
|
128
|
-
assert_scripted { scp.download!("/path/to/remote.txt", io, :preserve => true) }
|
129
|
-
assert_equal "a" * 1234, io.string
|
130
|
-
end
|
131
|
-
|
132
|
-
def test_download_io_should_transfer_data
|
133
|
-
expect_scp_session "-f /path/to/remote.txt" do |channel|
|
134
|
-
simple_download(channel)
|
135
|
-
end
|
136
|
-
|
137
|
-
io = StringIO.new
|
138
|
-
assert_scripted { scp.download!("/path/to/remote.txt", io) }
|
139
|
-
assert_equal "a" * 1234, io.string
|
140
|
-
end
|
141
|
-
|
142
|
-
def test_download_bang_without_target_should_return_string
|
143
|
-
expect_scp_session "-f /path/to/remote.txt" do |channel|
|
144
|
-
simple_download(channel)
|
145
|
-
end
|
146
|
-
|
147
|
-
assert_scripted do
|
148
|
-
assert_equal "a" * 1234, scp.download!("/path/to/remote.txt")
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def test_download_directory_without_recursive_should_raise_error
|
153
|
-
expect_scp_session "-f /path/to/remote" do |channel|
|
154
|
-
channel.sends_ok
|
155
|
-
channel.gets_data "D0755 0 remote\n"
|
156
|
-
end
|
157
|
-
|
158
|
-
assert_raises(Net::SCP::Error) { scp.download!("/path/to/remote") }
|
159
|
-
end
|
160
|
-
|
161
|
-
def test_download_directory_should_create_directory_and_files_locally
|
162
|
-
file = nil
|
163
|
-
prepare_directory "/path/to/local" do |dir|
|
164
|
-
dir.directory "remote" do |dir2|
|
165
|
-
dir2.directory "sub" do |dir3|
|
166
|
-
file = dir3.file "remote.txt", ""
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
expect_scp_session "-f -r /path/to/remote" do |channel|
|
172
|
-
channel.sends_ok
|
173
|
-
channel.gets_data "D0755 0 remote\n"
|
174
|
-
channel.sends_ok
|
175
|
-
channel.gets_data "D0755 0 sub\n"
|
176
|
-
simple_download(channel)
|
177
|
-
channel.gets_data "E\n"
|
178
|
-
channel.sends_ok
|
179
|
-
channel.gets_data "E\n"
|
180
|
-
channel.sends_ok
|
181
|
-
end
|
182
|
-
|
183
|
-
scp.download!("/path/to/remote", "/path/to/local", :recursive => true, :ssh => { :verbose => :debug })
|
184
|
-
assert_equal "a" * 1234, file.io.string
|
185
|
-
end
|
186
|
-
|
187
|
-
private
|
188
|
-
|
189
|
-
def simple_download(channel, mode=0666)
|
190
|
-
channel.sends_ok
|
191
|
-
channel.gets_data "C%04o 1234 remote.txt\n" % mode
|
192
|
-
channel.sends_ok
|
193
|
-
channel.gets_data "a" * 1234
|
194
|
-
channel.gets_ok
|
195
|
-
channel.sends_ok
|
196
|
-
end
|
197
|
-
end
|
data/test/test_scp.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'common'
|
2
|
-
|
3
|
-
class TestSCP < Net::SCP::TestCase
|
4
|
-
def test_start_without_block_should_return_scp_instance
|
5
|
-
ssh = stub('session', :logger => nil)
|
6
|
-
Net::SSH.expects(:start).
|
7
|
-
with("remote.host", "username", :password => "foo").
|
8
|
-
returns(ssh)
|
9
|
-
|
10
|
-
ssh.expects(:close).never
|
11
|
-
scp = Net::SCP.start("remote.host", "username", :password => "foo")
|
12
|
-
assert_instance_of Net::SCP, scp
|
13
|
-
assert_equal ssh, scp.session
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_start_with_block_should_yield_scp_and_close_ssh_session
|
17
|
-
ssh = stub('session', :logger => nil)
|
18
|
-
Net::SSH.expects(:start).
|
19
|
-
with("remote.host", "username", :password => "foo").
|
20
|
-
returns(ssh)
|
21
|
-
|
22
|
-
ssh.expects(:loop)
|
23
|
-
ssh.expects(:close)
|
24
|
-
|
25
|
-
yielded = false
|
26
|
-
Net::SCP.start("remote.host", "username", :password => "foo") do |scp|
|
27
|
-
yielded = true
|
28
|
-
assert_instance_of Net::SCP, scp
|
29
|
-
assert_equal ssh, scp.session
|
30
|
-
end
|
31
|
-
|
32
|
-
assert yielded
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_self_upload_should_instatiate_scp_and_invoke_synchronous_upload
|
36
|
-
scp = stub('scp')
|
37
|
-
scp.expects(:upload!).with("/path/to/local", "/path/to/remote", :recursive => true)
|
38
|
-
|
39
|
-
Net::SCP.expects(:start).
|
40
|
-
with("remote.host", "username", :password => "foo").
|
41
|
-
yields(scp)
|
42
|
-
|
43
|
-
Net::SCP.upload!("remote.host", "username", "/path/to/local", "/path/to/remote",
|
44
|
-
:ssh => { :password => "foo" }, :recursive => true)
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_self_download_should_instatiate_scp_and_invoke_synchronous_download
|
48
|
-
scp = stub('scp')
|
49
|
-
scp.expects(:download!).with("/path/to/remote", "/path/to/local", :recursive => true).returns(:result)
|
50
|
-
|
51
|
-
Net::SCP.expects(:start).
|
52
|
-
with("remote.host", "username", :password => "foo").
|
53
|
-
yields(scp)
|
54
|
-
|
55
|
-
result = Net::SCP.download!("remote.host", "username", "/path/to/remote", "/path/to/local",
|
56
|
-
:ssh => { :password => "foo" }, :recursive => true)
|
57
|
-
|
58
|
-
assert_equal :result, result
|
59
|
-
end
|
60
|
-
end
|
data/test/test_upload.rb
DELETED
@@ -1,269 +0,0 @@
|
|
1
|
-
require 'common'
|
2
|
-
|
3
|
-
class TestUpload < Net::SCP::TestCase
|
4
|
-
def test_upload_file_should_transfer_file
|
5
|
-
prepare_file("/path/to/local.txt", "a" * 1234)
|
6
|
-
|
7
|
-
expect_scp_session "-t /path/to/remote.txt" do |channel|
|
8
|
-
channel.gets_ok
|
9
|
-
channel.sends_data "C0666 1234 local.txt\n"
|
10
|
-
channel.gets_ok
|
11
|
-
channel.sends_data "a" * 1234
|
12
|
-
channel.sends_ok
|
13
|
-
channel.gets_ok
|
14
|
-
end
|
15
|
-
|
16
|
-
assert_scripted { scp.upload!("/path/to/local.txt", "/path/to/remote.txt") }
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_upload_file_with_spaces_in_name_should_escape_remote_file_name
|
20
|
-
prepare_file("/path/to/local file.txt", "")
|
21
|
-
|
22
|
-
expect_scp_session "-t /path/to/remote\\ file.txt" do |channel|
|
23
|
-
channel.gets_ok
|
24
|
-
channel.sends_data "C0666 0 local file.txt\n"
|
25
|
-
channel.gets_ok
|
26
|
-
channel.sends_ok
|
27
|
-
channel.gets_ok
|
28
|
-
end
|
29
|
-
|
30
|
-
assert_scripted { scp.upload!("/path/to/local file.txt", "/path/to/remote file.txt") }
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_upload_file_with_metacharacters_in_name_should_escape_remote_file_name
|
34
|
-
prepare_file("/path/to/local/#{awful_file_name}", "")
|
35
|
-
|
36
|
-
expect_scp_session "-t /path/to/remote/#{escaped_file_name}" do |channel|
|
37
|
-
channel.gets_ok
|
38
|
-
channel.sends_data "C0666 0 #{awful_file_name}\n"
|
39
|
-
channel.gets_ok
|
40
|
-
channel.sends_ok
|
41
|
-
channel.gets_ok
|
42
|
-
end
|
43
|
-
|
44
|
-
assert_scripted { scp.upload!("/path/to/local/#{awful_file_name}", "/path/to/remote/#{awful_file_name}") }
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_upload_file_with_preserve_should_send_times
|
48
|
-
prepare_file("/path/to/local.txt", "a" * 1234, 0666, Time.at(1234567890, 123456), Time.at(1234543210, 345678))
|
49
|
-
|
50
|
-
expect_scp_session "-t -p /path/to/remote.txt" do |channel|
|
51
|
-
channel.gets_ok
|
52
|
-
channel.sends_data "T1234567890 123456 1234543210 345678\n"
|
53
|
-
channel.gets_ok
|
54
|
-
channel.sends_data "C0666 1234 local.txt\n"
|
55
|
-
channel.gets_ok
|
56
|
-
channel.sends_data "a" * 1234
|
57
|
-
channel.sends_ok
|
58
|
-
channel.gets_ok
|
59
|
-
end
|
60
|
-
|
61
|
-
assert_scripted { scp.upload!("/path/to/local.txt", "/path/to/remote.txt", :preserve => true) }
|
62
|
-
end
|
63
|
-
|
64
|
-
def test_upload_file_with_progress_callback_should_invoke_callback
|
65
|
-
prepare_file("/path/to/local.txt", "a" * 3000 + "b" * 3000 + "c" * 3000 + "d" * 3000)
|
66
|
-
|
67
|
-
expect_scp_session "-t /path/to/remote.txt" do |channel|
|
68
|
-
channel.gets_ok
|
69
|
-
channel.sends_data "C0666 12000 local.txt\n"
|
70
|
-
channel.gets_ok
|
71
|
-
channel.sends_data "a" * 3000
|
72
|
-
channel.sends_data "b" * 3000
|
73
|
-
channel.sends_data "c" * 3000
|
74
|
-
channel.sends_data "d" * 3000
|
75
|
-
channel.sends_ok
|
76
|
-
channel.gets_ok
|
77
|
-
end
|
78
|
-
|
79
|
-
calls = []
|
80
|
-
progress = Proc.new do |ch, name, sent, total|
|
81
|
-
calls << [name, sent, total]
|
82
|
-
end
|
83
|
-
|
84
|
-
assert_scripted do
|
85
|
-
scp.upload!("/path/to/local.txt", "/path/to/remote.txt", :chunk_size => 3000, &progress)
|
86
|
-
end
|
87
|
-
|
88
|
-
assert_equal ["/path/to/local.txt", 0, 12000], calls.shift
|
89
|
-
assert_equal ["/path/to/local.txt", 3000, 12000], calls.shift
|
90
|
-
assert_equal ["/path/to/local.txt", 6000, 12000], calls.shift
|
91
|
-
assert_equal ["/path/to/local.txt", 9000, 12000], calls.shift
|
92
|
-
assert_equal ["/path/to/local.txt", 12000, 12000], calls.shift
|
93
|
-
assert calls.empty?
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_upload_io_with_recursive_should_ignore_recursive
|
97
|
-
expect_scp_session "-t -r /path/to/remote.txt" do |channel|
|
98
|
-
channel.gets_ok
|
99
|
-
channel.sends_data "C0640 1234 remote.txt\n"
|
100
|
-
channel.gets_ok
|
101
|
-
channel.sends_data "a" * 1234
|
102
|
-
channel.sends_ok
|
103
|
-
channel.gets_ok
|
104
|
-
end
|
105
|
-
|
106
|
-
io = StringIO.new("a" * 1234)
|
107
|
-
assert_scripted { scp.upload!(io, "/path/to/remote.txt", :recursive => true) }
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_upload_io_with_preserve_should_ignore_preserve
|
111
|
-
expect_scp_session "-t -p /path/to/remote.txt" do |channel|
|
112
|
-
channel.gets_ok
|
113
|
-
channel.sends_data "C0640 1234 remote.txt\n"
|
114
|
-
channel.gets_ok
|
115
|
-
channel.sends_data "a" * 1234
|
116
|
-
channel.sends_ok
|
117
|
-
channel.gets_ok
|
118
|
-
end
|
119
|
-
|
120
|
-
io = StringIO.new("a" * 1234)
|
121
|
-
assert_scripted { scp.upload!(io, "/path/to/remote.txt", :preserve => true) }
|
122
|
-
end
|
123
|
-
|
124
|
-
def test_upload_io_should_transfer_data
|
125
|
-
expect_scp_session "-t /path/to/remote.txt" do |channel|
|
126
|
-
channel.gets_ok
|
127
|
-
channel.sends_data "C0640 1234 remote.txt\n"
|
128
|
-
channel.gets_ok
|
129
|
-
channel.sends_data "a" * 1234
|
130
|
-
channel.sends_ok
|
131
|
-
channel.gets_ok
|
132
|
-
end
|
133
|
-
|
134
|
-
io = StringIO.new("a" * 1234)
|
135
|
-
assert_scripted { scp.upload!(io, "/path/to/remote.txt") }
|
136
|
-
end
|
137
|
-
|
138
|
-
def test_upload_io_with_mode_should_honor_mode_as_permissions
|
139
|
-
expect_scp_session "-t /path/to/remote.txt" do |channel|
|
140
|
-
channel.gets_ok
|
141
|
-
channel.sends_data "C0666 1234 remote.txt\n"
|
142
|
-
channel.gets_ok
|
143
|
-
channel.sends_data "a" * 1234
|
144
|
-
channel.sends_ok
|
145
|
-
channel.gets_ok
|
146
|
-
end
|
147
|
-
|
148
|
-
io = StringIO.new("a" * 1234)
|
149
|
-
assert_scripted { scp.upload!(io, "/path/to/remote.txt", :mode => 0666) }
|
150
|
-
end
|
151
|
-
|
152
|
-
def test_upload_directory_without_recursive_should_error
|
153
|
-
prepare_directory("/path/to/local")
|
154
|
-
|
155
|
-
expect_scp_session("-t /path/to/remote") do |channel|
|
156
|
-
channel.gets_ok
|
157
|
-
end
|
158
|
-
|
159
|
-
assert_raises(Net::SCP::Error) { scp.upload!("/path/to/local", "/path/to/remote") }
|
160
|
-
end
|
161
|
-
|
162
|
-
def test_upload_empty_directory_should_create_directory_and_finish
|
163
|
-
prepare_directory("/path/to/local")
|
164
|
-
|
165
|
-
expect_scp_session("-t -r /path/to/remote") do |channel|
|
166
|
-
channel.gets_ok
|
167
|
-
channel.sends_data "D0777 0 local\n"
|
168
|
-
channel.gets_ok
|
169
|
-
channel.sends_data "E\n"
|
170
|
-
channel.gets_ok
|
171
|
-
end
|
172
|
-
|
173
|
-
assert_scripted { scp.upload!("/path/to/local", "/path/to/remote", :recursive => true) }
|
174
|
-
end
|
175
|
-
|
176
|
-
def test_upload_directory_should_recursively_create_and_upload_items
|
177
|
-
prepare_directory("/path/to/local") do |d|
|
178
|
-
d.file "hello.txt", "hello world\n"
|
179
|
-
d.directory "others" do |d2|
|
180
|
-
d2.file "data.dat", "abcdefghijklmnopqrstuvwxyz"
|
181
|
-
end
|
182
|
-
d.file "zoo.doc", "going to the zoo\n"
|
183
|
-
end
|
184
|
-
|
185
|
-
expect_scp_session("-t -r /path/to/remote") do |channel|
|
186
|
-
channel.gets_ok
|
187
|
-
channel.sends_data "D0777 0 local\n"
|
188
|
-
channel.gets_ok
|
189
|
-
channel.sends_data "C0666 12 hello.txt\n"
|
190
|
-
channel.gets_ok
|
191
|
-
channel.sends_data "hello world\n"
|
192
|
-
channel.sends_ok
|
193
|
-
channel.gets_ok
|
194
|
-
channel.sends_data "D0777 0 others\n"
|
195
|
-
channel.gets_ok
|
196
|
-
channel.sends_data "C0666 26 data.dat\n"
|
197
|
-
channel.gets_ok
|
198
|
-
channel.sends_data "abcdefghijklmnopqrstuvwxyz"
|
199
|
-
channel.sends_ok
|
200
|
-
channel.gets_ok
|
201
|
-
channel.sends_data "E\n"
|
202
|
-
channel.gets_ok
|
203
|
-
channel.sends_data "C0666 17 zoo.doc\n"
|
204
|
-
channel.gets_ok
|
205
|
-
channel.sends_data "going to the zoo\n"
|
206
|
-
channel.sends_ok
|
207
|
-
channel.gets_ok
|
208
|
-
channel.sends_data "E\n"
|
209
|
-
channel.gets_ok
|
210
|
-
end
|
211
|
-
|
212
|
-
assert_scripted { scp.upload!("/path/to/local", "/path/to/remote", :recursive => true) }
|
213
|
-
end
|
214
|
-
|
215
|
-
def test_upload_directory_with_preserve_should_send_times_for_all_items
|
216
|
-
prepare_directory("/path/to/local", 0755, Time.at(17171717, 191919), Time.at(18181818, 101010)) do |d|
|
217
|
-
d.file "hello.txt", "hello world\n", 0640, Time.at(12345, 67890), Time.at(234567, 890)
|
218
|
-
d.directory "others", 0770, Time.at(112233, 4455), Time.at(22334455, 667788) do |d2|
|
219
|
-
d2.file "data.dat", "abcdefghijklmnopqrstuvwxyz", 0600, Time.at(13579135, 13131), Time.at(7654321, 654321)
|
220
|
-
end
|
221
|
-
d.file "zoo.doc", "going to the zoo\n", 0444, Time.at(12121212, 131313), Time.at(23232323, 242424)
|
222
|
-
end
|
223
|
-
|
224
|
-
expect_scp_session("-t -r -p /path/to/remote") do |channel|
|
225
|
-
channel.gets_ok
|
226
|
-
channel.sends_data "T17171717 191919 18181818 101010\n"
|
227
|
-
channel.gets_ok
|
228
|
-
channel.sends_data "D0755 0 local\n"
|
229
|
-
channel.gets_ok
|
230
|
-
channel.sends_data "T12345 67890 234567 890\n"
|
231
|
-
channel.gets_ok
|
232
|
-
channel.sends_data "C0640 12 hello.txt\n"
|
233
|
-
channel.gets_ok
|
234
|
-
channel.sends_data "hello world\n"
|
235
|
-
channel.sends_ok
|
236
|
-
channel.gets_ok
|
237
|
-
channel.sends_data "T112233 4455 22334455 667788\n"
|
238
|
-
channel.gets_ok
|
239
|
-
channel.sends_data "D0770 0 others\n"
|
240
|
-
channel.gets_ok
|
241
|
-
channel.sends_data "T13579135 13131 7654321 654321\n"
|
242
|
-
channel.gets_ok
|
243
|
-
channel.sends_data "C0600 26 data.dat\n"
|
244
|
-
channel.gets_ok
|
245
|
-
channel.sends_data "abcdefghijklmnopqrstuvwxyz"
|
246
|
-
channel.sends_ok
|
247
|
-
channel.gets_ok
|
248
|
-
channel.sends_data "E\n"
|
249
|
-
channel.gets_ok
|
250
|
-
channel.sends_data "T12121212 131313 23232323 242424\n"
|
251
|
-
channel.gets_ok
|
252
|
-
channel.sends_data "C0444 17 zoo.doc\n"
|
253
|
-
channel.gets_ok
|
254
|
-
channel.sends_data "going to the zoo\n"
|
255
|
-
channel.sends_ok
|
256
|
-
channel.gets_ok
|
257
|
-
channel.sends_data "E\n"
|
258
|
-
channel.gets_ok
|
259
|
-
end
|
260
|
-
|
261
|
-
assert_scripted { scp.upload!("/path/to/local", "/path/to/remote", :preserve => true, :recursive => true) }
|
262
|
-
end
|
263
|
-
|
264
|
-
def test_upload_should_not_block
|
265
|
-
prepare_file("/path/to/local.txt", "data")
|
266
|
-
story { |s| s.opens_channel(false) }
|
267
|
-
assert_scripted { scp.upload("/path/to/local.txt", "/path/to/remote.txt") }
|
268
|
-
end
|
269
|
-
end
|