1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe RepositoryForkWorker, feature_category: :source_code_management do
include ProjectForksHelper
describe 'modules' do
it 'includes ProjectImportOptions' do
expect(described_class).to include_module(ProjectImportOptions)
end
end
describe "#perform" do
let(:project) { create(:project, :public, :repository) }
let(:forked_project) { create(:project, :repository, :import_scheduled) }
before do
fork_project(project, forked_project.creator, target_project: forked_project, repository: true)
end
shared_examples 'RepositoryForkWorker performing' do |branch|
def expect_fork_repository(success:, branch:)
allow(::Gitlab::GitalyClient::RepositoryService).to receive(:new).and_call_original
expect_next_instance_of(::Gitlab::GitalyClient::RepositoryService, forked_project.repository.raw) do |svc|
exp = expect(svc).to receive(:fork_repository).with(project.repository.raw, branch)
if success
exp.and_return(true)
else
exp.and_raise(GRPC::BadStatus, 'Fork failed in tests')
end
end
end
describe 'when a worker was reset without cleanup' do
let(:jid) { '12345678' }
it 'creates a new repository from a fork' do
allow(subject).to receive(:jid).and_return(jid)
expect_fork_repository(success: true, branch: branch)
perform!
end
end
it "creates a new repository from a fork" do
expect_fork_repository(success: true, branch: branch)
perform!
end
it 'protects the default branch' do
expect_fork_repository(success: true, branch: branch)
perform!
expect(forked_project.protected_branches.first.name).to eq(forked_project.default_branch)
end
it 'flushes various caches' do
expect_fork_repository(success: true, branch: branch)
# Works around https://github.com/rspec/rspec-mocks/issues/910
expect(Project).to receive(:find).with(forked_project.id).and_return(forked_project)
expect(forked_project.repository).to receive(:expire_emptiness_caches)
.and_call_original
expect(forked_project.repository).to receive(:expire_exists_cache)
.and_call_original
expect(forked_project.wiki.repository).to receive(:expire_emptiness_caches)
.and_call_original
expect(forked_project.wiki.repository).to receive(:expire_exists_cache)
.and_call_original
perform!
end
it 'handles bad fork' do
error_message = "Unable to fork project #{forked_project.id} for repository #{project.disk_path} -> #{forked_project.disk_path}: Failed to create fork repository"
expect_fork_repository(success: false, branch: branch)
expect { perform! }.to raise_error(StandardError, error_message)
end
it 'calls Projects::LfsPointers::LfsLinkService#execute with OIDs of source project LFS objects' do
expect_fork_repository(success: true, branch: branch)
expect_next_instance_of(Projects::LfsPointers::LfsLinkService) do |service|
expect(service).to receive(:execute).with(project.lfs_objects_oids)
end
perform!
end
it "handles LFS objects link failure" do
error_message = "Unable to fork project #{forked_project.id} for repository #{project.disk_path} -> #{forked_project.disk_path}: Source project has too many LFS objects"
expect_fork_repository(success: true, branch: branch)
expect_next_instance_of(Projects::LfsPointers::LfsLinkService) do |service|
expect(service).to receive(:execute).and_raise(Projects::LfsPointers::LfsLinkService::TooManyOidsError)
end
expect { perform! }.to raise_error(StandardError, error_message)
end
end
context 'only project ID passed' do
def perform!
subject.perform(forked_project.id)
end
it_behaves_like 'RepositoryForkWorker performing'
end
context 'when a specific branch is requested' do
def perform!
forked_project.create_import_data(data: { fork_branch: 'wip' })
subject.perform(forked_project.id)
end
it_behaves_like 'RepositoryForkWorker performing', 'wip'
end
context 'project ID, storage and repo paths passed' do
def perform!
subject.perform(forked_project.id, 'repos/path', project.disk_path)
end
it_behaves_like 'RepositoryForkWorker performing'
end
end
end
|