From 561e1b470f0a99fe6304c8f197348c47a637d594 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 2 Mar 2020 21:08:01 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../cleanup_tags_service_spec.rb | 84 +++++++++++++++++----- spec/services/projects/fork_service_spec.rb | 21 ++++++ spec/services/projects/lsif_data_service_spec.rb | 15 ++-- .../update_repository_storage_service_spec.rb | 83 +++++++++++++++++++++ spec/services/projects/update_service_spec.rb | 19 +++++ 5 files changed, 197 insertions(+), 25 deletions(-) create mode 100644 spec/services/projects/update_repository_storage_service_spec.rb (limited to 'spec/services/projects') diff --git a/spec/services/projects/container_repository/cleanup_tags_service_spec.rb b/spec/services/projects/container_repository/cleanup_tags_service_spec.rb index ef7e9cda9e0..96cddef4628 100644 --- a/spec/services/projects/container_repository/cleanup_tags_service_spec.rb +++ b/spec/services/projects/container_repository/cleanup_tags_service_spec.rb @@ -48,25 +48,37 @@ describe Projects::ContainerRepository::CleanupTagsService do end context 'when regex matching everything is specified' do + shared_examples 'removes all matches' do + it 'does remove B* and C' do + # The :A cannot be removed as config is shared with :latest + # The :E cannot be removed as it does not have valid manifest + + expect_delete('sha256:configB').twice + expect_delete('sha256:configC') + expect_delete('sha256:configD') + + is_expected.to include(status: :success, deleted: %w(D Bb Ba C)) + end + end + let(:params) do - { 'name_regex' => '.*' } + { 'name_regex_delete' => '.*' } end - it 'does remove B* and C' do - # The :A cannot be removed as config is shared with :latest - # The :E cannot be removed as it does not have valid manifest + it_behaves_like 'removes all matches' - expect_delete('sha256:configB').twice - expect_delete('sha256:configC') - expect_delete('sha256:configD') + context 'with deprecated name_regex param' do + let(:params) do + { 'name_regex' => '.*' } + end - is_expected.to include(status: :success, deleted: %w(D Bb Ba C)) + it_behaves_like 'removes all matches' end end - context 'when regex matching specific tags is used' do + context 'when delete regex matching specific tags is used' do let(:params) do - { 'name_regex' => 'C|D' } + { 'name_regex_delete' => 'C|D' } end it 'does remove C and D' do @@ -75,11 +87,37 @@ describe Projects::ContainerRepository::CleanupTagsService do is_expected.to include(status: :success, deleted: %w(D C)) end + + context 'with overriding allow regex' do + let(:params) do + { 'name_regex_delete' => 'C|D', + 'name_regex_keep' => 'C' } + end + + it 'does not remove C' do + expect_delete('sha256:configD') + + is_expected.to include(status: :success, deleted: %w(D)) + end + end + + context 'with name_regex_delete overriding deprecated name_regex' do + let(:params) do + { 'name_regex' => 'C|D', + 'name_regex_delete' => 'D' } + end + + it 'does not remove C' do + expect_delete('sha256:configD') + + is_expected.to include(status: :success, deleted: %w(D)) + end + end end context 'when removing a tagged image that is used by another tag' do let(:params) do - { 'name_regex' => 'Ba' } + { 'name_regex_delete' => 'Ba' } end it 'does not remove the tag' do @@ -89,9 +127,23 @@ describe Projects::ContainerRepository::CleanupTagsService do end end + context 'with allow regex value' do + let(:params) do + { 'name_regex_delete' => '.*', + 'name_regex_keep' => 'B.*' } + end + + it 'does not remove B*' do + expect_delete('sha256:configC') + expect_delete('sha256:configD') + + is_expected.to include(status: :success, deleted: %w(D C)) + end + end + context 'when removing keeping only 3' do let(:params) do - { 'name_regex' => '.*', + { 'name_regex_delete' => '.*', 'keep_n' => 3 } end @@ -104,7 +156,7 @@ describe Projects::ContainerRepository::CleanupTagsService do context 'when removing older than 1 day' do let(:params) do - { 'name_regex' => '.*', + { 'name_regex_delete' => '.*', 'older_than' => '1 day' } end @@ -118,7 +170,7 @@ describe Projects::ContainerRepository::CleanupTagsService do context 'when combining all parameters' do let(:params) do - { 'name_regex' => '.*', + { 'name_regex_delete' => '.*', 'keep_n' => 1, 'older_than' => '1 day' } end @@ -136,7 +188,7 @@ describe Projects::ContainerRepository::CleanupTagsService do context 'with valid container_expiration_policy param' do let(:params) do - { 'name_regex' => '.*', + { 'name_regex_delete' => '.*', 'keep_n' => 1, 'older_than' => '1 day', 'container_expiration_policy' => true } @@ -152,7 +204,7 @@ describe Projects::ContainerRepository::CleanupTagsService do context 'without container_expiration_policy param' do let(:params) do - { 'name_regex' => '.*', + { 'name_regex_delete' => '.*', 'keep_n' => 1, 'older_than' => '1 day' } end diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index fa6d42369c8..12c51d01d63 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -307,6 +307,27 @@ describe Projects::ForkService do end end + context 'when a project is already forked' do + it 'creates a new poolresository after the project is moved to a new shard' do + project = create(:project, :public, :repository) + fork_before_move = fork_project(project) + + # Stub everything required to move a project to a Gitaly shard that does not exist + stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/second_storage' }) + allow_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror).and_return(true) + + Projects::UpdateRepositoryStorageService.new(project).execute('test_second_storage') + fork_after_move = fork_project(project) + pool_repository_before_move = PoolRepository.joins(:shard) + .where(source_project: project, shards: { name: 'default' }).first + pool_repository_after_move = PoolRepository.joins(:shard) + .where(source_project: project, shards: { name: 'test_second_storage' }).first + + expect(fork_before_move.pool_repository).to eq(pool_repository_before_move) + expect(fork_after_move.pool_repository).to eq(pool_repository_after_move) + end + end + context 'when forking with object pools' do let(:fork_from_project) { create(:project, :public) } let(:forker) { create(:user) } diff --git a/spec/services/projects/lsif_data_service_spec.rb b/spec/services/projects/lsif_data_service_spec.rb index 93579869d1d..4866f848121 100644 --- a/spec/services/projects/lsif_data_service_spec.rb +++ b/spec/services/projects/lsif_data_service_spec.rb @@ -7,9 +7,8 @@ describe Projects::LsifDataService do let(:project) { build_stubbed(:project) } let(:path) { 'main.go' } let(:commit_id) { Digest::SHA1.hexdigest(SecureRandom.hex) } - let(:params) { { path: path, commit_id: commit_id } } - let(:service) { described_class.new(artifact.file, project, params) } + let(:service) { described_class.new(artifact.file, project, commit_id) } describe '#execute' do def highlighted_value(value) @@ -18,7 +17,7 @@ describe Projects::LsifDataService do context 'fetched lsif file', :use_clean_rails_memory_store_caching do it 'is cached' do - service.execute + service.execute(path) cached_data = Rails.cache.fetch("project:#{project.id}:lsif:#{commit_id}") @@ -30,7 +29,7 @@ describe Projects::LsifDataService do let(:path_prefix) { "/#{project.full_path}/-/blob/#{commit_id}" } it 'returns lsif ranges for the file' do - expect(service.execute).to eq([ + expect(service.execute(path)).to eq([ { end_char: 9, end_line: 6, @@ -87,7 +86,7 @@ describe Projects::LsifDataService do let(:path) { 'morestrings/reverse.go' } it 'returns lsif ranges for the file' do - expect(service.execute.first).to eq({ + expect(service.execute(path).first).to eq({ end_char: 2, end_line: 11, start_char: 1, @@ -102,7 +101,7 @@ describe Projects::LsifDataService do let(:path) { 'unknown.go' } it 'returns nil' do - expect(service.execute).to eq(nil) + expect(service.execute(path)).to eq(nil) end end end @@ -120,9 +119,7 @@ describe Projects::LsifDataService do end it 'fetches the document with the shortest absolute path' do - service.instance_variable_set(:@docs, docs) - - expect(service.__send__(:doc_id)).to eq(3) + expect(service.__send__(:find_doc_id, docs, path)).to eq(3) end end end diff --git a/spec/services/projects/update_repository_storage_service_spec.rb b/spec/services/projects/update_repository_storage_service_spec.rb new file mode 100644 index 00000000000..a0917f718e6 --- /dev/null +++ b/spec/services/projects/update_repository_storage_service_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Projects::UpdateRepositoryStorageService do + include Gitlab::ShellAdapter + + subject { described_class.new(project) } + + describe "#execute" do + let(:time) { Time.now } + + before do + allow(Time).to receive(:now).and_return(time) + end + + context 'without wiki and design repository' do + let(:project) { create(:project, :repository, repository_read_only: true, wiki_enabled: false) } + + context 'when the move succeeds' do + it 'moves the repository to the new storage and unmarks the repository as read only' do + old_path = Gitlab::GitalyClient::StorageSettings.allow_disk_access do + project.repository.path_to_repo + end + + expect_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror) + .with(project.repository.raw).and_return(true) + + subject.execute('test_second_storage') + expect(project).not_to be_repository_read_only + expect(project.repository_storage).to eq('test_second_storage') + expect(gitlab_shell.repository_exists?('default', old_path)).to be(false) + expect(project.project_repository.shard_name).to eq('test_second_storage') + end + end + + context 'when the project is already on the target storage' do + it 'bails out and does nothing' do + expect do + subject.execute(project.repository_storage) + end.to raise_error(described_class::RepositoryAlreadyMoved) + end + end + + context 'when the move fails' do + it 'unmarks the repository as read-only without updating the repository storage' do + expect_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror) + .with(project.repository.raw).and_return(false) + expect(GitlabShellWorker).not_to receive(:perform_async) + + subject.execute('test_second_storage') + + expect(project).not_to be_repository_read_only + expect(project.repository_storage).to eq('default') + end + end + end + + context 'with wiki repository' do + include_examples 'moves repository to another storage', 'wiki' do + let(:project) { create(:project, :repository, repository_read_only: true, wiki_enabled: true) } + let(:repository) { project.wiki.repository } + + before do + project.create_wiki + end + end + end + + context 'when a object pool was joined' do + let(:project) { create(:project, :repository, wiki_enabled: false, repository_read_only: true) } + let(:pool) { create(:pool_repository, :ready, source_project: project) } + + it 'leaves the pool' do + allow_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror).and_return(true) + + subject.execute('test_second_storage') + + expect(project.reload_pool_repository).to be_nil + end + end + end +end diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index 90fb6b932ee..8b5b6e5ac4e 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -613,6 +613,25 @@ describe Projects::UpdateService do end end + describe 'repository_storage' do + let(:admin) { create(:admin) } + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + let(:opts) { { repository_storage: 'test_second_storage' } } + + it 'calls the change repository storage method if the storage changed' do + expect(project).to receive(:change_repository_storage).with('test_second_storage') + + update_project(project, admin, opts).inspect + end + + it "doesn't call the change repository storage for non-admin users" do + expect(project).not_to receive(:change_repository_storage) + + update_project(project, user, opts).inspect + end + end + def update_project(project, user, opts) described_class.new(project, user, opts).execute end -- cgit v1.2.3