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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-11-18 16:16:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-18 16:16:36 +0300
commit311b0269b4eb9839fa63f80c8d7a58f32b8138a0 (patch)
tree07e7870bca8aed6d61fdcc810731c50d2c40af47 /spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
parent27909cef6c4170ed9205afa7426b8d3de47cbb0c (diff)
Add latest changes from gitlab-org/gitlab@14-5-stable-eev14.5.0-rc42
Diffstat (limited to 'spec/workers/loose_foreign_keys/cleanup_worker_spec.rb')
-rw-r--r--spec/workers/loose_foreign_keys/cleanup_worker_spec.rb153
1 files changed, 153 insertions, 0 deletions
diff --git a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
new file mode 100644
index 00000000000..544be2a69a6
--- /dev/null
+++ b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
@@ -0,0 +1,153 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe LooseForeignKeys::CleanupWorker do
+ include MigrationsHelpers
+
+ def create_table_structure
+ migration = ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers)
+
+ migration.create_table :_test_loose_fk_parent_table_1
+ migration.create_table :_test_loose_fk_parent_table_2
+
+ migration.create_table :_test_loose_fk_child_table_1_1 do |t|
+ t.bigint :parent_id
+ end
+
+ migration.create_table :_test_loose_fk_child_table_1_2 do |t|
+ t.bigint :parent_id_with_different_column
+ end
+
+ migration.create_table :_test_loose_fk_child_table_2_1 do |t|
+ t.bigint :parent_id
+ end
+
+ migration.track_record_deletions(:_test_loose_fk_parent_table_1)
+ migration.track_record_deletions(:_test_loose_fk_parent_table_2)
+ end
+
+ let!(:parent_model_1) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_loose_fk_parent_table_1'
+
+ include LooseForeignKey
+
+ loose_foreign_key :_test_loose_fk_child_table_1_1, :parent_id, on_delete: :async_delete
+ loose_foreign_key :_test_loose_fk_child_table_1_2, :parent_id_with_different_column, on_delete: :async_nullify
+ end
+ end
+
+ let!(:parent_model_2) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_loose_fk_parent_table_2'
+
+ include LooseForeignKey
+
+ loose_foreign_key :_test_loose_fk_child_table_2_1, :parent_id, on_delete: :async_delete
+ end
+ end
+
+ let!(:child_model_1) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_loose_fk_child_table_1_1'
+ end
+ end
+
+ let!(:child_model_2) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_loose_fk_child_table_1_2'
+ end
+ end
+
+ let!(:child_model_3) do
+ Class.new(ApplicationRecord) do
+ self.table_name = '_test_loose_fk_child_table_2_1'
+ end
+ end
+
+ let(:loose_fk_parent_table_1) { table(:_test_loose_fk_parent_table_1) }
+ let(:loose_fk_parent_table_2) { table(:_test_loose_fk_parent_table_2) }
+ let(:loose_fk_child_table_1_1) { table(:_test_loose_fk_child_table_1_1) }
+ let(:loose_fk_child_table_1_2) { table(:_test_loose_fk_child_table_1_2) }
+ let(:loose_fk_child_table_2_1) { table(:_test_loose_fk_child_table_2_1) }
+
+ before(:all) do
+ create_table_structure
+ end
+
+ after(:all) do
+ migration = ActiveRecord::Migration.new
+
+ migration.drop_table :_test_loose_fk_parent_table_1
+ migration.drop_table :_test_loose_fk_parent_table_2
+ migration.drop_table :_test_loose_fk_child_table_1_1
+ migration.drop_table :_test_loose_fk_child_table_1_2
+ migration.drop_table :_test_loose_fk_child_table_2_1
+ end
+
+ before do
+ parent_record_1 = loose_fk_parent_table_1.create!
+ loose_fk_child_table_1_1.create!(parent_id: parent_record_1.id)
+ loose_fk_child_table_1_2.create!(parent_id_with_different_column: parent_record_1.id)
+
+ parent_record_2 = loose_fk_parent_table_1.create!
+ 2.times { loose_fk_child_table_1_1.create!(parent_id: parent_record_2.id) }
+ 3.times { loose_fk_child_table_1_2.create!(parent_id_with_different_column: parent_record_2.id) }
+
+ parent_record_3 = loose_fk_parent_table_2.create!
+ 5.times { loose_fk_child_table_2_1.create!(parent_id: parent_record_3.id) }
+
+ parent_model_1.delete_all
+ parent_model_2.delete_all
+ end
+
+ it 'cleans up all rows' do
+ described_class.new.perform
+
+ expect(loose_fk_child_table_1_1.count).to eq(0)
+ expect(loose_fk_child_table_1_2.where(parent_id_with_different_column: nil).count).to eq(4)
+ expect(loose_fk_child_table_2_1.count).to eq(0)
+ end
+
+ context 'when deleting in batches' do
+ before do
+ stub_const('LooseForeignKeys::CleanupWorker::BATCH_SIZE', 2)
+ end
+
+ it 'cleans up all rows' do
+ expect(LooseForeignKeys::BatchCleanerService).to receive(:new).exactly(:twice).and_call_original
+
+ described_class.new.perform
+
+ expect(loose_fk_child_table_1_1.count).to eq(0)
+ expect(loose_fk_child_table_1_2.where(parent_id_with_different_column: nil).count).to eq(4)
+ expect(loose_fk_child_table_2_1.count).to eq(0)
+ end
+ end
+
+ context 'when the deleted rows count limit have been reached' do
+ def count_deletable_rows
+ loose_fk_child_table_1_1.count + loose_fk_child_table_2_1.count
+ end
+
+ before do
+ stub_const('LooseForeignKeys::ModificationTracker::MAX_DELETES', 2)
+ stub_const('LooseForeignKeys::CleanerService::DELETE_LIMIT', 1)
+ end
+
+ it 'cleans up 2 rows' do
+ expect { described_class.new.perform }.to change { count_deletable_rows }.by(-2)
+ end
+ end
+
+ context 'when the loose_foreign_key_cleanup feature flag is off' do
+ before do
+ stub_feature_flags(loose_foreign_key_cleanup: false)
+ end
+
+ it 'does nothing' do
+ expect { described_class.new.perform }.not_to change { LooseForeignKeys::DeletedRecord.status_processed.count }
+ end
+ end
+end