diff options
Diffstat (limited to 'spec/lib/gitlab/background_migration/batching_strategies')
3 files changed, 161 insertions, 5 deletions
diff --git a/spec/lib/gitlab/background_migration/batching_strategies/backfill_issue_work_item_type_batching_strategy_spec.rb b/spec/lib/gitlab/background_migration/batching_strategies/backfill_issue_work_item_type_batching_strategy_spec.rb new file mode 100644 index 00000000000..3cba99bfe51 --- /dev/null +++ b/spec/lib/gitlab/background_migration/batching_strategies/backfill_issue_work_item_type_batching_strategy_spec.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::BackfillIssueWorkItemTypeBatchingStrategy, '#next_batch', schema: 20220326161803 do # rubocop:disable Layout/LineLength + # let! can't be used in migration specs because all tables but `work_item_types` are deleted after each spec + let!(:issue_type_enum) { { issue: 0, incident: 1, test_case: 2, requirement: 3, task: 4 } } + let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') } + let!(:project) { table(:projects).create!(namespace_id: namespace.id) } + let!(:issues_table) { table(:issues) } + let!(:task_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_type_enum[:task]) } + + let!(:issue1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:issue]) } + let!(:task1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:task]) } + let!(:issue2) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:issue]) } + let!(:issue3) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:issue]) } + let!(:task2) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:task]) } + let!(:incident1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:incident]) } + # test_case is EE only, but enum values exist on the FOSS model + let!(:test_case1) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:test_case]) } + + let!(:task3) do + issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:task], work_item_type_id: task_type.id) + end + + let!(:task4) { issues_table.create!(project_id: project.id, issue_type: issue_type_enum[:task]) } + + let!(:batching_strategy) { described_class.new(connection: ActiveRecord::Base.connection) } + + context 'when issue_type is issue' do + let(:job_arguments) { [issue_type_enum[:issue], 'irrelevant_work_item_id'] } + + context 'when starting on the first batch' do + it 'returns the bounds of the next batch' do + batch_bounds = next_batch(issue1.id, 2) + + expect(batch_bounds).to match_array([issue1.id, issue2.id]) + end + end + + context 'when additional batches remain' do + it 'returns the bounds of the next batch' do + batch_bounds = next_batch(issue2.id, 2) + + expect(batch_bounds).to match_array([issue2.id, issue3.id]) + end + end + + context 'when on the final batch' do + it 'returns the bounds of the next batch' do + batch_bounds = next_batch(issue3.id, 2) + + expect(batch_bounds).to match_array([issue3.id, issue3.id]) + end + end + + context 'when no additional batches remain' do + it 'returns nil' do + batch_bounds = next_batch(issue3.id + 1, 1) + + expect(batch_bounds).to be_nil + end + end + end + + context 'when issue_type is incident' do + let(:job_arguments) { [issue_type_enum[:incident], 'irrelevant_work_item_id'] } + + context 'when starting on the first batch' do + it 'returns the bounds of the next batch with only one element' do + batch_bounds = next_batch(incident1.id, 2) + + expect(batch_bounds).to match_array([incident1.id, incident1.id]) + end + end + end + + context 'when issue_type is requirement and there are no matching records' do + let(:job_arguments) { [issue_type_enum[:requirement], 'irrelevant_work_item_id'] } + + context 'when starting on the first batch' do + it 'returns nil' do + batch_bounds = next_batch(1, 2) + + expect(batch_bounds).to be_nil + end + end + end + + context 'when issue_type is task' do + let(:job_arguments) { [issue_type_enum[:task], 'irrelevant_work_item_id'] } + + context 'when starting on the first batch' do + it 'returns the bounds of the next batch' do + batch_bounds = next_batch(task1.id, 2) + + expect(batch_bounds).to match_array([task1.id, task2.id]) + end + end + + context 'when additional batches remain' do + it 'returns the bounds of the next batch, does not skip records where FK is already set' do + batch_bounds = next_batch(task2.id, 2) + + expect(batch_bounds).to match_array([task2.id, task3.id]) + end + end + + context 'when on the final batch' do + it 'returns the bounds of the next batch' do + batch_bounds = next_batch(task4.id, 2) + + expect(batch_bounds).to match_array([task4.id, task4.id]) + end + end + + context 'when no additional batches remain' do + it 'returns nil' do + batch_bounds = next_batch(task4.id + 1, 1) + + expect(batch_bounds).to be_nil + end + end + end + + def next_batch(min_value, batch_size) + batching_strategy.next_batch( + :issues, + :id, + batch_min_value: min_value, + batch_size: batch_size, + job_arguments: job_arguments + ) + end +end diff --git a/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb b/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb index b01dd5b410e..dc0935efa94 100644 --- a/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb +++ b/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::BackfillProjectNamespacePerGroupBatchingStrategy, '#next_batch' do +RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::BackfillProjectNamespacePerGroupBatchingStrategy, '#next_batch', :migration, schema: 20220326161803 do let!(:namespaces) { table(:namespaces) } let!(:projects) { table(:projects) } let!(:background_migrations) { table(:batched_background_migrations) } diff --git a/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb b/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb index 4e0ebd4b692..521e2067744 100644 --- a/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb +++ b/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb @@ -15,7 +15,7 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchi context 'when starting on the first batch' do it 'returns the bounds of the next batch' do - batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace1.id, batch_size: 3, job_arguments: nil) + batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace1.id, batch_size: 3, job_arguments: []) expect(batch_bounds).to eq([namespace1.id, namespace3.id]) end @@ -23,7 +23,7 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchi context 'when additional batches remain' do it 'returns the bounds of the next batch' do - batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace2.id, batch_size: 3, job_arguments: nil) + batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace2.id, batch_size: 3, job_arguments: []) expect(batch_bounds).to eq([namespace2.id, namespace4.id]) end @@ -31,7 +31,7 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchi context 'when on the final batch' do it 'returns the bounds of the next batch' do - batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace4.id, batch_size: 3, job_arguments: nil) + batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace4.id, batch_size: 3, job_arguments: []) expect(batch_bounds).to eq([namespace4.id, namespace4.id]) end @@ -39,9 +39,30 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchi context 'when no additional batches remain' do it 'returns nil' do - batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace4.id + 1, batch_size: 1, job_arguments: nil) + batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace4.id + 1, batch_size: 1, job_arguments: []) expect(batch_bounds).to be_nil end end + + context 'additional filters' do + let(:strategy_with_filters) do + Class.new(described_class) do + def apply_additional_filters(relation, job_arguments:) + min_id = job_arguments.first + + relation.where.not(type: 'Project').where('id >= ?', min_id) + end + end + end + + let(:batching_strategy) { strategy_with_filters.new(connection: ActiveRecord::Base.connection) } + let!(:namespace5) { namespaces.create!(name: 'batchtest5', path: 'batch-test5', type: 'Project') } + + it 'applies additional filters' do + batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace4.id, batch_size: 3, job_arguments: [1]) + + expect(batch_bounds).to eq([namespace4.id, namespace4.id]) + end + end end |