267 lines
7.1 KiB
Ruby
267 lines
7.1 KiB
Ruby
# Copyright (c) HashiCorp, Inc.
|
|
# SPDX-License-Identifier: BUSL-1.1
|
|
|
|
require "pathname"
|
|
require "tmpdir"
|
|
|
|
require File.expand_path("../../../../base", __FILE__)
|
|
|
|
require Vagrant.source_root.join("plugins/kernel_v2/config/vm")
|
|
|
|
describe Vagrant::Action::Builtin::SyncedFolders do
|
|
include_context "unit"
|
|
include_context "synced folder actions"
|
|
|
|
let(:app) { lambda { |env| } }
|
|
let(:env) { { machine: machine, ui: ui } }
|
|
let(:machine) do
|
|
double("machine").tap do |machine|
|
|
allow(machine).to receive(:config).and_return(machine_config)
|
|
end
|
|
end
|
|
|
|
let(:machine_config) do
|
|
double("machine_config").tap do |top_config|
|
|
allow(top_config).to receive(:vm).and_return(vm_config)
|
|
end
|
|
end
|
|
|
|
let(:vm_config) { double("machine_vm_config") }
|
|
|
|
let(:ui) { Vagrant::UI::Silent.new }
|
|
|
|
subject { described_class.new(app, env) }
|
|
|
|
describe "call" do
|
|
let(:synced_folders) { {} }
|
|
let(:plugins) { {} }
|
|
|
|
before do
|
|
plugins[:default] = [impl(true, "default"), 10]
|
|
plugins[:nfs] = [impl(true, "nfs"), 5]
|
|
|
|
env[:root_path] = Pathname.new(Dir.mktmpdir("vagrant-test-synced-folders-call"))
|
|
allow(subject).to receive(:plugins).and_return(plugins)
|
|
allow(subject).to receive(:synced_folders).and_return(synced_folders)
|
|
allow(subject).to receive(:save_synced_folders)
|
|
allow(machine).to receive_message_chain(:guest, :capability?).with(:persist_mount_shared_folder).and_return(false)
|
|
end
|
|
|
|
after do
|
|
FileUtils.rm_rf(env[:root_path])
|
|
end
|
|
|
|
it "should create on the host if specified" do
|
|
synced_folders["default"] = {
|
|
"root" => {
|
|
hostpath: "foo",
|
|
},
|
|
|
|
"other" => {
|
|
hostpath: "bar",
|
|
create: true,
|
|
}
|
|
}
|
|
|
|
subject.call(env)
|
|
|
|
expect(env[:root_path].join("foo")).not_to be_directory
|
|
expect(env[:root_path].join("bar")).to be_directory
|
|
end
|
|
|
|
it "doesn't expand the host path if told not to" do
|
|
called_folders = nil
|
|
tracker = Class.new(impl(true, "good")) do
|
|
define_method(:prepare) do |machine, folders, opts|
|
|
called_folders = folders
|
|
end
|
|
end
|
|
|
|
plugins[:tracker] = [tracker, 15]
|
|
|
|
synced_folders["tracker"] = {
|
|
"root" => {
|
|
hostpath: "foo",
|
|
hostpath_exact: true,
|
|
},
|
|
|
|
"other" => {
|
|
hostpath: "/bar",
|
|
}
|
|
}
|
|
|
|
subject.call(env)
|
|
|
|
expect(called_folders).to_not be_nil
|
|
expect(called_folders["root"][:hostpath]).to eq("foo")
|
|
end
|
|
|
|
it "expands the host path relative to the root path" do
|
|
called_folders = nil
|
|
tracker = Class.new(impl(true, "good")) do
|
|
define_method(:prepare) do |machine, folders, opts|
|
|
called_folders = folders
|
|
end
|
|
end
|
|
|
|
plugins[:tracker] = [tracker, 15]
|
|
|
|
synced_folders["tracker"] = {
|
|
"root" => {
|
|
hostpath: "foo",
|
|
},
|
|
|
|
"other" => {
|
|
hostpath: "/bar",
|
|
}
|
|
}
|
|
|
|
subject.call(env)
|
|
|
|
expect(called_folders).to_not be_nil
|
|
expect(called_folders["root"][:hostpath]).to eq(
|
|
Pathname.new(File.expand_path(
|
|
called_folders["root"][:hostpath],
|
|
env[:root_path])).to_s)
|
|
end
|
|
|
|
it "should invoke prepare then enable" do
|
|
ids = []
|
|
order = []
|
|
tracker = Class.new(impl(true, "good")) do
|
|
define_method(:prepare) do |machine, folders, opts|
|
|
ids << self.object_id
|
|
order << :prepare
|
|
end
|
|
|
|
define_method(:enable) do |machine, folders, opts|
|
|
ids << self.object_id
|
|
order << :enable
|
|
end
|
|
end
|
|
|
|
plugins[:tracker] = [tracker, 15]
|
|
|
|
synced_folders["tracker"] = {
|
|
"root" => {
|
|
hostpath: "foo",
|
|
},
|
|
|
|
"other" => {
|
|
hostpath: "bar",
|
|
create: true,
|
|
}
|
|
}
|
|
|
|
subject.call(env)
|
|
|
|
expect(order).to eq([:prepare, :enable])
|
|
expect(ids.length).to eq(2)
|
|
expect(ids[0]).to eq(ids[1])
|
|
end
|
|
|
|
it "syncs custom folders" do
|
|
ids = []
|
|
order = []
|
|
tracker = Class.new(impl(true, "good")) do
|
|
define_method(:prepare) do |machine, folders, opts|
|
|
ids << self.object_id
|
|
order << :prepare
|
|
end
|
|
|
|
define_method(:enable) do |machine, folders, opts|
|
|
ids << self.object_id
|
|
order << :enable
|
|
end
|
|
end
|
|
|
|
plugins[:tracker] = [tracker, 15]
|
|
|
|
synced_folders["tracker"] = {
|
|
"root" => {
|
|
hostpath: "foo",
|
|
},
|
|
|
|
"other" => {
|
|
hostpath: "bar",
|
|
create: true,
|
|
}
|
|
}
|
|
|
|
new_config = double("config")
|
|
env[:synced_folders_config] = new_config
|
|
|
|
expect(subject).to receive(:synced_folders).
|
|
with(machine, config: new_config, cached: false).
|
|
and_return(synced_folders)
|
|
|
|
subject.call(env)
|
|
|
|
expect(order).to eq([:prepare, :enable])
|
|
expect(ids.length).to eq(2)
|
|
expect(ids[0]).to eq(ids[1])
|
|
end
|
|
|
|
context "with folders from the machine" do
|
|
it "removes outdated folders not present in config" do
|
|
expect(subject).to receive(:save_synced_folders).with(
|
|
machine, anything, merge: true, vagrantfile: true)
|
|
|
|
subject.call(env)
|
|
end
|
|
end
|
|
|
|
context "with custom folders" do
|
|
before do
|
|
new_config = double("config")
|
|
env[:synced_folders_config] = new_config
|
|
|
|
allow(subject).to receive(:synced_folders).
|
|
with(machine, config: new_config, cached: false).
|
|
and_return({})
|
|
end
|
|
|
|
it "doesn't remove outdated folders not present in config" do
|
|
expect(subject).to receive(:save_synced_folders).with(
|
|
machine, anything, merge: true)
|
|
|
|
subject.call(env)
|
|
end
|
|
end
|
|
|
|
context "with guest capability to persist synced folders" do
|
|
it "persists folders" do
|
|
synced_folders["default"] = {
|
|
"root" => {
|
|
hostpath: "foo",
|
|
},
|
|
|
|
"other" => {
|
|
hostpath: "bar",
|
|
create: true,
|
|
}
|
|
}
|
|
allow(machine).to receive_message_chain(:guest, :capability?).with(:persist_mount_shared_folder).and_return(true)
|
|
expect(vm_config).to receive(:allow_fstab_modification).and_return(true)
|
|
expect(machine).to receive_message_chain(:guest, :capability).with(:persist_mount_shared_folder, synced_folders)
|
|
subject.call(env)
|
|
end
|
|
|
|
it "does not persists folders if configured to not do so" do
|
|
allow(machine).to receive_message_chain(:guest, :capability?).with(:persist_mount_shared_folder).and_return(true)
|
|
expect(vm_config).to receive(:allow_fstab_modification).and_return(false)
|
|
expect(machine).to receive_message_chain(:guest, :capability).with(:persist_mount_shared_folder, nil)
|
|
subject.call(env)
|
|
end
|
|
end
|
|
|
|
context "when guest is not available" do
|
|
it "does not persist folders if guest is not available" do
|
|
allow(machine).to receive_message_chain(:guest, :capability?).and_raise(Vagrant::Errors::MachineGuestNotReady)
|
|
expect(vm_config).to_not receive(:allow_fstab_modification)
|
|
subject.call(env)
|
|
end
|
|
end
|
|
end
|
|
end
|