vaguerent/test/unit/vagrant/util/file_mutex_test.rb

83 lines
2.4 KiB
Ruby

# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
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