spec/client_spec.rb in redlock-0.1.8 vs spec/client_spec.rb in redlock-0.2.0

- old
+ new

@@ -1,11 +1,12 @@ require 'spec_helper' require 'securerandom' RSpec.describe Redlock::Client do # It is recommended to have at least 3 servers in production - let(:lock_manager) { Redlock::Client.new } + let(:lock_manager_opts) { { retry_count: 3 } } + let(:lock_manager) { Redlock::Client.new(Redlock::Client::DEFAULT_REDIS_URLS, lock_manager_opts) } let(:resource_key) { SecureRandom.hex(3) } let(:ttl) { 1000 } describe 'initialize' do it 'accepts both redis URLs and Redis objects' do @@ -41,20 +42,20 @@ @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 - context 'when extend_life flag is given' do + context 'when extend_only_if_life flag is given' do it 'does not extend a non-existent lock' do - @lock_info = lock_manager.lock(resource_key, ttl, extend: {value: 'hello world'}, extend_life: true) + @lock_info = lock_manager.lock(resource_key, ttl, extend: {value: 'hello world'}, extend_only_if_life: true) expect(@lock_info).to eq(false) end end - context 'when extend_life flag is not given' do + context 'when extend_only_if_life flag is not given' do 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'}, extend_life: false) + @lock_info = lock_manager.lock(resource_key, ttl, extend: {value: 'hello world'}, extend_only_if_life: false) 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 end @@ -77,9 +78,36 @@ 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 + + it 'retries up to \'retry_count\' times' do + expect(lock_manager).to receive(:lock_instances).exactly( + lock_manager_opts[:retry_count]).times.and_return(false) + lock_manager.lock(resource_key, ttl) + end + + it 'sleeps in between retries' do + expect(lock_manager).to receive(:sleep).exactly(lock_manager_opts[:retry_count] - 1).times + lock_manager.lock(resource_key, ttl) + end + + it 'sleeps at least the specified retry_delay in milliseconds' do + expected_minimum = described_class::DEFAULT_RETRY_DELAY + expect(lock_manager).to receive(:sleep) do |sleep| + expect(sleep).to satisfy { |value| value >= expected_minimum / 1000.to_f } + end.at_least(:once) + lock_manager.lock(resource_key, ttl) + end + + it 'sleeps a maximum of retry_delay + retry_jitter in milliseconds' do + expected_maximum = described_class::DEFAULT_RETRY_DELAY + described_class::DEFAULT_RETRY_JITTER + expect(lock_manager).to receive(:sleep) do |sleep| + expect(sleep).to satisfy { |value| value < expected_maximum / 1000.to_f } + end.at_least(:once) + lock_manager.lock(resource_key, ttl) end end context 'when script cache has been flushed' do before(:each) do