diff options
Diffstat (limited to 'spec/support/shared_examples/workers')
4 files changed, 156 insertions, 27 deletions
diff --git a/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb b/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb index 003b8d07819..e4e4bdd9e6c 100644 --- a/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb +++ b/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb @@ -341,15 +341,21 @@ RSpec.shared_examples 'it runs batched background migration jobs' do |tracking_d context 'health status' do subject(:migration_run) { described_class.new.perform } - it 'puts migration on hold when there is autovaccum activity on related tables' do - swapout_view_for_table(:postgres_autovacuum_activity, connection: connection) - create( - :postgres_autovacuum_activity, - table: migration.table_name, - table_identifier: "public.#{migration.table_name}" - ) + context 'with skip_autovacuum_health_check_for_ci_builds FF disabled' do + before do + stub_feature_flags(skip_autovacuum_health_check_for_ci_builds: false) + end - expect { migration_run }.to change { migration.reload.on_hold? }.from(false).to(true) + it 'puts migration on hold when there is autovaccum activity on related tables' do + swapout_view_for_table(:postgres_autovacuum_activity, connection: connection) + create( + :postgres_autovacuum_activity, + table: migration.table_name, + table_identifier: "public.#{migration.table_name}" + ) + + expect { migration_run }.to change { migration.reload.on_hold? }.from(false).to(true) + end end it 'puts migration on hold when the pending WAL count is above the limit' do diff --git a/spec/support/shared_examples/workers/idempotency_shared_examples.rb b/spec/support/shared_examples/workers/idempotency_shared_examples.rb index be43ea7d5f0..4d752afa00e 100644 --- a/spec/support/shared_examples/workers/idempotency_shared_examples.rb +++ b/spec/support/shared_examples/workers/idempotency_shared_examples.rb @@ -5,7 +5,7 @@ # # Usage: # -# include_examples 'an idempotent worker' do +# it_behaves_like 'an idempotent worker' do # it 'checks the side-effects for multiple calls' do # # it'll call the job's perform method 3 times # # by default. diff --git a/spec/support/shared_examples/workers/schedule_bulk_repository_shard_moves_shared_examples.rb b/spec/support/shared_examples/workers/schedule_bulk_repository_shard_moves_shared_examples.rb index 6707f65eb69..4b73c1720bc 100644 --- a/spec/support/shared_examples/workers/schedule_bulk_repository_shard_moves_shared_examples.rb +++ b/spec/support/shared_examples/workers/schedule_bulk_repository_shard_moves_shared_examples.rb @@ -6,7 +6,7 @@ RSpec.shared_examples 'schedules bulk repository shard moves' do describe "#perform" do before do - stub_storage_settings(destination_storage_name => { 'path' => 'tmp/tests/extra_storage' }) + stub_storage_settings(destination_storage_name => {}) allow(worker_klass).to receive(:perform_async) end diff --git a/spec/support/shared_examples/workers/update_repository_move_shared_examples.rb b/spec/support/shared_examples/workers/update_repository_move_shared_examples.rb index 9b7183a9eac..cb3cd81f5ce 100644 --- a/spec/support/shared_examples/workers/update_repository_move_shared_examples.rb +++ b/spec/support/shared_examples/workers/update_repository_move_shared_examples.rb @@ -1,43 +1,166 @@ # frozen_string_literal: true RSpec.shared_examples 'an update storage move worker' do + let(:worker) { described_class.new } + it 'has the `until_executed` deduplicate strategy' do expect(described_class.get_deduplicate_strategy).to eq(:until_executed) end - describe '#perform' do + describe '#perform', :clean_gitlab_redis_shared_state do let(:service) { double(:update_repository_storage_service) } before do allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(%w[default test_second_storage]) end - context 'without repository storage move' do - it 'calls the update repository storage service' do - expect(service_klass).to receive(:new).and_return(service) - expect(service).to receive(:execute) + describe 'deprecated method signature' do + # perform(container_id, new_repository_storage_key, repository_storage_move_id = nil) + subject { worker.perform(container.id, 'test_second_storage', repository_storage_move_id) } - expect do - subject.perform(container.id, 'test_second_storage') - end.to change { repository_storage_move_klass.count }.by(1) - - storage_move = container.repository_storage_moves.last - expect(storage_move).to have_attributes( - source_storage_name: 'default', - destination_storage_name: 'test_second_storage' - ) + context 'without repository storage move' do + let(:repository_storage_move_id) { nil } + + it 'calls the update repository storage service' do + expect(service_klass).to receive(:new).and_return(service) + expect(service).to receive(:execute) + + expect do + worker.perform(container.id, 'test_second_storage') + end.to change { repository_storage_move_klass.count }.by(1) + + storage_move = container.repository_storage_moves.last + expect(storage_move).to have_attributes( + source_storage_name: 'default', + destination_storage_name: 'test_second_storage' + ) + end + end + + context 'with repository storage move' do + let(:repository_storage_move_id) { repository_storage_move.id } + + before do + allow(service_klass).to receive(:new).and_return(service) + end + + it 'calls the update repository storage service' do + expect(service).to receive(:execute) + + expect do + subject + end.not_to change { repository_storage_move_klass.count } + end + + context 'when repository storage move raises an exception' do + let(:exception) { RuntimeError.new('boom') } + + it 'releases the exclusive lock' do + expect(service).to receive(:execute).and_raise(exception) + + allow_next_instance_of(Gitlab::ExclusiveLease) do |lease| + expect(lease).to receive(:cancel) + end + + expect { subject }.to raise_error(exception) + end + end + + context 'when exclusive lease already set' do + let(:lease_key) { [described_class.name.underscore, container.id].join(':') } + let(:exclusive_lease) { Gitlab::ExclusiveLease.new(lease_key, uuid: uuid, timeout: 1.minute) } + let(:uuid) { 'other_worker_jid' } + + it 'does not call the update repository storage service' do + expect(exclusive_lease.try_obtain).to eq(uuid) + expect(service).not_to receive(:execute) + + subject + + expect(repository_storage_move.reload).to be_failed + end + + context 'when exclusive lease was taken by the current worker' do + let(:uuid) { 'existing_worker_jid' } + + before do + allow(worker).to receive(:jid).and_return(uuid) + end + + it 'marks storage migration as failed' do + expect(exclusive_lease.try_obtain).to eq(worker.jid) + expect(service).not_to receive(:execute) + + subject + + expect(repository_storage_move.reload).to be_failed + end + end + end end end - context 'with repository storage move' do + describe 'new method signature' do + # perform(repository_storage_move_id) + subject { worker.perform(repository_storage_move.id) } + + before do + allow(service_klass).to receive(:new).and_return(service) + end + it 'calls the update repository storage service' do - expect(service_klass).to receive(:new).and_return(service) expect(service).to receive(:execute) expect do - subject.perform(nil, nil, repository_storage_move.id) + subject end.not_to change { repository_storage_move_klass.count } end + + context 'when repository storage move raises an exception' do + let(:exception) { RuntimeError.new('boom') } + + it 'releases the exclusive lock' do + expect(service).to receive(:execute).and_raise(exception) + + allow_next_instance_of(Gitlab::ExclusiveLease) do |lease| + expect(lease).to receive(:cancel) + end + + expect { subject }.to raise_error(exception) + end + end + + context 'when exclusive lease already set' do + let(:lease_key) { [described_class.name.underscore, repository_storage_move.container_id].join(':') } + let(:exclusive_lease) { Gitlab::ExclusiveLease.new(lease_key, uuid: uuid, timeout: 1.minute) } + let(:uuid) { 'other_worker_jid' } + + it 'does not call the update repository storage service' do + expect(exclusive_lease.try_obtain).to eq(uuid) + expect(service).not_to receive(:execute) + + subject + + expect(repository_storage_move.reload).to be_failed + end + + context 'when exclusive lease was taken by the current worker' do + let(:uuid) { 'existing_worker_jid' } + + before do + allow(worker).to receive(:jid).and_return(uuid) + end + + it 'marks storage migration as failed' do + expect(exclusive_lease.try_obtain).to eq(worker.jid) + expect(service).not_to receive(:execute) + + subject + + expect(repository_storage_move.reload).to be_failed + end + end + end end end end |