Skip to content

Instantly share code, notes, and snippets.

@marzdgzmn
Created November 7, 2018 08:03
Show Gist options
  • Save marzdgzmn/0d66c7d34a0175f217bd1c5d52027ba6 to your computer and use it in GitHub Desktop.
Save marzdgzmn/0d66c7d34a0175f217bd1c5d52027ba6 to your computer and use it in GitHub Desktop.
describe '#sync' do
let(:mirror) do
OpenStruct.new(name: 'dummy_mirror',
local_dir: tmp_dir,
pre_cmd: true)
end
before(:each) do
@sync = Sync.new(mirror)
end
after(:each) do
File.delete(@sync.send(:lock_file)) if File.exist?(@sync.send(:lock_file))
end
# subject(:sync) { Sync.new(mirror) }
context 'when establishing lock' do
it 'should create a lock file' do
allow(@sync).to receive(:sync) # Get rid of error messages
@sync.run
expect(File.exist?(@sync.send(:lock_file))).to be true
end
context 'when trying to acquire a lock when a lock file already exists' do
before(:each) do
File.open(File.join(mirror.local_dir, "#{mirror.name}.lock"), File::RDWR | File::CREAT) do |f|
f.write(5)
f.flush
end
end
it 'should delete and create a lock file if corresponding process for the lock file does not exist' do
allow(Process).to receive(:kill).and_raise Errno::ESRCH
allow(@sync).to receive(:sync) # so as not to continue processing the script
expect(File).to receive(:delete).with(File.join(mirror.local_dir, "#{mirror.name}.lock")).twice # once for sync.run, twice for after(:each)
expect(File.exist?(@sync.send(:lock_file))).to be true
@sync.run
end
it 'should log an error and exit if app does not have privilege to send signal to the process' do
allow(Process).to receive(:kill).and_raise Errno::EPERM
allow(@sync).to receive(:exit).and_throw(:exit)
expect(@sync).to receive(:log_error).with('No permission/privilege to send signal to process(5)')
expect { @sync.run }.to throw_symbol :exit
end
it 'should log an error and exit if the corresponding process for the lock file is running' do
allow(@sync).to receive(:exit).and_throw(:exit)
expect(@sync).to receive(:log_error).with('Cannot establish lock. Another process(5) is currently running and holding the lock.')
expect { @sync.run }.to throw_symbol :exit
end
end
end
end
def establish_lock
puts 'establish lock'
if File.exist?(lock_file)
puts 'exists'
acquire_lock
else
puts 'else exist'
create_lock
end
end
def acquire_lock
pid = File.read(lock_file).to_i
puts File.read(lock_file)
Process.kill(0, pid)
rescue Errno::ESRCH
puts 'esrch'
File.delete(lock_file) # nonexistent process
create_lock
rescue Errno::EPERM
puts 'eperm'
log_error "No permission/privilege to send signal to process(#{pid})"
puts 'before exit'
exit
else
puts 'nyahahaha'
log_error "Cannot establish lock. Another process(#{pid}) is currently running and holding the lock."
exit
end
def create_lock
File.open(lock_file, File::RDWR | File::CREAT, 0o644) do |f|
f.flock(File::LOCK_EX)
f.write(Process.pid.to_s)
f.flush
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment