diff options
Diffstat (limited to 'spec/migrations')
25 files changed, 599 insertions, 157 deletions
diff --git a/spec/migrations/20210413132500_reschedule_artifact_expiry_backfill_again_spec.rb b/spec/migrations/20210413132500_reschedule_artifact_expiry_backfill_again_spec.rb deleted file mode 100644 index e1dc7487222..00000000000 --- a/spec/migrations/20210413132500_reschedule_artifact_expiry_backfill_again_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe RescheduleArtifactExpiryBackfillAgain, :migration do - let(:migration_class) { Gitlab::BackgroundMigration::BackfillArtifactExpiryDate } - let(:migration_name) { migration_class.to_s.demodulize } - - before do - table(:namespaces).create!(id: 123, name: 'test_namespace', path: 'test_namespace') - table(:projects).create!(id: 123, name: 'sample_project', path: 'sample_project', namespace_id: 123) - end - - it 'correctly schedules background migrations' do - first_artifact = create_artifact(job_id: 0, expire_at: nil, created_at: Date.new(2020, 06, 21)) - second_artifact = create_artifact(job_id: 1, expire_at: nil, created_at: Date.new(2020, 06, 21)) - create_artifact(job_id: 2, expire_at: Date.yesterday, created_at: Date.new(2020, 06, 21)) - create_artifact(job_id: 3, expire_at: nil, created_at: Date.new(2020, 06, 23)) - - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(1) - expect(migration_name).to be_scheduled_migration_with_multiple_args(first_artifact.id, second_artifact.id) - end - end - end - - private - - def create_artifact(params) - table(:ci_builds).create!(id: params[:job_id], project_id: 123) - table(:ci_job_artifacts).create!(project_id: 123, file_type: 1, **params) - end -end diff --git a/spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb index 9addaaf2551..d1c04c5d320 100644 --- a/spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb +++ b/spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true + require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid.rb') +require_migration! def create_background_migration_jobs(ids, status, created_at) proper_status = case status diff --git a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb index 2698af6f6f5..127f4798f33 100644 --- a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb +++ b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20220124130028_dedup_runner_projects.rb') +require_migration! RSpec.describe DedupRunnerProjects, :migration, schema: 20220120085655 do let(:namespaces) { table(:namespaces) } diff --git a/spec/migrations/20220213103859_remove_integrations_type_spec.rb b/spec/migrations/20220213103859_remove_integrations_type_spec.rb new file mode 100644 index 00000000000..b1a4370700a --- /dev/null +++ b/spec/migrations/20220213103859_remove_integrations_type_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe RemoveIntegrationsType, :migration do + subject(:migration) { described_class.new } + + let(:integrations) { table(:integrations) } + let(:bg_migration) { instance_double(bg_migration_class) } + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 2) + end + + it 'performs remaining background migrations', :aggregate_failures do + # Already migrated + integrations.create!(type: 'SlackService', type_new: 'Integrations::Slack') + # update required + record1 = integrations.create!(type: 'SlackService') + record2 = integrations.create!(type: 'JiraService') + record3 = integrations.create!(type: 'SlackService') + + migrate! + + expect(record1.reload.type_new).to eq 'Integrations::Slack' + expect(record2.reload.type_new).to eq 'Integrations::Jira' + expect(record3.reload.type_new).to eq 'Integrations::Slack' + end +end diff --git a/spec/migrations/20220324165436_schedule_backfill_project_settings_spec.rb b/spec/migrations/20220324165436_schedule_backfill_project_settings_spec.rb new file mode 100644 index 00000000000..a8014e73bf0 --- /dev/null +++ b/spec/migrations/20220324165436_schedule_backfill_project_settings_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleBackfillProjectSettings do + let_it_be(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background jobs for each batch of projects' do + migrate! + + expect(migration).to( + have_scheduled_batched_migration( + table_name: :projects, + column_name: :id, + interval: described_class::INTERVAL + ) + ) + end + end +end diff --git a/spec/migrations/20220331133802_schedule_backfill_topics_title_spec.rb b/spec/migrations/20220331133802_schedule_backfill_topics_title_spec.rb new file mode 100644 index 00000000000..13e8c42269b --- /dev/null +++ b/spec/migrations/20220331133802_schedule_backfill_topics_title_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleBackfillTopicsTitle do + let(:topics) { table(:topics) } + + let!(:topic1) { topics.create!(name: 'topic1') } + let!(:topic2) { topics.create!(name: 'topic2') } + let!(:topic3) { topics.create!(name: 'topic3') } + + it 'correctly schedules background migrations', :aggregate_failures do + stub_const("#{Gitlab::Database::Migrations::BackgroundMigrationHelpers}::BATCH_SIZE", 2) + + Sidekiq::Testing.fake! do + freeze_time do + migrate! + + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, topic1.id, topic2.id) + expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, topic3.id, topic3.id) + expect(BackgroundMigrationWorker.jobs.size).to eq(2) + end + end + end +end diff --git a/spec/migrations/20220420135946_update_batched_background_migration_arguments_spec.rb b/spec/migrations/20220420135946_update_batched_background_migration_arguments_spec.rb new file mode 100644 index 00000000000..6dbee483e15 --- /dev/null +++ b/spec/migrations/20220420135946_update_batched_background_migration_arguments_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe UpdateBatchedBackgroundMigrationArguments do + let(:batched_migrations) { table(:batched_background_migrations) } + + before do + common_attributes = { + max_value: 10, + batch_size: 5, + sub_batch_size: 2, + interval: 2.minutes, + table_name: 'events', + column_name: 'id' + } + + batched_migrations.create!(common_attributes.merge(job_class_name: 'Job1', job_arguments: '[]')) + batched_migrations.create!(common_attributes.merge(job_class_name: 'Job2', job_arguments: '["some_argument"]')) + batched_migrations.create!(common_attributes.merge(job_class_name: 'Job3', job_arguments: '[]')) + end + + describe '#up' do + it 'updates batched migration arguments to have an empty jsonb array' do + expect { migrate! } + .to change { batched_migrations.where("job_arguments = '[]'").count }.from(0).to(2) + .and change { batched_migrations.where("job_arguments = '\"[]\"'").count }.from(2).to(0) + end + end + + describe '#down' do + before do + migrate! + end + + it 'reverts batched migration arguments to have the previous default' do + expect { schema_migrate_down! } + .to change { batched_migrations.where("job_arguments = '\"[]\"'").count }.from(0).to(2) + .and change { batched_migrations.where("job_arguments = '[]'").count }.from(2).to(0) + end + end +end diff --git a/spec/migrations/20220426185933_backfill_deployments_finished_at_spec.rb b/spec/migrations/20220426185933_backfill_deployments_finished_at_spec.rb new file mode 100644 index 00000000000..c79325c5077 --- /dev/null +++ b/spec/migrations/20220426185933_backfill_deployments_finished_at_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe BackfillDeploymentsFinishedAt, :migration do + let(:deployments) { table(:deployments) } + let(:namespaces) { table(:namespaces) } + + let(:namespace) { namespaces.create!(name: 'user', path: 'user') } + let(:project_namespace) { namespaces.create!(name: 'project', path: 'project', type: 'Project') } + let(:project) { table(:projects).create!(namespace_id: namespace.id, project_namespace_id: project_namespace.id) } + let(:environment) { table(:environments).create!(name: 'production', slug: 'production', project_id: project.id) } + + describe '#up' do + context 'when a deployment row does not have a value for finished_at' do + context 'and deployment succeeded' do + before do + create_deployment!(status: described_class::DEPLOYMENT_STATUS_SUCCESS, finished_at: nil) + end + + it 'copies created_at to finished_at' do + expect { migrate! } + .to change { deployments.last.finished_at }.from(nil).to(deployments.last.created_at) + .and not_change { deployments.last.created_at } + end + end + + context 'and deployment does not have status: success' do + before do + create_deployment!(status: 0, finished_at: nil) + create_deployment!(status: 1, finished_at: nil) + create_deployment!(status: 3, finished_at: nil) + create_deployment!(status: 4, finished_at: nil) + create_deployment!(status: 5, finished_at: nil) + create_deployment!(status: 6, finished_at: nil) + end + + it 'does not fill finished_at' do + expect { migrate! }.to not_change { deployments.where(finished_at: nil).count } + end + end + end + + context 'when a deployment row has value for finished_at' do + let(:finished_at) { '2018-10-30 11:12:02 UTC' } + + before do + create_deployment!(status: described_class::DEPLOYMENT_STATUS_SUCCESS, finished_at: finished_at) + end + + it 'does not affect existing value' do + expect { migrate! } + .to not_change { deployments.last.finished_at } + .and not_change { deployments.last.created_at } + end + end + end + + def create_deployment!(status:, finished_at:) + deployments.create!( + environment_id: environment.id, + project_id: project.id, + ref: 'master', + tag: false, + sha: 'x', + status: status, + iid: deployments.count + 1, + finished_at: finished_at + ) + end +end diff --git a/spec/migrations/20220502015011_clean_up_fix_merge_request_diff_commit_users_spec.rb b/spec/migrations/20220502015011_clean_up_fix_merge_request_diff_commit_users_spec.rb new file mode 100644 index 00000000000..769c0993b67 --- /dev/null +++ b/spec/migrations/20220502015011_clean_up_fix_merge_request_diff_commit_users_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! 'clean_up_fix_merge_request_diff_commit_users' + +RSpec.describe CleanUpFixMergeRequestDiffCommitUsers, :migration do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:project_namespace) { namespaces.create!(name: 'project2', path: 'project2', type: 'Project') } + let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') } + + describe '#up' do + it 'finalizes the background migration' do + expect(described_class).to be_finalize_background_migration_of('FixMergeRequestDiffCommitUsers') + + migrate! + end + + it 'processes pending background jobs' do + project = projects.create!(name: 'p1', namespace_id: namespace.id, project_namespace_id: project_namespace.id) + + Gitlab::Database::BackgroundMigrationJob.create!( + class_name: 'FixMergeRequestDiffCommitUsers', + arguments: [project.id] + ) + + migrate! + + background_migrations = Gitlab::Database::BackgroundMigrationJob + .where(class_name: 'FixMergeRequestDiffCommitUsers') + + expect(background_migrations.count).to eq(0) + end + end +end diff --git a/spec/migrations/20220502173045_reset_too_many_tags_skipped_registry_imports_spec.rb b/spec/migrations/20220502173045_reset_too_many_tags_skipped_registry_imports_spec.rb new file mode 100644 index 00000000000..cc4041fe151 --- /dev/null +++ b/spec/migrations/20220502173045_reset_too_many_tags_skipped_registry_imports_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ResetTooManyTagsSkippedRegistryImports, :aggregate_failures do + let(:migration) { described_class::MIGRATION } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:container_repositories) { table(:container_repositories) } + + let!(:namespace) { namespaces.create!(id: 1, name: 'namespace', path: 'namespace') } + let!(:project) { projects.create!(id: 1, name: 'project', path: 'project', project_namespace_id: 1, namespace_id: 1) } + + let!(:container_repository1) do + container_repositories.create!( + name: 'container_repository1', + project_id: 1, + migration_state: 'import_skipped', + migration_skipped_reason: 2 + ) + end + + let!(:container_repository2) do + container_repositories.create!( + name: 'container_repository2', + project_id: 1, + migration_state: 'import_skipped', + migration_skipped_reason: 2 + ) + end + + let!(:container_repository3) do + container_repositories.create!( + name: 'container_repository3', + project_id: 1, + migration_state: 'import_skipped', + migration_skipped_reason: 2 + ) + end + + # this should not qualify for the migration + let!(:container_repository4) do + container_repositories.create!( + name: 'container_repository4', + project_id: 1, + migration_state: 'default' + ) + end + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 2) + end + + it 'schedules jobs to reset skipped registry imports' do + Sidekiq::Testing.fake! do + freeze_time do + migrate! + + expect(migration).to be_scheduled_delayed_migration( + 2.minutes, container_repository1.id, container_repository2.id) + expect(migration).to be_scheduled_delayed_migration( + 4.minutes, container_repository3.id, container_repository3.id) + expect(BackgroundMigrationWorker.jobs.size).to eq(2) + end + end + end +end diff --git a/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb b/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb new file mode 100644 index 00000000000..8bc336a6b26 --- /dev/null +++ b/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe FixAutomaticIterationsCadencesStartDate, + quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/362446' do + let(:migration) { described_class.new } + let(:namespaces) { table(:namespaces) } + let(:sprints) { table(:sprints) } + let(:iterations_cadences) { table(:iterations_cadences) } + + let!(:group1) { namespaces.create!(name: 'abc', path: 'abc') } + let!(:group2) { namespaces.create!(name: 'def', path: 'def') } + + let(:jan2022) { Date.new(2022, 1, 1) } + let(:feb2022) { Date.new(2022, 2, 1) } + let(:may2022) { Date.new(2022, 5, 1) } + let(:dec2022) { Date.new(2022, 12, 1) } + + let!(:cadence1) { iterations_cadences.create!(start_date: jan2022, title: "ic 1", group_id: group1.id) } + let!(:cadence2) { iterations_cadences.create!(start_date: may2022, group_id: group1.id, title: "ic 2") } + let!(:cadence3) do + iterations_cadences.create!(start_date: jan2022, automatic: false, group_id: group2.id, title: "ic 3 (invalid)") + end + + let!(:cadence4) { iterations_cadences.create!(start_date: jan2022, group_id: group2.id, title: "ic 4 (invalid)") } + + before do + sprints.create!(id: 2, start_date: jan2022, due_date: jan2022 + 1.week, iterations_cadence_id: cadence1.id, + group_id: group1.id, iid: 1) + sprints.create!(id: 1, start_date: dec2022, due_date: dec2022 + 1.week, iterations_cadence_id: cadence1.id, + group_id: group1.id, iid: 2) + + sprints.create!(id: 4, start_date: feb2022, due_date: feb2022 + 1.week, iterations_cadence_id: cadence3.id, + group_id: group2.id, iid: 1) + sprints.create!(id: 3, start_date: may2022, due_date: may2022 + 1.week, iterations_cadence_id: cadence3.id, + group_id: group2.id, iid: 2) + + sprints.create!(id: 5, start_date: may2022, due_date: may2022 + 1.week, iterations_cadence_id: cadence4.id, + group_id: group2.id, iid: 4) + sprints.create!(id: 6, start_date: feb2022, due_date: feb2022 + 1.week, iterations_cadence_id: cadence4.id, + group_id: group2.id, iid: 3) + end + + describe '#up' do + it "updates automatic iterations_cadence records to use start dates of their earliest sprint records" do + migrate! + + # This cadence has a valid start date. Its start date should be left as it is + expect(cadence1.reload.start_date).to eq jan2022 + + # This cadence doesn't have an iteration. Its start date should be left as it is. + expect(cadence2.reload.start_date).to eq may2022 + + # This cadence has an invalid start date but it isn't automatic. Its start date should be left as it is. + expect(cadence3.reload.start_date).to eq jan2022 + + # This cadence has an invalid start date. Its start date should be fixed. + expect(cadence4.reload.start_date).to eq feb2022 + end + end +end diff --git a/spec/migrations/20220505174658_update_index_on_alerts_to_exclude_null_fingerprints_spec.rb b/spec/migrations/20220505174658_update_index_on_alerts_to_exclude_null_fingerprints_spec.rb new file mode 100644 index 00000000000..0c4d0e86789 --- /dev/null +++ b/spec/migrations/20220505174658_update_index_on_alerts_to_exclude_null_fingerprints_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe UpdateIndexOnAlertsToExcludeNullFingerprints do + let(:alerts) { 'alert_management_alerts'} + let(:old_index) { described_class::OLD_INDEX_NAME } + let(:new_index) { described_class::NEW_INDEX_NAME } + + it 'correctly migrates up and down' do + reversible_migration do |migration| + migration.before -> { + expect(subject.index_exists_by_name?(alerts, old_index)).to be_truthy + expect(subject.index_exists_by_name?(alerts, new_index)).to be_falsey + } + + migration.after -> { + expect(subject.index_exists_by_name?(alerts, old_index)).to be_falsey + expect(subject.index_exists_by_name?(alerts, new_index)).to be_truthy + } + end + end +end diff --git a/spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb b/spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb new file mode 100644 index 00000000000..63fff279acc --- /dev/null +++ b/spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RescheduleExpireOAuthTokens do + let_it_be(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background jobs for each batch of oauth tokens' do + migrate! + + expect(migration).to( + have_scheduled_batched_migration( + table_name: :oauth_access_tokens, + column_name: :id, + interval: described_class::INTERVAL + ) + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb b/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb index ce0ab4223e8..74429e498df 100644 --- a/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb +++ b/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -require Rails.root.join('db', 'migrate', '20210629031900_associate_existing_dast_builds_with_variables.rb') +require_migration! RSpec.describe AssociateExistingDastBuildsWithVariables do subject(:migration) { described_class.new } diff --git a/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb b/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb index 1a64de8d0db..16a08ec47c4 100644 --- a/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb +++ b/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' require_migration! -# require Rails.root.join('db', 'post_migrate', '20210825193652_backfill_candence_id_for_boards_scoped_to_iteration.rb') RSpec.describe BackfillCadenceIdForBoardsScopedToIteration, :migration do let(:projects) { table(:projects) } diff --git a/spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb b/spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb new file mode 100644 index 00000000000..28578a3d79a --- /dev/null +++ b/spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe BackfillIntegrationsEnableSslVerification do + let_it_be(:migration) { described_class::MIGRATION } + let_it_be(:integrations) { described_class::Integration } + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 2) + + integrations.create!(id: 1, type_new: 'Integrations::DroneCi') + integrations.create!(id: 2, type_new: 'Integrations::DroneCi', properties: {}) + integrations.create!(id: 3, type_new: 'Integrations::Bamboo', properties: {}) + integrations.create!(id: 4, type_new: 'Integrations::Teamcity', properties: {}) + integrations.create!(id: 5, type_new: 'Integrations::DroneCi', properties: {}) + integrations.create!(id: 6, type_new: 'Integrations::Teamcity', properties: {}) + end + + describe '#up' do + it 'schedules background jobs for each batch of integrations', :freeze_time do + Sidekiq::Testing.fake! do + migrate! + + expect(BackgroundMigrationWorker.jobs.size).to eq(2) + expect(migration).to be_scheduled_delayed_migration(5.minutes, 2, 4) + expect(migration).to be_scheduled_delayed_migration(10.minutes, 5, 6) + end + end + end +end diff --git a/spec/migrations/backfill_work_item_type_id_on_issues_spec.rb b/spec/migrations/backfill_work_item_type_id_on_issues_spec.rb deleted file mode 100644 index 6798b0cc7e8..00000000000 --- a/spec/migrations/backfill_work_item_type_id_on_issues_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe BackfillWorkItemTypeIdOnIssues, :migration do - let_it_be(:migration) { described_class::MIGRATION } - let_it_be(:interval) { 2.minutes } - let_it_be(:issue_type_enum) { { issue: 0, incident: 1, test_case: 2, requirement: 3, task: 4 } } - let_it_be(:base_work_item_type_ids) do - table(:work_item_types).where(namespace_id: nil).order(:base_type).each_with_object({}) do |type, hash| - hash[type.base_type] = type.id - end - end - - describe '#up' do - it 'correctly schedules background migrations' do - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - scheduled_migrations = Gitlab::Database::BackgroundMigration::BatchedMigration.where(job_class_name: migration) - work_item_types = table(:work_item_types).where(namespace_id: nil) - - expect(scheduled_migrations.count).to eq(work_item_types.count) - - [:issue, :incident, :test_case, :requirement, :task].each do |issue_type| - expect(migration).to have_scheduled_batched_migration( - table_name: :issues, - column_name: :id, - job_arguments: [issue_type_enum[issue_type], base_work_item_type_ids[issue_type_enum[issue_type]]], - interval: interval, - batch_size: described_class::BATCH_SIZE, - max_batch_size: described_class::MAX_BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE, - batch_class_name: described_class::BATCH_CLASS_NAME - ) - end - end - end - end - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/cleanup_after_fixing_regression_with_new_users_emails_spec.rb b/spec/migrations/cleanup_after_fixing_regression_with_new_users_emails_spec.rb new file mode 100644 index 00000000000..043bb091df3 --- /dev/null +++ b/spec/migrations/cleanup_after_fixing_regression_with_new_users_emails_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe CleanupAfterFixingRegressionWithNewUsersEmails, :sidekiq do + let(:migration) { described_class.new } + let(:users) { table(:users) } + let(:emails) { table(:emails) } + + # rubocop: disable Layout/LineLength + let!(:user_1) { users.create!(name: 'confirmed-user-1', email: 'confirmed-1@example.com', confirmed_at: 3.days.ago, projects_limit: 100) } + let!(:user_2) { users.create!(name: 'confirmed-user-2', email: 'confirmed-2@example.com', confirmed_at: 1.day.ago, projects_limit: 100) } + let!(:user_3) { users.create!(name: 'confirmed-user-3', email: 'confirmed-3@example.com', confirmed_at: 1.day.ago, projects_limit: 100) } + let!(:user_4) { users.create!(name: 'unconfirmed-user', email: 'unconfirmed@example.com', confirmed_at: nil, projects_limit: 100) } + + let!(:email_1) { emails.create!(email: 'confirmed-1@example.com', user_id: user_1.id, confirmed_at: 1.day.ago) } + let!(:email_2) { emails.create!(email: 'other_2@example.com', user_id: user_2.id, confirmed_at: 1.day.ago) } + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 2) + end + + it 'adds primary email to emails for confirmed users that do not have their primary email in emails table', :aggregate_failures do + original_email_1_confirmed_at = email_1.reload.confirmed_at + + expect { migration.up }.to change { emails.count }.by(2) + + expect(emails.find_by(user_id: user_2.id, email: 'confirmed-2@example.com').confirmed_at).to eq(user_2.reload.confirmed_at) + expect(emails.find_by(user_id: user_3.id, email: 'confirmed-3@example.com').confirmed_at).to eq(user_3.reload.confirmed_at) + expect(email_1.reload.confirmed_at).to eq(original_email_1_confirmed_at) + + expect(emails.exists?(user_id: user_4.id)).to be(false) + end + # rubocop: enable Layout/LineLength + + it 'continues in case of errors with one email' do + allow(Email).to receive(:create) { raise 'boom!' } + + expect { migration.up }.not_to raise_error + end +end diff --git a/spec/migrations/finalize_project_namespaces_backfill_spec.rb b/spec/migrations/finalize_project_namespaces_backfill_spec.rb index 3d0b0ec13fe..56f3b0f6ba5 100644 --- a/spec/migrations/finalize_project_namespaces_backfill_spec.rb +++ b/spec/migrations/finalize_project_namespaces_backfill_spec.rb @@ -9,9 +9,11 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do let_it_be(:migration) { described_class::MIGRATION } describe '#up' do - shared_examples 'raises migration not finished exception' do - it 'raises exception' do - expect { migrate! }.to raise_error(/Expected batched background migration for the given configuration to be marked as 'finished'/) + shared_examples 'finalizes the migration' do + it 'finalizes the migration' do + allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner| + expect(runner).to receive(:finalize).with('"ProjectNamespaces::BackfillProjectNamespaces"', :projects, :id, [nil, "up"]) + end end end @@ -42,7 +44,7 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do context 'when project namespace backfilling migration finished successfully' do it 'does not raise exception' do - expect { migrate! }.not_to raise_error(/Expected batched background migration for the given configuration to be marked as 'finished'/) + expect { migrate! }.not_to raise_error end end @@ -61,7 +63,7 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do project_namespace_backfill.update!(status: status) end - it_behaves_like 'raises migration not finished exception' + it_behaves_like 'finalizes the migration' end end end diff --git a/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb b/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb index 4b8d3641247..1b6cb6a86a0 100644 --- a/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb +++ b/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -require Rails.root.join('db', 'migrate', '20210526190553_insert_ci_daily_pipeline_schedule_triggers_plan_limits.rb') +require_migration! RSpec.describe InsertCiDailyPipelineScheduleTriggersPlanLimits do let_it_be(:plans) { table(:plans) } diff --git a/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb b/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb index e838476a650..2108adcc973 100644 --- a/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb +++ b/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20210610102413_migrate_protected_attribute_to_pending_builds.rb') +require_migration! RSpec.describe MigrateProtectedAttributeToPendingBuilds do let(:namespaces) { table(:namespaces) } diff --git a/spec/migrations/replace_work_item_type_backfill_next_batch_strategy_spec.rb b/spec/migrations/replace_work_item_type_backfill_next_batch_strategy_spec.rb deleted file mode 100644 index 5e22fc06973..00000000000 --- a/spec/migrations/replace_work_item_type_backfill_next_batch_strategy_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ReplaceWorkItemTypeBackfillNextBatchStrategy, :migration do - describe '#up' do - it 'sets the new strategy for existing migrations' do - migrations = create_migrations(described_class::OLD_STRATEGY_CLASS, 2) - - expect do - migrate! - - migrations.each(&:reload) - end.to change { migrations.pluck(:batch_class_name).uniq }.from([described_class::OLD_STRATEGY_CLASS]) - .to([described_class::NEW_STRATEGY_CLASS]) - end - end - - describe '#down' do - it 'sets the old strategy for existing migrations' do - migrations = create_migrations(described_class::NEW_STRATEGY_CLASS, 2) - - expect do - migrate! - schema_migrate_down! - - migrations.each(&:reload) - end.to change { migrations.pluck(:batch_class_name).uniq }.from([described_class::NEW_STRATEGY_CLASS]) - .to([described_class::OLD_STRATEGY_CLASS]) - end - end - - def create_migrations(batch_class_name, count) - Array.new(2) { |index| create_background_migration(batch_class_name, [index]) } - end - - def create_background_migration(batch_class_name, job_arguments) - migrations_table = table(:batched_background_migrations) - - migrations_table.create!( - batch_class_name: batch_class_name, - job_class_name: described_class::JOB_CLASS_NAME, - max_value: 10, - batch_size: 5, - sub_batch_size: 1, - interval: 2.minutes, - table_name: :issues, - column_name: :id, - total_tuple_count: 10_000, - pause_ms: 100, - job_arguments: job_arguments - ) - end -end diff --git a/spec/migrations/retry_backfill_traversal_ids_spec.rb b/spec/migrations/retry_backfill_traversal_ids_spec.rb index e5ebd4228ca..910be9f2c69 100644 --- a/spec/migrations/retry_backfill_traversal_ids_spec.rb +++ b/spec/migrations/retry_backfill_traversal_ids_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20210604070207_retry_backfill_traversal_ids.rb') +require_migration! RSpec.describe RetryBackfillTraversalIds, :migration do include ReloadHelpers diff --git a/spec/migrations/schedule_backfill_draft_status_on_merge_requests_corrected_regex_spec.rb b/spec/migrations/schedule_backfill_draft_status_on_merge_requests_corrected_regex_spec.rb new file mode 100644 index 00000000000..9d7651d01ed --- /dev/null +++ b/spec/migrations/schedule_backfill_draft_status_on_merge_requests_corrected_regex_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe ScheduleBackfillDraftStatusOnMergeRequestsCorrectedRegex, :sidekiq do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:merge_requests) { table(:merge_requests) } + + let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') } + let(:proj_namespace) { namespaces.create!(name: 'proj1', path: 'proj1', type: 'Project', parent_id: namespace.id) } + let!(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: proj_namespace.id) } + + let(:draft_prefixes) { ["[Draft]", "(Draft)", "Draft:", "Draft", "[WIP]", "WIP:", "WIP"] } + + def create_merge_request(params) + common_params = { + target_project_id: project.id, + target_branch: 'feature1', + source_branch: 'master' + } + + merge_requests.create!(common_params.merge(params)) + end + + before do + draft_prefixes.each do |prefix| + (1..4).each do |n| + create_merge_request( + title: "#{prefix} This is a title", + draft: false, + state_id: n + ) + + create_merge_request( + title: "This is a title with the #{prefix} in a weird spot", + draft: false, + state_id: n + ) + end + end + + stub_const("#{described_class}::BATCH_SIZE", 1) + end + + it 'schedules BackfillDraftStatusOnMergeRequests background jobs' do + Sidekiq::Testing.fake! do + draft_mrs = MergeRequest.where(state_id: 1) + .where(draft: false) + .where("title ~* ?", described_class::CORRECTED_REGEXP_STR) + + first_mr_id = draft_mrs.first.id + second_mr_id = draft_mrs.second.id + + freeze_time do + migrate! + + expect(BackgroundMigrationWorker.jobs.size).to eq(7) + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(2.minutes, first_mr_id, first_mr_id) + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(4.minutes, second_mr_id, second_mr_id) + end + end + end +end diff --git a/spec/migrations/toggle_vsa_aggregations_enable_spec.rb b/spec/migrations/toggle_vsa_aggregations_enable_spec.rb new file mode 100644 index 00000000000..a6850d493b7 --- /dev/null +++ b/spec/migrations/toggle_vsa_aggregations_enable_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ToggleVsaAggregationsEnable, :migration do + let(:aggregations) { table(:analytics_cycle_analytics_aggregations) } + let(:groups) { table(:namespaces) } + + let!(:group1) { groups.create!(name: 'aaa', path: 'aaa') } + let!(:group2) { groups.create!(name: 'aaa', path: 'aaa') } + let!(:group3) { groups.create!(name: 'aaa', path: 'aaa') } + + let!(:aggregation1) { aggregations.create!(group_id: group1.id, enabled: false) } + let!(:aggregation2) { aggregations.create!(group_id: group2.id, enabled: true) } + let!(:aggregation3) { aggregations.create!(group_id: group3.id, enabled: false) } + + it 'makes all aggregations enabled' do + migrate! + + expect(aggregation1.reload).to be_enabled + expect(aggregation2.reload).to be_enabled + expect(aggregation3.reload).to be_enabled + end +end |