diff --git a/lib/vagrant/plugin/v2/plugin.rb b/lib/vagrant/plugin/v2/plugin.rb index 7ec9f6644..84f1c707a 100644 --- a/lib/vagrant/plugin/v2/plugin.rb +++ b/lib/vagrant/plugin/v2/plugin.rb @@ -252,7 +252,7 @@ module Vagrant # to be executed. This means that if it is an instance method, # the block should return an instance of the class. # - # @param [String] host The name of the synced folder + # @param [String] synced_folder The name of the synced folder # @param [String] cap The name of the capability def self.synced_folder_capability(synced_folder, cap, &block) components.synced_folder_capabilities[synced_folder.to_sym].register(cap.to_sym, &block) diff --git a/plugins/synced_folders/unix_mount_helpers.rb b/plugins/synced_folders/unix_mount_helpers.rb index 2cb0932d7..a6921ce29 100644 --- a/plugins/synced_folders/unix_mount_helpers.rb +++ b/plugins/synced_folders/unix_mount_helpers.rb @@ -113,6 +113,7 @@ module VagrantPlugins merged.map do |key, value| [key, value].compact.join("=") end + end end end end diff --git a/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb b/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb index e46bfe164..fcaabf5d9 100644 --- a/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb +++ b/test/unit/plugins/guests/linux/cap/mount_virtual_box_shared_folder_test.rb @@ -23,9 +23,11 @@ describe "VagrantPlugins::GuestLinux::Cap::MountVirtualBoxSharedFolder" do } end let(:cap){ caps.get(:mount_virtualbox_shared_folder) } + let(:mount_options_cap){ double("opts") } before do allow(machine).to receive(:communicate).and_return(comm) + allow(machine).to receive(:synced_folder_types).and_return( { :virtualbox => mount_options_cap } ) end after do @@ -40,159 +42,27 @@ describe "VagrantPlugins::GuestLinux::Cap::MountVirtualBoxSharedFolder" do end it "generates the expected default mount command" do - expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) end it "automatically chown's the mounted directory on guest" do - expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_gid} #{mount_guest_path}") cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) end - context "with owner user ID explicitly defined" do - - before do - expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") - end - - context "with user ID provided as Integer" do - let(:mount_owner){ 2000 } - - it "generates the expected mount command using mount_owner directly" do - expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_owner},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) - expect(comm).to receive(:sudo).with("chown #{mount_owner}:#{mount_gid} #{mount_guest_path}") - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) - end - end - - context "with user ID provided as String" do - let(:mount_owner){ "2000" } - - it "generates the expected mount command using mount_owner directly" do - expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_owner},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) - expect(comm).to receive(:sudo).with("chown #{mount_owner}:#{mount_gid} #{mount_guest_path}") - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) - end - end - - end - - context "with owner group ID explicitly defined" do - - before do - expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - end - - context "with owner group ID provided as Integer" do - let(:mount_group){ 2000 } - - it "generates the expected mount command using mount_group directly" do - expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_uid},gid=#{mount_group} #{mount_name} #{mount_guest_path}", anything) - expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_group} #{mount_guest_path}") - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) - end - end - - context "with owner group ID provided as String" do - let(:mount_group){ "2000" } - - it "generates the expected mount command using mount_group directly" do - expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_uid},gid=#{mount_group} #{mount_name} #{mount_guest_path}", anything) - expect(comm).to receive(:sudo).with("chown #{mount_uid}:#{mount_group} #{mount_guest_path}") - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) - end - end - - end - - context "with non-existent default owner group" do - - it "fetches the effective group ID of the user" do - expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''}) - expect(comm).to receive(:execute).with("id -g #{mount_owner}", anything).and_yield(:stdout, "1").and_return(0) - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) - end - end - - context "with non-existent owner group" do - - it "raises an error" do - expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''}) - expect do - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) - end.to raise_error Vagrant::Errors::VirtualBoxMountFailed - end - end - - context "with read-only option defined" do - - it "does not chown mounted guest directory" do - expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") - expect(comm).to receive(:sudo).with("mount -t vboxsf -o ro,uid=#{mount_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) - expect(comm).not_to receive(:sudo).with("chown #{mount_uid}:#{mount_gid} #{mount_guest_path}") - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["ro"])) - end - end - context "with upstart init" do it "emits mount event" do expect(comm).to receive(:sudo).with(/initctl emit/) + expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) end end - context "with custom mount options" do - - let(:ui){ double(:ui) } - before do - allow(ui).to receive(:warn) - allow(machine).to receive(:ui).and_return(ui) - end - - context "with uid defined" do - let(:options_uid){ '1234' } - - it "should only include uid defined within mount options" do - expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") - expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{options_uid},gid=#{mount_gid} #{mount_name} #{mount_guest_path}", anything) - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["uid=#{options_uid}"])) - end - end - - context "with gid defined" do - let(:options_gid){ '1234' } - - it "should only include gid defined within mount options" do - expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") - expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{mount_uid},gid=#{options_gid} #{mount_name} #{mount_guest_path}", anything) - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["gid=#{options_gid}"])) - end - end - - context "with uid and gid defined" do - let(:options_gid){ '1234' } - let(:options_uid){ '1234' } - - it "should only include uid and gid defined within mount options" do - expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) - expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{options_gid}:") - expect(comm).to receive(:sudo).with("mount -t vboxsf -o uid=#{options_uid},gid=#{options_gid} #{mount_name} #{mount_guest_path}", anything) - cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["gid=#{options_gid}", "uid=#{options_uid}"])) - end - end - end - context "with guest builtin vboxsf module" do let(:vbox_stderr){ <<-EOF mount.vboxsf cannot be used with mainline vboxsf; instead use: @@ -201,6 +71,7 @@ mount.vboxsf cannot be used with mainline vboxsf; instead use: EOF } it "should perform guest mount using builtin module" do + expect(mount_options_cap).to receive(:capability).with(:mount_options, mount_name, mount_guest_path, folder_options).and_return(["uid=#{mount_uid},gid=#{mount_gid}", mount_uid, mount_gid]) expect(comm).to receive(:sudo).with(/mount -t vboxsf/, any_args).and_yield(:stderr, vbox_stderr).and_return(1) expect(comm).to receive(:sudo).with(/mount -cit/, any_args) cap.mount_virtualbox_shared_folder(machine, mount_name, mount_guest_path, folder_options) diff --git a/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb b/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb index f4d6f58c7..bf3eacffb 100644 --- a/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb +++ b/test/unit/plugins/guests/linux/cap/persist_mount_shared_folder_test.rb @@ -9,10 +9,15 @@ describe "VagrantPlugins::GuestLinux::Cap::PersistMountSharedFolder" do let(:machine) { double("machine") } let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + let(:options_gid){ '1234' } + let(:options_uid){ '1234' } let(:cap){ caps.get(:persist_mount_shared_folder) } + let(:mount_options_cap){ double("opts") } before do allow(machine).to receive(:communicate).and_return(comm) + allow(machine).to receive(:synced_folder_types).and_return( { :virtualbox => mount_options_cap } ) + allow(mount_options_cap).to receive(:capability).with(:mount_options, any_args).and_return(["uid=#{options_uid},gid=#{options_gid}", options_uid, options_gid]) end after do @@ -20,12 +25,10 @@ describe "VagrantPlugins::GuestLinux::Cap::PersistMountSharedFolder" do end describe ".persist_mount_shared_folder" do - let(:options_gid){ '1234' } - let(:options_uid){ '1234' } let (:fstab_folders) { [ - ["test1", {:guestpath=>"/test1", :hostpath=>"/my/host/path", :disabled=>false, :__vagrantfile=>true, :owner=>"vagrant", :group=>"vagrant", :mount_options=>["uid=1234", "gid=1234"] }], - ["vagrant", {:guestpath=>"/vagrant", :hostpath=>"/my/host/vagrant", :disabled=>false, :__vagrantfile=>true, :owner=>"vagrant", :group=>"vagrant", :mount_options=>["uid=1234", "gid=1234"] }] + ["test1", {:guestpath=>"/test1", :hostpath=>"/my/host/path", :disabled=>false, :__vagrantfile=>true, :owner=>"vagrant", :group=>"vagrant", :mount_options=>["uid=#{options_uid}", "gid=#{options_gid}"] }], + ["vagrant", {:guestpath=>"/vagrant", :hostpath=>"/my/host/vagrant", :disabled=>false, :__vagrantfile=>true, :owner=>"vagrant", :group=>"vagrant", :mount_options=>["uid=#{options_uid}", "gid=#{options_gid}"] }] ]} let(:ui){ double(:ui) } @@ -37,8 +40,8 @@ describe "VagrantPlugins::GuestLinux::Cap::PersistMountSharedFolder" do end it "inserts folders into /etc/fstab" do - expected_entry_vagrant = "vagrant /vagrant vboxsf uid=1234,gid=1234,nofail 0 0" - expected_entry_test = "test1 /test1 vboxsf uid=1234,gid=1234,nofail 0 0" + expected_entry_vagrant = "vagrant /vagrant vboxsf uid=#{options_uid},gid=#{options_gid},nofail 0 0" + expected_entry_test = "test1 /test1 vboxsf uid=#{options_uid},gid=#{options_gid},nofail 0 0" expect(cap).to receive(:remove_vagrant_managed_fstab) expect(comm).to receive(:sudo).with(/#{expected_entry_test}\n#{expected_entry_vagrant}/) cap.persist_mount_shared_folder(machine, fstab_folders, "vboxsf") diff --git a/test/unit/plugins/kernel_v2/config/vm_test.rb b/test/unit/plugins/kernel_v2/config/vm_test.rb index ebcef38a3..0084d7c95 100644 --- a/test/unit/plugins/kernel_v2/config/vm_test.rb +++ b/test/unit/plugins/kernel_v2/config/vm_test.rb @@ -37,7 +37,7 @@ describe VagrantPlugins::Kernel_V2::VMConfig do allow(machine).to receive(:env).and_return(env) allow(machine).to receive(:provider_config).and_return(nil) allow(machine).to receive(:provider_options).and_return({}) - + allow(machine).to receive(:synced_folder_types).and_return([]) allow(provider).to receive(:capability?).with(:validate_disk_ext).and_return(true) allow(provider).to receive(:capability).with(:validate_disk_ext, "vdi").and_return(true) allow(provider).to receive(:capability?).with(:set_default_disk_ext).and_return(true) @@ -51,7 +51,7 @@ describe VagrantPlugins::Kernel_V2::VMConfig do assert_valid end - it "validates disables_host_modification option" do + it "validates disables_host_modification option" do subject.allow_hosts_modification = true subject.finalize! assert_valid @@ -65,6 +65,13 @@ describe VagrantPlugins::Kernel_V2::VMConfig do assert_invalid end + it "does not check for fstab caps if already set" do + expect(machine).to_not receive(:synced_folder_types) + subject.allow_fstab_modification = true + subject.finalize! + assert_valid + end + describe "#base_mac" do it "defaults properly" do subject.finalize! diff --git a/test/unit/plugins/providers/virtualbox/cap/mount_options_test.rb b/test/unit/plugins/providers/virtualbox/cap/mount_options_test.rb new file mode 100644 index 000000000..430c409c4 --- /dev/null +++ b/test/unit/plugins/providers/virtualbox/cap/mount_options_test.rb @@ -0,0 +1,179 @@ +require_relative "../../../../base" + +describe "VagrantPlugins::ProviderVirtualBox::Cap::MountOptions" do + let(:caps) do + VagrantPlugins::ProviderVirtualBox::Plugin + .components + .synced_folder_capabilities[:virtualbox] + end + + let(:machine) { double("machine") } + let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + let(:mount_owner){ "vagrant" } + let(:mount_group){ "vagrant" } + let(:mount_uid){ "1000" } + let(:mount_gid){ "1000" } + let(:mount_name){ "vagrant" } + let(:mount_guest_path){ "/vagrant" } + let(:folder_options) do + { + owner: mount_owner, + group: mount_group, + hostpath: "/host/directory/path" + } + end + let(:cap){ caps.get(:mount_options) } + + before do + allow(machine).to receive(:communicate).and_return(comm) + end + + after do + comm.verify_expectations! + end + + describe ".mount_options" do + + before do + allow(comm).to receive(:sudo).with(any_args) + allow(comm).to receive(:execute).with(any_args) + end + + context "with owner user ID explicitly defined" do + + before do + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + end + + context "with user ID provided as Integer" do + let(:mount_owner){ 2000 } + it "generates the expected mount command using mount_owner directly" do + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + expect(out_mount_options).to eq("uid=#{mount_owner},gid=#{mount_gid}") + expect(out_mount_uid).to eq(mount_owner) + expect(out_mount_gid).to eq(mount_gid) + end + end + + context "with user ID provided as String" do + let(:mount_owner){ "2000" } + it "generates the expected mount command using mount_owner directly" do + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + expect(out_mount_options).to eq("uid=#{mount_owner},gid=#{mount_gid}") + expect(out_mount_uid).to eq(mount_owner) + expect(out_mount_gid).to eq(mount_gid) + end + end + + end + + context "with owner group ID explicitly defined" do + + before do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + end + + context "with owner group ID provided as Integer" do + let(:mount_group){ 2000 } + + it "generates the expected mount command using mount_group directly" do + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + expect(out_mount_options).to eq("uid=#{mount_uid},gid=#{mount_group}") + expect(out_mount_uid).to eq(mount_uid) + expect(out_mount_gid).to eq(mount_group) + end + end + + context "with owner group ID provided as String" do + let(:mount_group){ "2000" } + + it "generates the expected mount command using mount_group directly" do + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + expect(out_mount_options).to eq("uid=#{mount_uid},gid=#{mount_group}") + expect(out_mount_uid).to eq(mount_uid) + expect(out_mount_gid).to eq(mount_group) + end + end + + end + + context "with non-existent default owner group" do + it "fetches the effective group ID of the user" do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''}) + expect(comm).to receive(:execute).with("id -g #{mount_owner}", anything).and_yield(:stdout, "1").and_return(0) + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + expect(out_mount_options).to eq("uid=#{mount_uid},gid=1") + end + end + + context "with non-existent owner group" do + it "raises an error" do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''}) + expect do + cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + end.to raise_error Vagrant::Errors::VirtualBoxMountFailed + end + end + + context "with read-only option defined" do + it "does not chown mounted guest directory" do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["ro"])) + expect(out_mount_options).to eq("ro,uid=#{mount_uid},gid=#{mount_gid}") + expect(out_mount_uid).to eq(mount_uid) + expect(out_mount_gid).to eq(mount_gid) + end + end + + context "with custom mount options" do + let(:ui){ double(:ui) } + before do + allow(ui).to receive(:warn) + allow(machine).to receive(:ui).and_return(ui) + end + + context "with uid defined" do + let(:options_uid){ '1234' } + + it "should only include uid defined within mount options" do + expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["uid=#{options_uid}"]) ) + expect(out_mount_options).to eq("uid=#{options_uid},gid=#{mount_gid}") + expect(out_mount_uid).to eq(options_uid) + expect(out_mount_gid).to eq(mount_gid) + end + end + + context "with gid defined" do + let(:options_gid){ '1234' } + + it "should only include gid defined within mount options" do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["gid=#{options_gid}"]) ) + expect(out_mount_options).to eq("uid=#{mount_uid},gid=#{options_gid}") + expect(out_mount_uid).to eq(mount_uid) + expect(out_mount_gid).to eq(options_gid) + end + end + + context "with uid and gid defined" do + let(:options_gid){ '1234' } + let(:options_uid){ '1234' } + + it "should only include uid and gid defined within mount options" do + expect(comm).not_to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).not_to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{options_gid}:") + out_mount_options, out_mount_uid, out_mount_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options.merge(mount_options: ["uid=#{options_uid}", "gid=#{options_gid}"]) ) + expect(out_mount_options).to eq("uid=#{options_uid},gid=#{options_gid}") + expect(out_mount_uid).to eq(options_uid) + expect(out_mount_gid).to eq(options_gid) + end + end + end + end +end diff --git a/test/unit/plugins/synced_folders/smb/caps/mount_options_test.rb b/test/unit/plugins/synced_folders/smb/caps/mount_options_test.rb new file mode 100644 index 000000000..90f6472a5 --- /dev/null +++ b/test/unit/plugins/synced_folders/smb/caps/mount_options_test.rb @@ -0,0 +1,67 @@ +require_relative "../../../../base" + +require_relative "../../../../../../plugins/synced_folders/smb/cap/mount_options" + +describe VagrantPlugins::SyncedFolderSMB::Cap::MountOptions do + + let(:caps) do + VagrantPlugins::SyncedFolderSMB::Plugin + .components + .synced_folder_capabilities[:smb] + end + let(:cap){ caps.get(:mount_options) } + + let(:machine) { double("machine") } + let(:comm) { VagrantTests::DummyCommunicator::Communicator.new(machine) } + let(:mount_owner){ "vagrant" } + let(:mount_group){ "vagrant" } + let(:mount_uid){ "1000" } + let(:mount_gid){ "1000" } + let(:mount_name){ "vagrant" } + let(:mount_guest_path){ "/vagrant" } + let(:folder_options) do + { + owner: mount_owner, + group: mount_group, + hostpath: "/host/directory/path" + } + end + + before do + allow(machine).to receive(:communicate).and_return(comm) + allow(machine).to receive_message_chain(:env, :host, :capability?).with(:smb_mount_options).and_return(false) + ENV['VAGRANT_DISABLE_SMBMFSYMLINKS'] = "1" + end + + describe ".mount_options" do + it "generates the expected default mount command" do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + out_opts, out_uid, out_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + expect(out_opts).to eq("sec=ntlmssp,credentials=/etc/smb_creds_vagrant,uid=1000,gid=1000") + expect(out_uid).to eq(mount_uid) + expect(out_gid).to eq(mount_gid) + end + + it "includes provided mount options" do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_yield(:stdout, "vagrant:x:#{mount_gid}:") + folder_options[:mount_options] =["ro"] + out_opts, out_uid, out_gid = cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + expect(out_opts).to eq("sec=ntlmssp,credentials=/etc/smb_creds_vagrant,uid=1000,gid=1000,ro") + expect(out_uid).to eq(mount_uid) + expect(out_gid).to eq(mount_gid) + end + + context "with non-existent owner group" do + it "raises an error" do + expect(comm).to receive(:execute).with("id -u #{mount_owner}", anything).and_yield(:stdout, mount_uid) + expect(comm).to receive(:execute).with("id -g #{mount_group}", anything).and_yield(:stdout, mount_gid) + expect(comm).to receive(:execute).with("getent group #{mount_group}", anything).and_raise(Vagrant::Errors::VirtualBoxMountFailed, {command: '', output: ''}) + expect do + cap.mount_options(machine, mount_name, mount_guest_path, folder_options) + end.to raise_error Vagrant::Errors::VirtualBoxMountFailed + end + end + end +end diff --git a/test/unit/vagrant/machine_test.rb b/test/unit/vagrant/machine_test.rb index 913dc5e9c..c2003a87a 100644 --- a/test/unit/vagrant/machine_test.rb +++ b/test/unit/vagrant/machine_test.rb @@ -1006,5 +1006,16 @@ describe Vagrant::Machine do end end end + + describe "#synced_folder_types" do + it "returns a map of initialized synced folders" do + allow(instance).to receive(:synced_folders).and_return( {:smb => {}, :virtualbox => {}} ) + folders = instance.synced_folder_types + folders.each do |k, v| + expect([:smb, :virtualbox]).to include(k) + expect(v.respond_to?(:capability)).to eq(true) + end + end + end end end diff --git a/test/unit/vagrant/plugin/v2/manager_test.rb b/test/unit/vagrant/plugin/v2/manager_test.rb index c145b4b28..5dbcc11a5 100644 --- a/test/unit/vagrant/plugin/v2/manager_test.rb +++ b/test/unit/vagrant/plugin/v2/manager_test.rb @@ -357,4 +357,22 @@ describe Vagrant::Plugin::V2::Manager do expect(instance.synced_folders[:foo]).to eq(["bar", 10]) expect(instance.synced_folders[:bar]).to eq(["baz", 50]) end + + it "should enumerate registered synced_folder_capabilities classes" do + pA = plugin do |p| + p.synced_folder_capability("foo", "foo") { "bar" } + end + + pB = plugin do |p| + p.synced_folder_capability("bar", "bar") { "baz" } + end + + instance.register(pA) + instance.register(pB) + + expect(instance.synced_folder_capabilities.to_hash.length).to eq(2) + expect(instance.synced_folder_capabilities[:foo][:foo]).to eq("bar") + expect(instance.synced_folder_capabilities[:bar][:bar]).to eq("baz") + end + end