When unlocking the file mutex utility always unlock the file prior to deletion to ensure the file can be properly deleted.
80 lines
2.3 KiB
Ruby
80 lines
2.3 KiB
Ruby
require File.expand_path("../../../base", __FILE__)
|
|
require 'vagrant/util/file_mutex'
|
|
|
|
describe Vagrant::Util::FileMutex do
|
|
include_context "unit"
|
|
|
|
let(:temp_dir) { Dir.mktmpdir("vagrant-test-util-mutex_test") }
|
|
let(:mutex_path) { File.join(temp_dir, "test.lock") }
|
|
let(:subject) { described_class.new(mutex_path) }
|
|
|
|
after do
|
|
FileUtils.rm_rf(temp_dir)
|
|
end
|
|
|
|
it "should create a lock file" do
|
|
subject.lock
|
|
expect(File).to exist(mutex_path)
|
|
end
|
|
|
|
it "should create and delete lock file" do
|
|
subject.lock
|
|
expect(File).to exist(mutex_path)
|
|
subject.unlock
|
|
expect(File).to_not exist(mutex_path)
|
|
end
|
|
|
|
it "should not raise an error if the lock file does not exist" do
|
|
subject.unlock
|
|
expect(File).to_not exist(mutex_path)
|
|
end
|
|
|
|
it "should run a function with a lock" do
|
|
subject.with_lock { true }
|
|
expect(File).to_not exist(mutex_path)
|
|
end
|
|
|
|
it "should fail running a function when locked" do
|
|
# create a lock
|
|
subject.lock
|
|
# create a new lock that will run a function
|
|
instance = described_class.new(mutex_path)
|
|
# lock should persist for multiple runs
|
|
expect {instance.with_lock { true }}.
|
|
to raise_error(Vagrant::Errors::VagrantLocked)
|
|
expect {instance.with_lock { true }}.
|
|
to raise_error(Vagrant::Errors::VagrantLocked)
|
|
# mutex should exist until its unlocked
|
|
expect(File).to exist(mutex_path)
|
|
subject.unlock
|
|
expect(File).to_not exist(mutex_path)
|
|
end
|
|
|
|
it "should fail running a function within a locked" do
|
|
# create a new lock that will run a function
|
|
instance = described_class.new(mutex_path)
|
|
expect {
|
|
subject.with_lock { instance.with_lock{true} }
|
|
}.to raise_error(Vagrant::Errors::VagrantLocked)
|
|
expect(File).to_not exist(mutex_path)
|
|
end
|
|
|
|
it "should delete the lock even when the function fails" do
|
|
expect {
|
|
subject.with_lock { raise Vagrant::Errors::VagrantError.new }
|
|
}.to raise_error(Vagrant::Errors::VagrantError)
|
|
expect(File).to_not exist(mutex_path)
|
|
end
|
|
|
|
it "should unlock file before deletion" do
|
|
lock_file = double(:lock_file)
|
|
allow(subject).to receive(:lock_file).and_return(lock_file)
|
|
allow(lock_file).to receive(:flock).and_return(true)
|
|
|
|
expect(lock_file).to receive(:flock).with(File::LOCK_UN)
|
|
expect(lock_file).to receive(:close)
|
|
|
|
subject.with_lock { true }
|
|
end
|
|
end
|