Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb')
-rw-r--r--spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb78
1 files changed, 78 insertions, 0 deletions
diff --git a/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb b/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb
index d3d57ea2444..538d9638879 100644
--- a/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb
+++ b/spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb
@@ -115,4 +115,82 @@ RSpec.describe LooseForeignKeys::BatchCleanerService do
expect(loose_fk_child_table_2.where(parent_id_with_different_column: other_parent_record.id).count).to eq(2)
end
end
+
+ describe 'fair queueing' do
+ context 'when the execution is over the limit' do
+ let(:modification_tracker) { instance_double(LooseForeignKeys::ModificationTracker) }
+ let(:over_limit_return_values) { [true] }
+ let(:deleted_record) { LooseForeignKeys::DeletedRecord.load_batch_for_table('public._test_loose_fk_parent_table', 1).first }
+ let(:deleted_records_rescheduled_counter) { Gitlab::Metrics.registry.get(:loose_foreign_key_rescheduled_deleted_records) }
+ let(:deleted_records_incremented_counter) { Gitlab::Metrics.registry.get(:loose_foreign_key_incremented_deleted_records) }
+
+ let(:cleaner) do
+ described_class.new(parent_table: '_test_loose_fk_parent_table',
+ loose_foreign_key_definitions: loose_foreign_key_definitions,
+ deleted_parent_records: LooseForeignKeys::DeletedRecord.load_batch_for_table('public._test_loose_fk_parent_table', 100),
+ modification_tracker: modification_tracker
+ )
+ end
+
+ before do
+ parent_record_1.delete
+ allow(modification_tracker).to receive(:over_limit?).and_return(*over_limit_return_values)
+ allow(modification_tracker).to receive(:add_deletions)
+ end
+
+ context 'when the deleted record is under the maximum allowed cleanup attempts' do
+ it 'updates the cleanup_attempts column', :aggregate_failures do
+ deleted_record.update!(cleanup_attempts: 1)
+
+ cleaner.execute
+
+ expect(deleted_record.reload.cleanup_attempts).to eq(2)
+ expect(deleted_records_incremented_counter.get(table: loose_fk_parent_table.table_name, db_config_name: 'main')).to eq(1)
+ end
+
+ context 'when the deleted record is above the maximum allowed cleanup attempts' do
+ it 'reschedules the record', :aggregate_failures do
+ deleted_record.update!(cleanup_attempts: LooseForeignKeys::BatchCleanerService::CLEANUP_ATTEMPTS_BEFORE_RESCHEDULE + 1)
+
+ freeze_time do
+ cleaner.execute
+
+ expect(deleted_record.reload).to have_attributes(
+ cleanup_attempts: 0,
+ consume_after: 5.minutes.from_now
+ )
+ expect(deleted_records_rescheduled_counter.get(table: loose_fk_parent_table.table_name, db_config_name: 'main')).to eq(1)
+ end
+ end
+ end
+
+ describe 'when over limit happens on the second cleanup call without skip locked' do
+ # over_limit? is called twice, we test here the 2nd call
+ # - When invoking cleanup with SKIP LOCKED
+ # - When invoking cleanup (no SKIP LOCKED)
+ let(:over_limit_return_values) { [false, true] }
+
+ it 'updates the cleanup_attempts column' do
+ expect(cleaner).to receive(:run_cleaner_service).twice
+
+ deleted_record.update!(cleanup_attempts: 1)
+
+ cleaner.execute
+
+ expect(deleted_record.reload.cleanup_attempts).to eq(2)
+ end
+ end
+ end
+
+ context 'when the lfk_fair_queueing FF is off' do
+ before do
+ stub_feature_flags(lfk_fair_queueing: false)
+ end
+
+ it 'does nothing' do
+ expect { cleaner.execute }.not_to change { deleted_record.reload.cleanup_attempts }
+ end
+ end
+ end
+ end
end