importer_spec.rb 6.4 KB
Newer Older
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
require 'spec_helper'

describe Gitlab::BareRepositoryImport::Importer, repository: true do
  let!(:admin) { create(:admin) }
  let!(:base_dir) { Dir.mktmpdir + '/' }
  let(:bare_repository) { Gitlab::BareRepositoryImport::Repository.new(base_dir, File.join(base_dir, "#{project_path}.git")) }

  subject(:importer) { described_class.new(admin, bare_repository) }

  before do
    allow(described_class).to receive(:log)
  end

  after do
    FileUtils.rm_rf(base_dir)
  end

  shared_examples 'importing a repository' do
    describe '.execute' do
      it 'creates a project for a repository in storage' do
        FileUtils.mkdir_p(File.join(base_dir, "#{project_path}.git"))
        fake_importer = double

        expect(described_class).to receive(:new).and_return(fake_importer)
        expect(fake_importer).to receive(:create_project_if_needed)

        described_class.execute(base_dir)
      end

      it 'skips wiki repos' do
        repo_dir = File.join(base_dir, 'the-group', 'the-project.wiki.git')
        FileUtils.mkdir_p(File.join(repo_dir))

        expect(described_class).to receive(:log).with(" * Skipping repo #{repo_dir}")
        expect(described_class).not_to receive(:new)

        described_class.execute(base_dir)
      end

      context 'without admin users' do
        let(:admin) { nil }

        it 'raises an error' do
          expect { described_class.execute(base_dir) }.to raise_error(Gitlab::BareRepositoryImport::Importer::NoAdminError)
        end
      end
    end

    describe '#create_project_if_needed' do
      it 'starts an import for a project that did not exist' do
        expect(importer).to receive(:create_project)

        importer.create_project_if_needed
      end

      it 'skips importing when the project already exists' do
        project = create(:project, path: 'a-project', namespace: existing_group)

        expect(importer).not_to receive(:create_project)
        expect(importer).to receive(:log).with(" * #{project.name} (#{project_path}) exists")

        importer.create_project_if_needed
      end

      it 'creates a project with the correct path in the database' do
        importer.create_project_if_needed

        expect(Project.find_by_full_path(project_path)).not_to be_nil
      end

71 72 73 74 75 76
      it 'does not schedule an import' do
        expect_any_instance_of(Project).not_to receive(:import_schedule)

        importer.create_project_if_needed
      end

77
      it 'creates the Git repo in disk' do
78
        create_bare_repository("#{project_path}.git")
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

        importer.create_project_if_needed

        project = Project.find_by_full_path(project_path)

        expect(File).to exist(File.join(project.repository_storage_path, project.disk_path + '.git'))
      end

      context 'hashed storage enabled' do
        it 'creates a project with the correct path in the database' do
          stub_application_setting(hashed_storage_enabled: true)

          importer.create_project_if_needed

          expect(Project.find_by_full_path(project_path)).not_to be_nil
        end
      end
    end
  end

  context 'with subgroups', :nested_groups do
    let(:project_path) { 'a-group/a-sub-group/a-project' }

    let(:existing_group) do
      group = create(:group, path: 'a-group')
      create(:group, path: 'a-sub-group', parent: group)
    end

    it_behaves_like 'importing a repository'
  end

  context 'without subgroups' do
    let(:project_path) { 'a-group/a-project' }
    let(:existing_group) { create(:group, path: 'a-group') }

    it_behaves_like 'importing a repository'
  end

  context 'without groups' do
    let(:project_path) { 'a-project' }

    it 'starts an import for a project that did not exist' do
      expect(importer).to receive(:create_project)

      importer.create_project_if_needed
    end

    it 'creates a project with the correct path in the database' do
      importer.create_project_if_needed

      expect(Project.find_by_full_path("#{admin.full_path}/#{project_path}")).not_to be_nil
    end

    it 'creates the Git repo in disk' do
133
      create_bare_repository("#{project_path}.git")
134 135 136 137 138 139

      importer.create_project_if_needed

      project = Project.find_by_full_path("#{admin.full_path}/#{project_path}")

      expect(File).to exist(File.join(project.repository_storage_path, project.disk_path + '.git'))
J
James Lopez 已提交
140
      expect(File).to exist(File.join(project.repository_storage_path, project.disk_path + '.wiki.git'))
141
    end
142 143

    it 'moves an existing project to the correct path' do
144 145 146
      # This is a quick way to get a valid repository instead of copying an
      # existing one. Since it's not persisted, the importer will try to
      # create the project.
147
      project = build(:project, :repository)
148 149 150 151 152 153 154 155 156 157 158
      original_commit_count = project.repository.commit_count

      bare_repo = Gitlab::BareRepositoryImport::Repository.new(project.repository_storage_path, project.repository.path)
      gitlab_importer = described_class.new(admin, bare_repo)

      expect(gitlab_importer).to receive(:create_project).and_call_original

      new_project = gitlab_importer.create_project_if_needed

      expect(new_project.repository.commit_count).to eq(original_commit_count)
    end
159 160 161 162 163 164 165 166 167
  end

  context 'with Wiki' do
    let(:project_path) { 'a-group/a-project' }
    let(:existing_group) { create(:group, path: 'a-group') }

    it_behaves_like 'importing a repository'

    it 'creates the Wiki git repo in disk' do
168 169
      create_bare_repository("#{project_path}.git")
      create_bare_repository("#{project_path}.wiki.git")
170

J
James Lopez 已提交
171
      expect(Projects::CreateService).to receive(:new).with(admin, hash_including(skip_wiki: true,
172
                                                                                  import_type: 'bare_repository')).and_call_original
173

174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
      importer.create_project_if_needed

      project = Project.find_by_full_path(project_path)

      expect(File).to exist(File.join(project.repository_storage_path, project.disk_path + '.wiki.git'))
    end
  end

  context 'when subgroups are not available' do
    let(:project_path) { 'a-group/a-sub-group/a-project' }

    before do
      expect(Group).to receive(:supports_nested_groups?) { false }
    end

    describe '#create_project_if_needed' do
      it 'raises an error' do
        expect { importer.create_project_if_needed }.to raise_error('Nested groups are not supported on MySQL')
      end
    end
  end
195 196 197 198 199

  def create_bare_repository(project_path)
    repo_path = File.join(base_dir, project_path)
    Gitlab::Git::Repository.create(repo_path, bare: true)
  end
200
end