Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sidekiq Enterprise: until matcher #147

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion lib/rspec/sidekiq/matchers/be_unique.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def failure_message
if !interval_matches? && @expected_interval
"expected #{@klass} to be unique for #{@expected_interval} seconds, "\
"but its interval was #{actual_interval} seconds"
elsif !expiration_matches?
"expected #{@klass} to be unique until #{@expected_expiration}, "\
"but its unique_until was #{actual_expiration || 'not specified'}"
else
"expected #{@klass} to be unique in the queue"
end
Expand All @@ -33,14 +36,19 @@ def failure_message
def matches?(job)
@klass = job.is_a?(Class) ? job : job.class
@actual = @klass.get_sidekiq_options[unique_key]
!!(value_matches? && interval_matches?)
!!(value_matches? && interval_matches? && expiration_matches?)
end

def for(interval)
@expected_interval = interval
self
end

def until(expiration)
@expected_expiration = expiration
self
end

def interval_specified?
@expected_interval
end
Expand All @@ -49,6 +57,10 @@ def interval_matches?
!interval_specified? || actual_interval == @expected_interval
end

def expiration_matches?
@expected_expiration.nil? || actual_expiration == @expected_expiration
end

def failure_message_when_negated
"expected #{@klass} to not be unique in the queue"
end
Expand All @@ -59,6 +71,10 @@ def actual_interval
@klass.get_sidekiq_options['unique_job_expiration']
end

def actual_expiration
fail 'until is not supported for SidekiqUniqueJobs'
end

def value_matches?
[true, :all].include?(@actual)
end
Expand All @@ -73,6 +89,10 @@ def actual_interval
@actual
end

def actual_expiration
@klass.get_sidekiq_options['unique_until']
end

def value_matches?
@actual && @actual > 0
end
Expand Down
51 changes: 51 additions & 0 deletions spec/rspec/sidekiq/matchers/be_unique_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,57 @@
include_context 'a unique worker'
end

context '.until' do
let(:module_constant) { "Sidekiq::Enterprise" }
let(:expiration) { :success }
let(:interval) { 3.hours }
let(:sidekiq_options) { { unique_for: interval, unique_until: expiration } }
let(:worker) do
options = sidekiq_options
Class.new do
include ::Sidekiq::Worker
sidekiq_options options
def perform; end
end
end

before { stub_const(module_constant, true) }

subject do
stub_const('MuhWorker', worker)
MuhWorker
end

it { should be_unique.for(interval).until(:success) }

context 'errors' do
subject { expect(super()).to be_unique.until(:started) }

context 'when there is a mismatch' do
it do
expect { subject }.to raise_error RSpec::Expectations::ExpectationNotMetError,
'expected MuhWorker to be unique until started, but its unique_until was success'
end
end

context 'when not specified' do
let(:expiration) { nil }

it do
expect { subject }.to raise_error RSpec::Expectations::ExpectationNotMetError,
'expected MuhWorker to be unique until started, but its unique_until was not specified'
end
end

context 'when unique_until is not supported' do
let(:module_constant) { "SidekiqUniqueJobs" }
let(:sidekiq_options) { { unique: interval } }

it { expect { subject }.to raise_error 'until is not supported for SidekiqUniqueJobs' }
end
end
end

context 'a sidekiq-unique-jobs scheduled worker' do
let(:module_constant) { "SidekiqUniqueJobs" }
before { @worker = create_worker unique: :all }
Expand Down