diff options
author | Stan Hu <stanhu@gmail.com> | 2017-02-16 10:50:05 +0300 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2017-02-16 10:56:40 +0300 |
commit | 6606a45030ecd4035b095d33d32f1372c3562b02 (patch) | |
tree | e6d27e8d3e9d55e1e21d46d74934bc987041533c /spec/services/groups | |
parent | e90ec73f651ca6153a72437d4dd01f60c38839da (diff) |
Fix a number of race conditions that can occur during namespace deletion
There are two problems in the current implementation:
1. If a project is marked for deletion via the `pending_delete` flag
and then the namespace was quickly deleted, it's possible that the
namespace skips over that project and leaves that project in
an orphaned state.
2. Before namespace deletion, the namespace attempts to clean up
all the relevant storage paths. However, if all projects have been
removed synchronously, then the namespace will not be able to clean anything.
To prevent this, we should load the paths to be deleted before
actually destroying projects.
The specs were missing this second case due to a permission issue
that caused project removal never to happen.
Diffstat (limited to 'spec/services/groups')
-rw-r--r-- | spec/services/groups/destroy_service_spec.rb | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb index f86189b68e9..32c2ed8cae7 100644 --- a/spec/services/groups/destroy_service_spec.rb +++ b/spec/services/groups/destroy_service_spec.rb @@ -9,14 +9,18 @@ describe Groups::DestroyService, services: true do let!(:gitlab_shell) { Gitlab::Shell.new } let!(:remove_path) { group.path + "+#{group.id}+deleted" } + before do + group.add_user(user, Gitlab::Access::OWNER) + end + shared_examples 'group destruction' do |async| context 'database records' do before do destroy_group(group, user, async) end - it { expect(Group.all).not_to include(group) } - it { expect(Project.all).not_to include(project) } + it { expect(Group.unscoped.all).not_to include(group) } + it { expect(Project.unscoped.all).not_to include(project) } end context 'file system' do @@ -32,7 +36,7 @@ describe Groups::DestroyService, services: true do context 'Sidekiq fake' do before do - # Dont run sidekiq to check if renamed repository exists + # Don't run sidekiq to check if renamed repository exists Sidekiq::Testing.fake! { destroy_group(group, user, async) } end @@ -95,4 +99,13 @@ describe Groups::DestroyService, services: true do describe 'synchronous delete' do it_behaves_like 'group destruction', false end + + context 'projects in pending_delete' do + before do + project.pending_delete = true + project.save + end + + it_behaves_like 'group destruction', false + end end |