diff --git a/lib/redlock/client.rb b/lib/redlock/client.rb index d547f21..46003bd 100644 --- a/lib/redlock/client.rb +++ b/lib/redlock/client.rb @@ -30,13 +30,27 @@ def initialize(servers = DEFAULT_REDIS_URLS, options = {}) @retry_delay = options[:retry_delay] || DEFAULT_RETRY_DELAY end + def testing=(mode) + @testing_mode = mode + end + # Locks a resource for a given time. # Params: # +resource+:: the resource (or key) string to be locked. # +ttl+:: The time-to-live in ms for the lock. # +block+:: an optional block that automatically unlocks the lock. def lock(resource, ttl, &block) - lock_info = try_lock_instances(resource, ttl) + if @testing_mode == :bypass + lock_info = { + validity: ttl, + resource: resource, + value: SecureRandom.uuid + } + elsif @testing_mode == :fail + return false + else + lock_info = try_lock_instances(resource, ttl) + end if block_given? begin @@ -54,6 +68,8 @@ def lock(resource, ttl, &block) # Params: # +lock_info+:: the lock that has been acquired when you locked the resource. def unlock(lock_info) + return if @testing_mode == :bypass + @servers.each { |s| s.unlock(lock_info[:resource], lock_info[:value]) } end diff --git a/spec/client_spec.rb b/spec/client_spec.rb index f8d7e05..c0ebd73 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -94,6 +94,30 @@ end end end + + context 'when testing with bypass mode' do + before { lock_manager.testing = :bypass } + after { lock_manager.testing = nil } + + it 'bypasses the redis servers' do + expect(lock_manager).to_not receive(:try_lock_instances) + lock_manager.lock(resource_key, ttl) do |lock_info| + expect(lock_info).to be_lock_info_for(resource_key) + end + end + end + + context 'when testing with fail mode' do + before { lock_manager.testing = :fail } + after { lock_manager.testing = nil } + + it 'fails' do + expect(lock_manager).to_not receive(:try_lock_instances) + lock_manager.lock(resource_key, ttl) do |lock_info| + expect(lock_info).to eql(false) + end + end + end end describe 'unlock' do