spec/client_spec.rb in redlock-2.0.1 vs spec/client_spec.rb in redlock-2.0.2

- old
+ new

@@ -74,10 +74,42 @@ describe 'lock' do context 'when lock is available' do after(:each) { lock_manager.unlock(@lock_info) if @lock_info } + context 'when redis connection error occurs' do + let(:servers_with_quorum) { + [ + "redis://#{redis1_host}:#{redis1_port}", + "redis://#{redis2_host}:#{redis2_port}", + unreachable_redis + ] + } + + let(:servers_without_quorum) { + [ + "redis://#{redis1_host}:#{redis1_port}", + unreachable_redis, + unreachable_redis + ] + } + + it 'locks if majority of redis instances are available' do + redlock = Redlock::Client.new(servers_with_quorum) + + expect(redlock.lock(resource_key, ttl)).to be_truthy + end + + it 'fails to acquire a lock if majority of Redis instances are not available' do + redlock = Redlock::Client.new(servers_without_quorum) + + expect { + redlock.lock(resource_key, ttl) + }.to raise_error(Redlock::LockAcquisitionError) + end + end + it 'locks' do @lock_info = lock_manager.lock(resource_key, ttl) expect(resource_key).to_not be_lockable(lock_manager, ttl) end @@ -264,11 +296,14 @@ redis_instance = lock_manager.instance_variable_get(:@servers).first redis_instance.instance_variable_set(:@redis, unreachable_redis) expect { lock_manager.lock(resource_key, ttl) - }.to raise_error(RedisClient::CannotConnectError) + }.to raise_error(Redlock::LockAcquisitionError) do |e| + expect(e.errors[0]).to be_a(RedisClient::CannotConnectError) + expect(e.errors.count).to eq 1 + end end end context 'when a server comes back' do it 'recovers from connection issues' do @@ -276,11 +311,14 @@ redis_instance = lock_manager.instance_variable_get(:@servers).first old_redis = redis_instance.instance_variable_get(:@redis) redis_instance.instance_variable_set(:@redis, unreachable_redis) expect { lock_manager.lock(resource_key, ttl) - }.to raise_error(RedisClient::CannotConnectError) + }.to raise_error(Redlock::LockAcquisitionError) do |e| + expect(e.errors[0]).to be_a(RedisClient::CannotConnectError) + expect(e.errors.count).to eq 1 + end redis_instance.instance_variable_set(:@redis, old_redis) expect(lock_manager.lock(resource_key, ttl)).to be_truthy end end @@ -306,14 +344,18 @@ context 'when the script re-loading fails' do it 'does not try to to load the scripts to cache again twice' do # This time we do not pass it through to Redis, in order to simulate a passing # call to LOAD SCRIPT followed by another NOSCRIPT error. Imagine someone # repeatedly calling SCRIPT FLUSH on our Redis instance. - expect(@manipulated_instance).to receive(:load_scripts) + expect(@manipulated_instance).to receive(:load_scripts).exactly(8).times expect { lock_manager.lock(resource_key, ttl) - }.to raise_error(/NOSCRIPT/) + }.to raise_error(Redlock::LockAcquisitionError) do |e| + expect(e.errors[0]).to be_a(RedisClient::CommandError) + expect(e.errors[0].message).to match(/NOSCRIPT/) + expect(e.errors.count).to eq 1 + end end end context 'when the script re-loading succeeds' do it 'locks' do