# frozen_string_literal: true require 'spec_helper' describe Projects::AfterRenameService do let(:rugged_config) { rugged_repo(project.repository).config } describe '#execute' do context 'using legacy storage' do let(:project) { create(:project, :repository, :legacy_storage) } let(:gitlab_shell) { Gitlab::Shell.new } let(:project_storage) { project.send(:storage) } before do # Project#gitlab_shell returns a new instance of Gitlab::Shell on every # call. This makes testing a bit easier. allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) allow(project) .to receive(:previous_changes) .and_return('path' => ['foo']) allow(project) .to receive(:path_was) .and_return('foo') stub_feature_flags(skip_hashed_storage_upgrade: false) end it 'renames a repository' do stub_container_registry_config(enabled: false) expect(gitlab_shell).to receive(:mv_repository) .ordered .with(project.repository_storage, "#{project.namespace.full_path}/foo", "#{project.full_path}") .and_return(true) expect(gitlab_shell).to receive(:mv_repository) .ordered .with(project.repository_storage, "#{project.namespace.full_path}/foo.wiki", "#{project.full_path}.wiki") .and_return(true) expect_any_instance_of(SystemHooksService) .to receive(:execute_hooks_for) .with(project, :rename) expect_any_instance_of(Gitlab::UploadsTransfer) .to receive(:rename_project) .with('foo', project.path, project.namespace.full_path) expect(project).to receive(:expire_caches_before_rename) described_class.new(project).execute end context 'container registry with images' do let(:container_repository) { create(:container_repository) } before do stub_container_registry_config(enabled: true) stub_container_registry_tags(repository: :any, tags: ['tag']) project.container_repositories << container_repository end it 'raises a RenameFailedError' do expect { described_class.new(project).execute } .to raise_error(described_class::RenameFailedError) end end context 'gitlab pages' do before do expect(project_storage).to receive(:rename_repo) { true } end it 'moves pages folder to new location' do expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project) described_class.new(project).execute end end context 'attachments' do before do expect(project_storage).to receive(:rename_repo) { true } end it 'moves uploads folder to new location' do expect_any_instance_of(Gitlab::UploadsTransfer).to receive(:rename_project) described_class.new(project).execute end end it 'updates project full path in .git/config' do allow(project_storage).to receive(:rename_repo).and_return(true) described_class.new(project).execute expect(rugged_config['gitlab.fullpath']).to eq(project.full_path) end end context 'using hashed storage' do let(:project) { create(:project, :repository, skip_disk_validation: true) } let(:gitlab_shell) { Gitlab::Shell.new } let(:hash) { Digest::SHA2.hexdigest(project.id.to_s) } let(:hashed_prefix) { File.join('@hashed', hash[0..1], hash[2..3]) } let(:hashed_path) { File.join(hashed_prefix, hash) } before do # Project#gitlab_shell returns a new instance of Gitlab::Shell on every # call. This makes testing a bit easier. allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) allow(project).to receive(:previous_changes).and_return('path' => ['foo']) stub_feature_flags(skip_hashed_storage_upgrade: false) stub_application_setting(hashed_storage_enabled: true) end context 'migration to hashed storage' do it 'calls HashedStorageMigrationService with correct options' do project = create(:project, :repository, :legacy_storage) allow(project).to receive(:previous_changes).and_return('path' => ['foo']) expect_next_instance_of(::Projects::HashedStorageMigrationService) do |service| expect(service).to receive(:execute).and_return(true) end described_class.new(project).execute end end it 'renames a repository' do stub_container_registry_config(enabled: false) expect(gitlab_shell).not_to receive(:mv_repository) expect_any_instance_of(SystemHooksService) .to receive(:execute_hooks_for) .with(project, :rename) expect(project).to receive(:expire_caches_before_rename) described_class.new(project).execute end context 'container registry with images' do let(:container_repository) { create(:container_repository) } before do stub_container_registry_config(enabled: true) stub_container_registry_tags(repository: :any, tags: ['tag']) project.container_repositories << container_repository end it 'raises a RenameFailedError' do expect { described_class.new(project).execute } .to raise_error(described_class::RenameFailedError) end end context 'gitlab pages' do it 'moves pages folder to new location' do expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project) described_class.new(project).execute end end context 'attachments' do it 'keeps uploads folder location unchanged' do expect_any_instance_of(Gitlab::UploadsTransfer).not_to receive(:rename_project) described_class.new(project).execute end context 'when not rolled out' do let(:project) { create(:project, :repository, storage_version: 1, skip_disk_validation: true) } it 'moves pages folder to hashed storage' do expect_next_instance_of(Projects::HashedStorage::MigrateAttachmentsService) do |service| expect(service).to receive(:execute) end described_class.new(project).execute end end end it 'updates project full path in .git/config' do described_class.new(project).execute expect(rugged_config['gitlab.fullpath']).to eq(project.full_path) end end end end