From 6438df3a1e0fb944485cebf07976160184697d72 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 20 Jan 2021 13:34:23 -0600 Subject: Add latest changes from gitlab-org/gitlab@13-8-stable-ee --- ...ule_bulk_repository_shard_moves_service_spec.rb | 12 ++ .../update_repository_storage_service_spec.rb | 137 +++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 spec/services/snippets/schedule_bulk_repository_shard_moves_service_spec.rb create mode 100644 spec/services/snippets/update_repository_storage_service_spec.rb (limited to 'spec/services/snippets') diff --git a/spec/services/snippets/schedule_bulk_repository_shard_moves_service_spec.rb b/spec/services/snippets/schedule_bulk_repository_shard_moves_service_spec.rb new file mode 100644 index 00000000000..764c7f94a46 --- /dev/null +++ b/spec/services/snippets/schedule_bulk_repository_shard_moves_service_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Snippets::ScheduleBulkRepositoryShardMovesService do + it_behaves_like 'moves repository shard in bulk' do + let_it_be_with_reload(:container) { create(:snippet, :repository) } + + let(:move_service_klass) { SnippetRepositoryStorageMove } + let(:bulk_worker_klass) { ::SnippetScheduleBulkRepositoryShardMovesWorker } + end +end diff --git a/spec/services/snippets/update_repository_storage_service_spec.rb b/spec/services/snippets/update_repository_storage_service_spec.rb new file mode 100644 index 00000000000..b2bcd620d76 --- /dev/null +++ b/spec/services/snippets/update_repository_storage_service_spec.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Snippets::UpdateRepositoryStorageService do + include Gitlab::ShellAdapter + + subject { described_class.new(repository_storage_move) } + + describe "#execute" do + let_it_be_with_reload(:snippet) { create(:snippet, :repository) } + let_it_be(:destination) { 'test_second_storage' } + let_it_be(:checksum) { snippet.repository.checksum } + + let(:repository_storage_move_state) { :scheduled } + let(:repository_storage_move) { create(:snippet_repository_storage_move, repository_storage_move_state, container: snippet, destination_storage_name: destination) } + let(:snippet_repository_double) { double(:repository) } + let(:original_snippet_repository_double) { double(:repository) } + + before do + allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(%w[default test_second_storage]) + allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original + allow(Gitlab::GitalyClient).to receive(:filesystem_id).with(destination).and_return(SecureRandom.uuid) + allow(Gitlab::Git::Repository).to receive(:new).and_call_original + allow(Gitlab::Git::Repository).to receive(:new) + .with(destination, snippet.repository.raw.relative_path, snippet.repository.gl_repository, snippet.repository.full_path) + .and_return(snippet_repository_double) + allow(Gitlab::Git::Repository).to receive(:new) + .with('default', snippet.repository.raw.relative_path, nil, nil) + .and_return(original_snippet_repository_double) + end + + 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 + snippet.repository.path_to_repo + end + + expect(snippet_repository_double).to receive(:replicate) + .with(snippet.repository.raw) + expect(snippet_repository_double).to receive(:checksum) + .and_return(checksum) + expect(original_snippet_repository_double).to receive(:remove) + + result = subject.execute + snippet.reload + + expect(result).to be_success + expect(snippet).not_to be_repository_read_only + expect(snippet.repository_storage).to eq(destination) + expect(gitlab_shell.repository_exists?('default', old_path)).to be(false) + expect(snippet.snippet_repository.shard_name).to eq(destination) + end + end + + context 'when the filesystems are the same' do + let(:destination) { snippet.repository_storage } + + it 'bails out and does nothing' do + result = subject.execute + + expect(result).to be_error + expect(result.message).to match(/SameFilesystemError/) + end + end + + context 'when the move fails' do + it 'unmarks the repository as read-only without updating the repository storage' do + expect(snippet_repository_double).to receive(:replicate) + .with(snippet.repository.raw) + .and_raise(Gitlab::Git::CommandError) + + result = subject.execute + + expect(result).to be_error + expect(snippet).not_to be_repository_read_only + expect(snippet.repository_storage).to eq('default') + expect(repository_storage_move).to be_failed + end + end + + context 'when the cleanup fails' do + it 'sets the correct state' do + expect(snippet_repository_double).to receive(:replicate) + .with(snippet.repository.raw) + expect(snippet_repository_double).to receive(:checksum) + .and_return(checksum) + expect(original_snippet_repository_double).to receive(:remove) + .and_raise(Gitlab::Git::CommandError) + + result = subject.execute + + expect(result).to be_error + expect(repository_storage_move).to be_cleanup_failed + end + end + + context 'when the checksum does not match' do + it 'unmarks the repository as read-only without updating the repository storage' do + expect(snippet_repository_double).to receive(:replicate) + .with(snippet.repository.raw) + expect(snippet_repository_double).to receive(:checksum) + .and_return('not matching checksum') + + result = subject.execute + + expect(result).to be_error + expect(snippet).not_to be_repository_read_only + expect(snippet.repository_storage).to eq('default') + end + end + + context 'when the repository move is finished' do + let(:repository_storage_move_state) { :finished } + + it 'is idempotent' do + expect do + result = subject.execute + + expect(result).to be_success + end.not_to change(repository_storage_move, :state) + end + end + + context 'when the repository move is failed' do + let(:repository_storage_move_state) { :failed } + + it 'is idempotent' do + expect do + result = subject.execute + + expect(result).to be_success + end.not_to change(repository_storage_move, :state) + end + end + end +end -- cgit v1.2.1