forked from ManageIQ/manageiq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile_depot_ftp_spec.rb
114 lines (96 loc) · 3.67 KB
/
file_depot_ftp_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
describe FileDepotFtp do
before do
_, @miq_server, @zone = EvmSpecHelper.create_guid_miq_server_zone
end
let(:connection) { double("FtpConnection") }
let(:file_depot_ftp) { FileDepotFtp.new(:uri => "ftp://server.example.com/uploads") }
let(:log_file) { LogFile.new(:resource => @miq_server, :local_file => "/tmp/file.txt") }
context "#file_exists?" do
it "true if file exists" do
file_depot_ftp.ftp = double(:nlst => ["somefile"])
expect(file_depot_ftp.file_exists?("somefile")).to be_truthy
end
it "false if ftp raises on missing file" do
file_depot_ftp.ftp = double
expect(file_depot_ftp.ftp).to receive(:nlst).and_raise(Net::FTPPermError)
expect(file_depot_ftp.file_exists?("somefile")).to be_falsey
end
it "false if file missing" do
file_depot_ftp.ftp = double(:nlst => [])
expect(file_depot_ftp.file_exists?("somefile")).to be_falsey
end
end
context "#upload_file" do
it 'uploads file to vsftpd with existing directory structure' do
vsftpd = VsftpdMock.new('uploads' =>
{"#{@zone.name}_#{@zone.id}" =>
{"#{@miq_server.name}_#{@miq_server.id}" => {}}})
expect(file_depot_ftp).to receive(:connect).and_return(vsftpd)
file_depot_ftp.upload_file(log_file)
expect(vsftpd.content).to eq('uploads' =>
{"#{@zone.name}_#{@zone.id}" =>
{"#{@miq_server.name}_#{@miq_server.id}" =>
{"Current_region_unknown_#{@zone.name}_#{@zone.id}_#{@miq_server.name}_#{@miq_server.id}_unknown_unknown.txt" =>
log_file.local_file}}})
end
it 'uploads file to vsftpd with empty /uploads directory' do
vsftpd = VsftpdMock.new('uploads' => {})
expect(file_depot_ftp).to receive(:connect).and_return(vsftpd)
file_depot_ftp.upload_file(log_file)
expect(vsftpd.content).to eq('uploads' =>
{"#{@zone.name}_#{@zone.id}" =>
{"#{@miq_server.name}_#{@miq_server.id}" =>
{"Current_region_unknown_#{@zone.name}_#{@zone.id}_#{@miq_server.name}_#{@miq_server.id}_unknown_unknown.txt" =>
log_file.local_file}}})
end
it "already exists" do
expect(file_depot_ftp).to receive(:connect).and_return(connection)
expect(file_depot_ftp).to receive(:file_exists?).and_return(true)
expect(connection).not_to receive(:mkdir)
expect(connection).not_to receive(:putbinaryfile)
expect(log_file).not_to receive(:post_upload_tasks)
expect(connection).to receive(:close)
file_depot_ftp.upload_file(log_file)
end
end
class FtpMock
attr_reader :pwd, :content
def initialize(content = {})
@pwd = '/'
@content = content
end
def chdir(dir)
newpath = (Pathname.new(pwd) + dir).to_s
if local(newpath).kind_of? Hash
@pwd = newpath
end
end
private
def local(path)
local = @content
path.split('/').each do |dir|
next if dir.empty?
local = local[dir]
raise Net::FTPPermError, '550 Failed to change directory.' if local.nil?
end
local
end
end
class VsftpdMock < FtpMock
def nlst(path = '')
l = local(pwd + path)
l.respond_to?(:keys) ? l.keys : []
rescue
return []
end
def mkdir(dir)
l = local(pwd)
l[dir] = {}
end
def putbinaryfile(local_path, remote_path)
dir, base = Pathname.new(remote_path).split
l = local(dir.to_s)
l[base.to_s] = local_path
end
end
end