164 lines
4.9 KiB
Ruby
164 lines
4.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe Gitlab::BitbucketImport::ParallelScheduling, feature_category: :importers do
|
|
let_it_be(:project) do
|
|
create(:project, :import_started, import_source: 'foo/bar',
|
|
import_data_attributes: {
|
|
data: {
|
|
'project_key' => 'key',
|
|
'repo_slug' => 'slug'
|
|
},
|
|
credentials: { 'base_uri' => 'http://bitbucket.org/', 'user' => 'bitbucket', 'password' => 'password' }
|
|
}
|
|
)
|
|
end
|
|
|
|
let(:importer_class) do
|
|
Class.new do
|
|
include Gitlab::BitbucketImport::ParallelScheduling
|
|
|
|
def collection_method
|
|
:issues
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#calculate_job_delay' do
|
|
let(:importer) { importer_class.new(project) }
|
|
|
|
before do
|
|
stub_application_setting(concurrent_bitbucket_import_jobs_limit: 2)
|
|
end
|
|
|
|
it 'returns an incremental delay', :freeze_time do
|
|
expect(importer.send(:calculate_job_delay, 1)).to eq(0.5.minutes + 1.second)
|
|
expect(importer.send(:calculate_job_delay, 100)).to eq(50.minutes + 1.second)
|
|
end
|
|
|
|
it 'deducts the runtime from the delay', :freeze_time do
|
|
allow(importer).to receive(:job_started_at).and_return(1.second.ago)
|
|
|
|
expect(importer.send(:calculate_job_delay, 1)).to eq(0.5.minutes)
|
|
expect(importer.send(:calculate_job_delay, 100)).to eq(50.minutes)
|
|
end
|
|
end
|
|
|
|
describe '#each_object_to_import' do
|
|
let_it_be(:opened_issue) { Bitbucket::Representation::Issue.new({ 'id' => 1, 'state' => 'OPENED' }) }
|
|
let_it_be(:object) { opened_issue.to_hash }
|
|
|
|
let(:importer) { importer_class.new(project) }
|
|
|
|
context 'without representation_type' do
|
|
it 'raises NotImplementedError' do
|
|
expect { importer_class.new(project).each_object_to_import }.to raise_error(NotImplementedError)
|
|
end
|
|
end
|
|
|
|
context 'with representation_type' do
|
|
before do
|
|
allow(importer)
|
|
.to receive(:representation_type)
|
|
.and_return(:issue)
|
|
end
|
|
|
|
it 'yields every object to import' do
|
|
page = instance_double('Bitbucket::Page', attrs: [], items: [opened_issue])
|
|
allow(page).to receive(:next?).and_return(true)
|
|
allow(page).to receive(:next).and_return('https://example.com/next')
|
|
|
|
allow_next_instance_of(Bitbucket::Client) do |client|
|
|
expect(client)
|
|
.to receive(:each_page)
|
|
.with(:issues, :issue, 'foo/bar', { next_url: nil })
|
|
.and_yield(page)
|
|
end
|
|
|
|
expect(importer.page_keyset)
|
|
.to receive(:set)
|
|
.with('https://example.com/next')
|
|
.and_return(true)
|
|
|
|
expect(importer)
|
|
.to receive(:already_enqueued?)
|
|
.with(object)
|
|
.and_return(false)
|
|
|
|
expect(importer)
|
|
.to receive(:mark_as_enqueued)
|
|
.with(object)
|
|
|
|
expect { |b| importer.each_object_to_import(&b) }
|
|
.to yield_with_args(object)
|
|
end
|
|
|
|
it 'resumes from the last page' do
|
|
page = instance_double('Bitbucket::Page', attrs: [], items: [opened_issue])
|
|
allow(page).to receive(:next?).and_return(true)
|
|
allow(page).to receive(:next).and_return('https://example.com/next2')
|
|
|
|
expect(importer.page_keyset)
|
|
.to receive(:current)
|
|
.and_return('https://example.com/next')
|
|
|
|
allow_next_instance_of(Bitbucket::Client) do |client|
|
|
expect(client)
|
|
.to receive(:each_page)
|
|
.with(:issues, :issue, 'foo/bar', {
|
|
next_url: 'https://example.com/next'
|
|
})
|
|
.and_yield(page)
|
|
end
|
|
|
|
expect(importer.page_keyset)
|
|
.to receive(:set)
|
|
.with('https://example.com/next2')
|
|
.and_return(true)
|
|
|
|
expect(importer)
|
|
.to receive(:already_enqueued?)
|
|
.with(object)
|
|
.and_return(false)
|
|
|
|
expect(importer)
|
|
.to receive(:mark_as_enqueued)
|
|
.with(object)
|
|
|
|
expect { |b| importer.each_object_to_import(&b) }
|
|
.to yield_with_args(object)
|
|
end
|
|
|
|
it 'does not yield the object if it was already imported' do
|
|
page = instance_double('Bitbucket::Page', attrs: [], items: [opened_issue])
|
|
allow(page).to receive(:next?).and_return(true)
|
|
allow(page).to receive(:next).and_return('https://example.com/next')
|
|
|
|
allow_next_instance_of(Bitbucket::Client) do |client|
|
|
expect(client)
|
|
.to receive(:each_page)
|
|
.with(:issues, :issue, 'foo/bar', { next_url: nil })
|
|
.and_yield(page)
|
|
end
|
|
|
|
expect(importer.page_keyset)
|
|
.to receive(:set)
|
|
.with('https://example.com/next')
|
|
.and_return(true)
|
|
|
|
expect(importer)
|
|
.to receive(:already_enqueued?)
|
|
.with(object)
|
|
.and_return(true)
|
|
|
|
expect(importer)
|
|
.not_to receive(:mark_as_enqueued)
|
|
|
|
expect { |b| importer.each_object_to_import(&b) }
|
|
.not_to yield_control
|
|
end
|
|
end
|
|
end
|
|
end
|