spec/client_spec.rb in redlock-0.1.2 vs spec/client_spec.rb in redlock-0.1.3
- old
+ new
@@ -33,10 +33,29 @@
it 'returns lock information' do
@lock_info = lock_manager.lock(resource_key, ttl)
expect(@lock_info).to be_lock_info_for(resource_key)
end
+
+ it 'can extend its own lock' do
+ my_lock_info = lock_manager.lock(resource_key, ttl)
+ @lock_info = lock_manager.lock(resource_key, ttl, extend: my_lock_info)
+ expect(@lock_info).to be_lock_info_for(resource_key)
+ expect(@lock_info[:value]).to eq(my_lock_info[:value])
+ end
+
+ it "sets the given value when trying to extend a non-existent lock" do
+ @lock_info = lock_manager.lock(resource_key, ttl, extend: {value: 'hello world'})
+ expect(@lock_info).to be_lock_info_for(resource_key)
+ expect(@lock_info[:value]).to eq('hello world') # really we should test what's in redis
+ end
+
+ it "doesn't extend somebody else's lock" do
+ @lock_info = lock_manager.lock(resource_key, ttl)
+ second_attempt = lock_manager.lock(resource_key, ttl)
+ expect(second_attempt).to eq(false)
+ end
end
context 'when lock is not available' do
before { @another_lock_info = lock_manager.lock(resource_key, ttl) }
after { lock_manager.unlock(@another_lock_info) }
@@ -44,10 +63,16 @@
it 'returns false' do
lock_info = lock_manager.lock(resource_key, ttl)
expect(lock_info).to eql(false)
end
+
+ it "can't extend somebody else's lock" do
+ yet_another_lock_info = @another_lock_info.merge value: 'gibberish'
+ lock_info = lock_manager.lock(resource_key, ttl, extend: yet_another_lock_info)
+ expect(lock_info).to eql(false)
+ end
end
describe 'block syntax' do
context 'when lock is available' do
it 'locks' do
@@ -103,8 +128,51 @@
expect(resource_key).to_not be_lockable(lock_manager, ttl)
lock_manager.unlock(@lock_info)
expect(resource_key).to be_lockable(lock_manager, ttl)
+ end
+ end
+
+ describe 'lock!' do
+ context 'when lock is available' do
+ it 'locks' do
+ lock_manager.lock!(resource_key, ttl) do
+ expect(resource_key).to_not be_lockable(lock_manager, ttl)
+ end
+ end
+
+ it "returns the received block's return value" do
+ rv = lock_manager.lock!(resource_key, ttl) { :success }
+ expect(rv).to eql(:success)
+ end
+
+ it 'automatically unlocks' do
+ lock_manager.lock!(resource_key, ttl) {}
+ expect(resource_key).to be_lockable(lock_manager, ttl)
+ end
+
+ it 'automatically unlocks when block raises exception' do
+ lock_manager.lock!(resource_key, ttl) { fail } rescue nil
+ expect(resource_key).to be_lockable(lock_manager, ttl)
+ end
+ end
+
+ context 'when lock is not available' do
+ before { @another_lock_info = lock_manager.lock(resource_key, ttl) }
+ after { lock_manager.unlock(@another_lock_info) }
+
+ it 'raises a LockError' do
+ expect { lock_manager.lock!(resource_key, ttl) {} }.to raise_error(Redlock::LockError)
+ end
+
+ it 'does not execute the block' do
+ expect do
+ begin
+ lock_manager.lock!(resource_key, ttl) { fail }
+ rescue Redlock::LockError
+ end
+ end.to_not raise_error
+ end
end
end
end