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