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/workers/container_registry/delete_container_repository_worker_spec.rb')
-rw-r--r--spec/workers/container_registry/delete_container_repository_worker_spec.rb146
1 files changed, 146 insertions, 0 deletions
diff --git a/spec/workers/container_registry/delete_container_repository_worker_spec.rb b/spec/workers/container_registry/delete_container_repository_worker_spec.rb
new file mode 100644
index 00000000000..381e0cc164c
--- /dev/null
+++ b/spec/workers/container_registry/delete_container_repository_worker_spec.rb
@@ -0,0 +1,146 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ContainerRegistry::DeleteContainerRepositoryWorker, :aggregate_failures do
+ let_it_be_with_reload(:container_repository) { create(:container_repository) }
+ let_it_be(:second_container_repository) { create(:container_repository) }
+
+ let(:worker) { described_class.new }
+
+ describe '#perform_work' do
+ subject(:perform_work) { worker.perform_work }
+
+ context 'with no work to do - no container repositories pending deletion' do
+ it 'will not delete any container repository' do
+ expect(::Projects::ContainerRepository::CleanupTagsService).not_to receive(:new)
+
+ expect { perform_work }.to not_change { ContainerRepository.count }
+ end
+ end
+
+ context 'with work to do' do
+ let(:tags_count) { 0 }
+ let(:cleanup_tags_service_response) { { status: :success, original_size: 100, deleted_size: 0 } }
+ let(:cleanup_tags_service_double) do
+ instance_double('Projects::ContainerRepository::CleanupTagsService', execute: cleanup_tags_service_response)
+ end
+
+ before do
+ container_repository.delete_scheduled!
+ allow(Projects::ContainerRepository::CleanupTagsService)
+ .to receive(:new)
+ .with(container_repository: container_repository, params: described_class::CLEANUP_TAGS_SERVICE_PARAMS)
+ .and_return(cleanup_tags_service_double)
+ end
+
+ it 'picks and destroys the delete scheduled container repository' do
+ expect_next_pending_destruction_container_repository do |repo|
+ expect_logs_on(repo, tags_size_before_delete: 100, deleted_tags_size: 0)
+ expect(repo).to receive(:destroy!).and_call_original
+ end
+ perform_work
+ expect(ContainerRepository.all).to contain_exactly(second_container_repository)
+ end
+
+ context 'with an error during the tags cleanup' do
+ let(:cleanup_tags_service_response) { { status: :error, original_size: 100, deleted_size: 0 } }
+
+ it 'does not delete the container repository' do
+ expect_next_pending_destruction_container_repository do |repo|
+ expect_logs_on(repo, tags_size_before_delete: 100, deleted_tags_size: 0)
+ expect(repo).to receive(:set_delete_scheduled_status).and_call_original
+ expect(repo).not_to receive(:destroy!)
+ end
+ expect { perform_work }.to not_change(ContainerRepository, :count)
+ .and not_change { container_repository.reload.status }
+ expect(container_repository.delete_started_at).to eq(nil)
+ end
+ end
+
+ context 'with an error during the destroy' do
+ it 'does not delete the container repository' do
+ expect_next_pending_destruction_container_repository do |repo|
+ expect_logs_on(repo, tags_size_before_delete: 100, deleted_tags_size: 0)
+ expect(repo).to receive(:destroy!).and_raise('Error!')
+ expect(repo).to receive(:set_delete_scheduled_status).and_call_original
+ end
+
+ expect(::Gitlab::ErrorTracking).to receive(:log_exception)
+ .with(instance_of(RuntimeError), class: described_class.name)
+ expect { perform_work }.to not_change(ContainerRepository, :count)
+ .and not_change { container_repository.reload.status }
+ expect(container_repository.delete_started_at).to eq(nil)
+ end
+ end
+
+ context 'with tags left to destroy' do
+ let(:tags_count) { 10 }
+
+ it 'does not delete the container repository' do
+ expect_next_pending_destruction_container_repository do |repo|
+ expect(repo).not_to receive(:destroy!)
+ expect(repo).to receive(:set_delete_scheduled_status).and_call_original
+ end
+
+ expect { perform_work }.to not_change(ContainerRepository, :count)
+ .and not_change { container_repository.reload.status }
+ expect(container_repository.delete_started_at).to eq(nil)
+ end
+ end
+
+ context 'with no tags on the container repository' do
+ let(:tags_count) { 0 }
+ let(:cleanup_tags_service_response) { { status: :success, original_size: 0, deleted_size: 0 } }
+
+ it 'picks and destroys the delete scheduled container repository' do
+ expect_next_pending_destruction_container_repository do |repo|
+ expect_logs_on(repo, tags_size_before_delete: 0, deleted_tags_size: 0)
+ expect(repo).to receive(:destroy!).and_call_original
+ end
+ perform_work
+ expect(ContainerRepository.all).to contain_exactly(second_container_repository)
+ end
+ end
+
+ def expect_next_pending_destruction_container_repository
+ original_method = ContainerRepository.method(:next_pending_destruction)
+ expect(ContainerRepository).to receive(:next_pending_destruction).with(order_by: nil) do
+ original_method.call(order_by: nil).tap do |repo|
+ allow(repo).to receive(:tags_count).and_return(tags_count)
+ expect(repo).to receive(:set_delete_ongoing_status).and_call_original
+ yield repo
+ end
+ end
+ end
+
+ def expect_logs_on(container_repository, tags_size_before_delete:, deleted_tags_size:)
+ payload = {
+ project_id: container_repository.project.id,
+ container_repository_id: container_repository.id,
+ container_repository_path: container_repository.path,
+ tags_size_before_delete: tags_size_before_delete,
+ deleted_tags_size: deleted_tags_size
+ }
+ expect(worker.logger).to receive(:info).with(worker.structured_payload(payload))
+ .and_call_original
+ end
+ end
+ end
+
+ describe '#max_running_jobs' do
+ subject { worker.max_running_jobs }
+
+ it { is_expected.to eq(described_class::MAX_CAPACITY) }
+ end
+
+ describe '#remaining_work_count' do
+ let_it_be(:delete_scheduled_container_repositories) do
+ create_list(:container_repository, described_class::MAX_CAPACITY + 2, :status_delete_scheduled)
+ end
+
+ subject { worker.remaining_work_count }
+
+ it { is_expected.to eq(described_class::MAX_CAPACITY + 1) }
+ end
+end