summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2018-09-05 23:33:30 -0700
committerStan Hu <stanhu@gmail.com>2018-09-07 12:42:59 -0700
commit5830d1143dbf6b2958153233279896961e9a44df (patch)
treec3828d2fb9a5fbd2edc1c0c4a74537c6efe95d8c /spec
parent272281e4729c9e2193acea84394a191cfe2496af (diff)
downloadgitlab-ce-5830d1143dbf6b2958153233279896961e9a44df.tar.gz
Delete a container registry asynchronously
When a container registry has many tags, it's easy for the DELETE call to take more than 60 seconds and fail. This can also leave the registry in a bad state with null bytes since some of the images have been deleted with tags still pointing to them. In addition, we have to prevent users from accidentally initiating the delete multiple times or this could leave the registry with orphaned tags. This commit also adds a flash message to notify the user the registry is scheduled for deletion. Closes #49926, #51063
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/registry/repositories_controller_spec.rb5
-rw-r--r--spec/services/projects/container_repository/destroy_service_spec.rb40
-rw-r--r--spec/workers/delete_container_repository_worker_spec.rb33
3 files changed, 76 insertions, 2 deletions
diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb
index 17769a14def..d11e42b411b 100644
--- a/spec/controllers/projects/registry/repositories_controller_spec.rb
+++ b/spec/controllers/projects/registry/repositories_controller_spec.rb
@@ -86,9 +86,10 @@ describe Projects::Registry::RepositoriesController do
stub_container_registry_tags(repository: :any, tags: [])
end
- it 'deletes a repository' do
- expect { delete_repository(repository) }.to change { ContainerRepository.all.count }.by(-1)
+ it 'schedules a job to delete a repository' do
+ expect(DeleteContainerRepositoryWorker).to receive(:perform_async).with(user.id, repository.id)
+ delete_repository(repository)
expect(response).to have_gitlab_http_status(:no_content)
end
end
diff --git a/spec/services/projects/container_repository/destroy_service_spec.rb b/spec/services/projects/container_repository/destroy_service_spec.rb
new file mode 100644
index 00000000000..307ccc88865
--- /dev/null
+++ b/spec/services/projects/container_repository/destroy_service_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::ContainerRepository::DestroyService do
+ set(:user) { create(:user) }
+ set(:project) { create(:project, :private) }
+
+ subject { described_class.new(project, user) }
+
+ before do
+ stub_container_registry_config(enabled: true)
+ end
+
+ context 'when user does not have access to registry' do
+ let!(:repository) { create(:container_repository, :root, project: project) }
+
+ it 'does not delete a repository' do
+ expect { subject.execute(repository) }.not_to change { ContainerRepository.all.count }
+ end
+ end
+
+ context 'when user has access to registry' do
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when root container repository exists' do
+ let!(:repository) { create(:container_repository, :root, project: project) }
+
+ before do
+ stub_container_registry_tags(repository: :any, tags: [])
+ end
+
+ it 'deletes the repository' do
+ expect { described_class.new(project, user).execute(repository) }.to change { ContainerRepository.all.count }.by(-1)
+ end
+ end
+ end
+end
diff --git a/spec/workers/delete_container_repository_worker_spec.rb b/spec/workers/delete_container_repository_worker_spec.rb
new file mode 100644
index 00000000000..8c40611a959
--- /dev/null
+++ b/spec/workers/delete_container_repository_worker_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe DeleteContainerRepositoryWorker do
+ let(:registry) { create(:container_repository) }
+ let(:project) { registry.project }
+ let(:user) { project.owner }
+
+ subject { described_class.new }
+
+ describe '#perform' do
+ it 'executes the destroy service' do
+ service = instance_double(Projects::ContainerRepository::DestroyService)
+ expect(service).to receive(:execute)
+ expect(Projects::ContainerRepository::DestroyService).to receive(:new).with(project, user).and_return(service)
+
+ subject.perform(user.id, registry.id)
+ end
+
+ it 'does not raise error when user could not be found' do
+ expect do
+ subject.perform(-1, registry.id)
+ end.not_to raise_error
+ end
+
+ it 'does not raise error when registry could not be found' do
+ expect do
+ subject.perform(user.id, -1)
+ end.not_to raise_error
+ end
+ end
+end