Paul Hinze d03a058e04
Fix VAGRANT_CWD handling in vagrant push ftp
When testing all of the push functionality I ran into the fact that the
FTP upload code did not recognize that I had VAGRANT_CWD set, so it
wasn't finding the right files to upload.

This should make everything work properly relative to that location.
2022-01-06 18:09:30 -06:00

330 lines
7.9 KiB
Ruby

require_relative "../../../base"
require "fake_ftp"
require Vagrant.source_root.join("plugins/pushes/ftp/push")
describe VagrantPlugins::FTPPush::Push do
include_context "unit"
let(:env) { isolated_environment }
let(:config) do
double("config",
host: "127.0.0.1:#{@port}",
username: "sethvargo",
password: "bacon",
passive: false,
secure: false,
destination: "/var/www/site",
)
end
let(:ui) { Vagrant::UI::Silent.new }
subject { described_class.new(env, config) }
before do
allow(env).to receive(:root_path)
.and_return(File.expand_path("..", __FILE__))
allow(env).to receive(:ui)
.and_return(ui)
end
describe "#push" do
before(:all) do
@server = nil
with_random_port do |port1, port2|
@port = port1
@server = FakeFtp::Server.new(port1, port2)
end
@server.start
@dir = Dir.mktmpdir("vagrant-ftp-push")
FileUtils.touch("#{@dir}/.hidden.rb")
FileUtils.touch("#{@dir}/application.rb")
FileUtils.touch("#{@dir}/config.rb")
FileUtils.touch("#{@dir}/Gemfile")
FileUtils.touch("#{@dir}/data.txt")
FileUtils.mkdir("#{@dir}/empty_folder")
end
after(:all) do
FileUtils.rm_rf(@dir)
@server.stop
end
let(:server) { @server }
before do
allow(config).to receive(:dir)
.and_return(@dir)
allow(config).to receive(:includes)
.and_return([])
allow(config).to receive(:excludes)
.and_return(%w(*.rb))
end
after do
server.reset
end
it "pushes the files to the server" do
subject.push
expect(server.files).to eq(%w(Gemfile data.txt))
end
it "raises informative exception when too many files to process" do
expect(subject).to receive(:all_files).and_raise(SystemStackError)
expect{ subject.push }.to raise_error(VagrantPlugins::FTPPush::Errors::TooManyFiles)
end
context "when VAGRANT_CWD is set to something relative" do
# this will be the PWD for the test context
let(:pwd) { Pathname.new(Dir.mktmpdir("vagrant-ftp-push-pwd")) }
before do
# this path should have a ../ in it since the pwd is another temp dir
# and measuring path from one to the other. they're most likely to be
# siblings
relative_path = Pathname.new(@dir).relative_path_from(pwd)
allow(env).to receive(:root_path) { relative_path.to_s }
# reset config.dir to its default since it was set absolute above
allow(config).to receive(:dir) { "." }
end
it "properly paths out the files to upload" do
Vagrant::Util::SafeChdir.safe_chdir(pwd) do
subject.push
end
expect(server.files).to eq(%w(Gemfile data.txt))
ensure
FileUtils.rm_rf(pwd)
end
end
end
describe "#connect" do
before do
allow_any_instance_of(VagrantPlugins::FTPPush::FTPAdapter)
.to receive(:connect)
.and_yield(:ftp)
allow_any_instance_of(VagrantPlugins::FTPPush::SFTPAdapter)
.to receive(:connect)
.and_yield(:sftp)
end
context "when secure is requested" do
before do
allow(config).to receive(:secure)
.and_return(true)
end
it "yields a new SFTPAdapter" do
expect { |b| subject.connect(&b) }.to yield_with_args(:sftp)
end
end
context "when secure is not requested" do
before do
allow(config).to receive(:secure)
.and_return(false)
end
it "yields a new FTPAdapter" do
expect { |b| subject.connect(&b) }.to yield_with_args(:ftp)
end
end
end
describe "#all_files" do
before(:all) do
@dir = Dir.mktmpdir("vagrant-ftp-push-push-all-files")
FileUtils.touch("#{@dir}/.hidden.rb")
FileUtils.touch("#{@dir}/application.rb")
FileUtils.touch("#{@dir}/config.rb")
FileUtils.touch("#{@dir}/Gemfile")
FileUtils.mkdir("#{@dir}/empty_folder")
FileUtils.mkdir("#{@dir}/folder")
FileUtils.mkdir("#{@dir}/folder/.git")
FileUtils.touch("#{@dir}/folder/.git/config")
FileUtils.touch("#{@dir}/folder/server.rb")
end
after(:all) do
FileUtils.rm_rf(@dir)
end
let(:files) do
subject.all_files.map do |file|
file.sub("#{@dir}/", "")
end
end
before do
allow(config).to receive(:dir)
.and_return(@dir)
allow(config).to receive(:includes)
.and_return(%w(not_a_file.rb still_not_a_file.rb))
allow(config).to receive(:excludes)
.and_return(%w(*.rb))
end
it "returns the list of real files + includes, without excludes" do
expect(files).to eq(%w(
Gemfile
folder/.git/config
))
end
end
describe "#includes_files" do
before(:all) do
@dir = Dir.mktmpdir("vagrant-ftp-push-includes-files")
FileUtils.touch("#{@dir}/.hidden.rb")
FileUtils.touch("#{@dir}/application.rb")
FileUtils.touch("#{@dir}/config.rb")
FileUtils.touch("#{@dir}/Gemfile")
FileUtils.mkdir("#{@dir}/folder")
FileUtils.mkdir("#{@dir}/folder/.git")
FileUtils.touch("#{@dir}/folder/.git/config")
FileUtils.touch("#{@dir}/folder/server.rb")
end
after(:all) do
FileUtils.rm_rf(@dir)
end
let(:files) do
subject.includes_files.map do |file|
file.sub("#{@dir}/", "")
end
end
before do
allow(config).to receive(:dir)
.and_return(@dir)
end
def set_includes(value)
allow(config).to receive(:includes)
.and_return(value)
end
it "includes the file" do
set_includes(["Gemfile"])
expect(files).to eq(%w(
Gemfile
))
end
it "includes the files that are subdirectories" do
set_includes(["folder"])
expect(files).to eq(%w(
folder
folder/.git
folder/.git/config
folder/server.rb
))
end
it "includes files that match a pattern" do
set_includes(["*.rb"])
expect(files).to eq(%w(
.hidden.rb
application.rb
config.rb
))
end
end
describe "#filter_excludes" do
let(:dir) { "/root/dir" }
let(:list) do
%W(
#{dir}/.hidden.rb
#{dir}/application.rb
#{dir}/config.rb
#{dir}/Gemfile
#{dir}/folder
#{dir}/folder/.git
#{dir}/folder/.git/config
#{dir}/folder/server.rb
/path/outside/you.rb
/path/outside/me.rb
/path/outside/folder/bacon.rb
)
end
before do
allow(config).to receive(:dir)
.and_return(dir)
end
it "excludes files" do
subject.filter_excludes!(list, %w(*.rb))
expect(list).to eq(%W(
#{dir}/Gemfile
#{dir}/folder
#{dir}/folder/.git
#{dir}/folder/.git/config
))
end
it "excludes files in a directory" do
subject.filter_excludes!(list, %w(folder))
expect(list).to eq(%W(
#{dir}/.hidden.rb
#{dir}/application.rb
#{dir}/config.rb
#{dir}/Gemfile
/path/outside/you.rb
/path/outside/me.rb
/path/outside/folder/bacon.rb
))
end
it "excludes specific files in a directory" do
subject.filter_excludes!(list, %w(/path/outside/folder/*.rb))
expect(list).to eq(%W(
#{dir}/.hidden.rb
#{dir}/application.rb
#{dir}/config.rb
#{dir}/Gemfile
#{dir}/folder
#{dir}/folder/.git
#{dir}/folder/.git/config
#{dir}/folder/server.rb
/path/outside/you.rb
/path/outside/me.rb
))
end
it "excludes files outside the #dir" do
subject.filter_excludes!(list, %w(/path/outside))
expect(list).to eq(%W(
#{dir}/.hidden.rb
#{dir}/application.rb
#{dir}/config.rb
#{dir}/Gemfile
#{dir}/folder
#{dir}/folder/.git
#{dir}/folder/.git/config
#{dir}/folder/server.rb
))
end
end
end