gitlab-org--gitlab-foss/spec/lib/backup/repository_spec.rb
Zeger-Jan van de Weg 89a407dc3b
Restore Object Pools when restoring an object pool
Pool repositories are persisted in the database, and when the DB is
restored, the data need to be restored on disk. This is done by
resetting the state machine and rescheduling the object pool creation.

This is not an exact replica of the state like at the time of the
creation of the backup. However, the data is consistent again.

Dumping isn't required as internally GitLab uses git bundles which
bundle all refs and include all objects in the bundle that they require,
reduplicating as more repositories get backed up. This does require more
data to be stored.

Fixes https://gitlab.com/gitlab-org/gitaly/issues/1355
2018-12-13 09:00:03 +01:00

134 lines
3.6 KiB
Ruby

require 'spec_helper'
describe Backup::Repository do
let(:progress) { StringIO.new }
let!(:project) { create(:project, :wiki_repo) }
subject { described_class.new(progress) }
before do
allow(progress).to receive(:puts)
allow(progress).to receive(:print)
allow(FileUtils).to receive(:mkdir_p).and_return(true)
allow(FileUtils).to receive(:mv).and_return(true)
allow_any_instance_of(described_class).to receive(:progress).and_return(progress)
end
describe '#dump' do
describe 'repo failure' do
before do
allow(Gitlab::Popen).to receive(:popen).and_return(['normal output', 0])
end
it 'does not raise error' do
expect { subject.dump }.not_to raise_error
end
end
end
describe '#restore' do
let(:timestamp) { Time.utc(2017, 3, 22) }
let(:temp_dirs) do
Gitlab.config.repositories.storages.map do |name, storage|
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
File.join(storage.legacy_disk_path, '..', 'repositories.old.' + timestamp.to_i.to_s)
end
end
end
around do |example|
Timecop.freeze(timestamp) { example.run }
end
after do
temp_dirs.each { |path| FileUtils.rm_rf(path) }
end
describe 'command failure' do
before do
allow_any_instance_of(Gitlab::Shell).to receive(:create_repository).and_return(false)
end
context 'hashed storage' do
it 'shows the appropriate error' do
subject.restore
expect(progress).to have_received(:puts).with("[Failed] restoring #{project.full_path} repository")
end
end
context 'legacy storage' do
let!(:project) { create(:project, :legacy_storage) }
it 'shows the appropriate error' do
subject.restore
expect(progress).to have_received(:puts).with("[Failed] restoring #{project.full_path} repository")
end
end
end
context 'restoring object pools' do
it 'schedules restoring of the pool' do
pool_repository = create(:pool_repository, :failed)
pool_repository.delete_object_pool
subject.restore
pool_repository.reload
expect(pool_repository).not_to be_failed
expect(pool_repository.object_pool.exists?).to be(true)
end
end
end
describe '#prepare_directories', :seed_helper do
before do
allow(FileUtils).to receive(:mkdir_p).and_call_original
allow(FileUtils).to receive(:mv).and_call_original
end
after(:all) do
ensure_seeds
end
it' removes all repositories' do
# Sanity check: there should be something for us to delete
expect(list_repositories).to include(File.join(SEED_STORAGE_PATH, TEST_REPO_PATH))
subject.prepare_directories
expect(list_repositories).to be_empty
end
def list_repositories
Dir[File.join(SEED_STORAGE_PATH, '*.git')]
end
end
describe '#empty_repo?' do
context 'for a wiki' do
let(:wiki) { create(:project_wiki) }
it 'invalidates the emptiness cache' do
expect(wiki.repository).to receive(:expire_emptiness_caches).once
subject.send(:empty_repo?, wiki)
end
context 'wiki repo has content' do
let!(:wiki_page) { create(:wiki_page, wiki: wiki) }
it 'returns true, regardless of bad cache value' do
expect(subject.send(:empty_repo?, wiki)).to be(false)
end
end
context 'wiki repo does not have content' do
it 'returns true, regardless of bad cache value' do
expect(subject.send(:empty_repo?, wiki)).to be_truthy
end
end
end
end
end