Commit 76074cce authored by Dylan Griffith's avatar Dylan Griffith

Merge branch 'mk/refactor-reenqueuer-tests' into 'master'

Refactor Reenqueuer shared examples

See merge request gitlab-org/gitlab!45963
parents 894d255e 9a2bf96c
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# - `#lease_timeout` # - `#lease_timeout`
# #
# The worker spec should include `it_behaves_like 'reenqueuer'` and # The worker spec should include `it_behaves_like 'reenqueuer'` and
# `it_behaves_like 'it is rate limited to 1 call per'`. # `it_behaves_like '#perform is rate limited to 1 call per'`.
# #
# Optionally override `#minimum_duration` to adjust the rate limit. # Optionally override `#minimum_duration` to adjust the rate limit.
# #
......
...@@ -9,9 +9,10 @@ RSpec.describe Geo::Secondary::RegistryConsistencyWorker, :geo do ...@@ -9,9 +9,10 @@ RSpec.describe Geo::Secondary::RegistryConsistencyWorker, :geo do
let_it_be(:primary) { create(:geo_node, :primary) } let_it_be(:primary) { create(:geo_node, :primary) }
let_it_be(:secondary) { create(:geo_node) } let_it_be(:secondary) { create(:geo_node) }
let(:worker_class) { described_class }
let(:batch_size) { described_class::BATCH_SIZE } let(:batch_size) { described_class::BATCH_SIZE }
subject(:job) { described_class.new }
before do before do
stub_current_geo_node(secondary) stub_current_geo_node(secondary)
stub_registry_replication_config(enabled: true) stub_registry_replication_config(enabled: true)
...@@ -31,9 +32,7 @@ RSpec.describe Geo::Secondary::RegistryConsistencyWorker, :geo do ...@@ -31,9 +32,7 @@ RSpec.describe Geo::Secondary::RegistryConsistencyWorker, :geo do
allow(subject).to receive(:sleep) # faster tests allow(subject).to receive(:sleep) # faster tests
end end
it_behaves_like 'it is rate limited to 1 call per', 5.seconds do it_behaves_like '#perform is rate limited to 1 call per', 5.seconds
let(:rate_limited_method) { subject.perform }
end
context 'when RegistryConsistencyService#execute returns true at least once' do context 'when RegistryConsistencyService#execute returns true at least once' do
before do before do
......
# frozen_string_literal: true # frozen_string_literal: true
# Expects `worker_class` to be defined # Expects `subject` to be a job/worker instance
RSpec.shared_examples 'reenqueuer' do RSpec.shared_examples 'reenqueuer' do
subject(:job) { worker_class.new }
before do before do
allow(job).to receive(:sleep) # faster tests allow(subject).to receive(:sleep) # faster tests
end end
it 'implements lease_timeout' do it 'implements lease_timeout' do
expect(job.lease_timeout).to be_a(ActiveSupport::Duration) expect(subject.lease_timeout).to be_a(ActiveSupport::Duration)
end end
describe '#perform' do describe '#perform' do
it 'tries to obtain a lease' do it 'tries to obtain a lease' do
expect_to_obtain_exclusive_lease(job.lease_key) expect_to_obtain_exclusive_lease(subject.lease_key)
job.perform subject.perform
end end
end end
end end
# Example usage: # Expects `subject` to be a job/worker instance
# RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_duration|
# it_behaves_like 'it is rate limited to 1 call per', 5.seconds do
# subject { described_class.new }
# let(:rate_limited_method) { subject.perform }
# end
#
RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration|
before do before do
# Allow Timecop freeze and travel without the block form # Allow Timecop freeze and travel without the block form
Timecop.safe_mode = false Timecop.safe_mode = false
Timecop.freeze Timecop.freeze
time_travel_during_rate_limited_method(actual_duration) time_travel_during_perform(actual_duration)
end end
after do after do
...@@ -48,7 +40,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration| ...@@ -48,7 +40,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration|
it 'sleeps exactly the minimum duration' do it 'sleeps exactly the minimum duration' do
expect(subject).to receive(:sleep).with(a_value_within(0.01).of(minimum_duration)) expect(subject).to receive(:sleep).with(a_value_within(0.01).of(minimum_duration))
rate_limited_method subject.perform
end end
end end
...@@ -58,7 +50,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration| ...@@ -58,7 +50,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration|
it 'sleeps 90% of minimum duration' do it 'sleeps 90% of minimum duration' do
expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.9 * minimum_duration)) expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.9 * minimum_duration))
rate_limited_method subject.perform
end end
end end
...@@ -68,7 +60,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration| ...@@ -68,7 +60,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration|
it 'sleeps 10% of minimum duration' do it 'sleeps 10% of minimum duration' do
expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.1 * minimum_duration)) expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.1 * minimum_duration))
rate_limited_method subject.perform
end end
end end
...@@ -78,7 +70,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration| ...@@ -78,7 +70,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration|
it 'does not sleep' do it 'does not sleep' do
expect(subject).not_to receive(:sleep) expect(subject).not_to receive(:sleep)
rate_limited_method subject.perform
end end
end end
...@@ -88,7 +80,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration| ...@@ -88,7 +80,7 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration|
it 'does not sleep' do it 'does not sleep' do
expect(subject).not_to receive(:sleep) expect(subject).not_to receive(:sleep)
rate_limited_method subject.perform
end end
end end
...@@ -98,11 +90,11 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration| ...@@ -98,11 +90,11 @@ RSpec.shared_examples 'it is rate limited to 1 call per' do |minimum_duration|
it 'does not sleep' do it 'does not sleep' do
expect(subject).not_to receive(:sleep) expect(subject).not_to receive(:sleep)
rate_limited_method subject.perform
end end
end end
def time_travel_during_rate_limited_method(actual_duration) def time_travel_during_perform(actual_duration)
# Save the original implementation of ensure_minimum_duration # Save the original implementation of ensure_minimum_duration
original_ensure_minimum_duration = subject.method(:ensure_minimum_duration) original_ensure_minimum_duration = subject.method(:ensure_minimum_duration)
......
...@@ -40,9 +40,7 @@ RSpec.describe Reenqueuer do ...@@ -40,9 +40,7 @@ RSpec.describe Reenqueuer do
it_behaves_like 'reenqueuer' it_behaves_like 'reenqueuer'
it_behaves_like 'it is rate limited to 1 call per', 5.seconds do it_behaves_like '#perform is rate limited to 1 call per', 5.seconds
let(:rate_limited_method) { subject.perform }
end
it 'disables Sidekiq retries' do it 'disables Sidekiq retries' do
expect(job.sidekiq_options_hash).to include('retry' => false) expect(job.sidekiq_options_hash).to include('retry' => false)
...@@ -98,7 +96,7 @@ RSpec.describe Reenqueuer::ReenqueuerSleeper do ...@@ -98,7 +96,7 @@ RSpec.describe Reenqueuer::ReenqueuerSleeper do
Class.new do Class.new do
include Reenqueuer::ReenqueuerSleeper include Reenqueuer::ReenqueuerSleeper
def rate_limited_method def perform
ensure_minimum_duration(11.seconds) do ensure_minimum_duration(11.seconds) do
# do work # do work
end end
...@@ -108,12 +106,11 @@ RSpec.describe Reenqueuer::ReenqueuerSleeper do ...@@ -108,12 +106,11 @@ RSpec.describe Reenqueuer::ReenqueuerSleeper do
subject(:dummy) { dummy_class.new } subject(:dummy) { dummy_class.new }
# Test that rate_limited_method is rate limited by ensure_minimum_duration # Slightly higher-level test of ensure_minimum_duration since we conveniently
it_behaves_like 'it is rate limited to 1 call per', 11.seconds do # already have this shared example anyway.
let(:rate_limited_method) { dummy.rate_limited_method } it_behaves_like '#perform is rate limited to 1 call per', 11.seconds
end
# Test ensure_minimum_duration more directly # Unit test ensure_minimum_duration
describe '#ensure_minimum_duration' do describe '#ensure_minimum_duration' do
around do |example| around do |example|
# Allow Timecop.travel without the block form # Allow Timecop.travel without the block form
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment