Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 14:10:13 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 14:10:13 +0300
commit0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch)
tree7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /spec/migrations
parent72123183a20411a36d607d70b12d57c484394c8e (diff)
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20220416054011_schedule_backfill_project_member_namespace_id_spec.rb29
-rw-r--r--spec/migrations/20220502015011_clean_up_fix_merge_request_diff_commit_users_spec.rb16
-rw-r--r--spec/migrations/20220503035221_add_gitlab_schema_to_batched_background_migrations_spec.rb34
-rw-r--r--spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb3
-rw-r--r--spec/migrations/20220512190659_remove_web_hooks_web_hook_logs_web_hook_id_fk_spec.rb33
-rw-r--r--spec/migrations/20220520040416_schedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb63
-rw-r--r--spec/migrations/20220523171107_drop_deploy_tokens_token_column_spec.rb22
-rw-r--r--spec/migrations/20220524074947_finalize_backfill_null_note_discussion_ids_spec.rb34
-rw-r--r--spec/migrations/add_web_hook_calls_to_plan_limits_paid_tiers_spec.rb101
-rw-r--r--spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb85
-rw-r--r--spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb35
-rw-r--r--spec/migrations/cleanup_orphaned_routes_spec.rb30
-rw-r--r--spec/migrations/finalize_routes_backfilling_for_projects_spec.rb72
-rw-r--r--spec/migrations/queue_backfill_project_feature_package_registry_access_level_spec.rb24
-rw-r--r--spec/migrations/remove_invalid_integrations_spec.rb31
-rw-r--r--spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb2
-rw-r--r--spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb46
-rw-r--r--spec/migrations/schedule_populate_requirements_issue_id_spec.rb79
-rw-r--r--spec/migrations/schedule_purging_stale_security_scans_spec.rb69
19 files changed, 743 insertions, 65 deletions
diff --git a/spec/migrations/20220416054011_schedule_backfill_project_member_namespace_id_spec.rb b/spec/migrations/20220416054011_schedule_backfill_project_member_namespace_id_spec.rb
new file mode 100644
index 00000000000..2838fc9387c
--- /dev/null
+++ b/spec/migrations/20220416054011_schedule_backfill_project_member_namespace_id_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleBackfillProjectMemberNamespaceId do
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of project members' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :members,
+ 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/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
index 769c0993b67..2bc3e89a748 100644
--- 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
@@ -15,21 +15,5 @@ RSpec.describe CleanUpFixMergeRequestDiffCommitUsers, :migration do
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/20220503035221_add_gitlab_schema_to_batched_background_migrations_spec.rb b/spec/migrations/20220503035221_add_gitlab_schema_to_batched_background_migrations_spec.rb
new file mode 100644
index 00000000000..5002c665c79
--- /dev/null
+++ b/spec/migrations/20220503035221_add_gitlab_schema_to_batched_background_migrations_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddGitlabSchemaToBatchedBackgroundMigrations do
+ it 'sets gitlab_schema for existing methods to "gitlab_main" and default to NULL' do
+ batched_migrations = table(:batched_background_migrations)
+ batched_migration = batched_migrations.create!(
+ id: 1, created_at: Time.now, updated_at: Time.now,
+ max_value: 100, batch_size: 100, sub_batch_size: 10, interval: 120,
+ job_class_name: 'TestJob', table_name: '_test', column_name: 'id'
+ )
+
+ reversible_migration do |migration|
+ migration.before -> {
+ batched_migrations.reset_column_information
+ column = batched_migrations.columns.find { |column| column.name == 'gitlab_schema' }
+
+ expect(column).to be_nil
+ }
+
+ migration.after -> {
+ expect(batched_migration.reload.gitlab_schema).to eq('gitlab_main')
+
+ batched_migrations.reset_column_information
+ column = batched_migrations.columns.find { |column| column.name == 'gitlab_schema' }
+
+ expect(column).to be
+ expect(column.default).to be_nil
+ }
+ 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
index 8bc336a6b26..575157f8331 100644
--- a/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb
+++ b/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb
@@ -4,8 +4,7 @@ require 'spec_helper'
require_migration!
-RSpec.describe FixAutomaticIterationsCadencesStartDate,
- quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/362446' do
+RSpec.describe FixAutomaticIterationsCadencesStartDate do
let(:migration) { described_class.new }
let(:namespaces) { table(:namespaces) }
let(:sprints) { table(:sprints) }
diff --git a/spec/migrations/20220512190659_remove_web_hooks_web_hook_logs_web_hook_id_fk_spec.rb b/spec/migrations/20220512190659_remove_web_hooks_web_hook_logs_web_hook_id_fk_spec.rb
new file mode 100644
index 00000000000..fa94a73582d
--- /dev/null
+++ b/spec/migrations/20220512190659_remove_web_hooks_web_hook_logs_web_hook_id_fk_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveWebHooksWebHookLogsWebHookIdFk do
+ let(:web_hooks) { table(:web_hooks) }
+ let(:logs) { table(:web_hook_logs) }
+
+ let!(:hook) { web_hooks.create! }
+
+ let!(:log_a) { logs.create!(web_hook_id: hook.id, response_body: 'msg-a') }
+ let!(:log_b) { logs.create!(web_hook_id: hook.id, response_body: 'msg-b') }
+
+ describe '#up' do
+ it 'allows us to delete web-hooks and leave web-hook logs intact' do
+ migrate!
+
+ expect { hook.delete }.not_to change(logs, :count)
+
+ expect(logs.pluck(:response_body)).to match_array %w[msg-a msg-b]
+ end
+ end
+
+ describe '#down' do
+ it 'ensures referential integrity of hook logs' do
+ migrate!
+ schema_migrate_down!
+
+ expect { hook.delete }.to change(logs, :count).by(-2)
+ end
+ end
+end
diff --git a/spec/migrations/20220520040416_schedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb b/spec/migrations/20220520040416_schedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb
new file mode 100644
index 00000000000..e3bc832a10b
--- /dev/null
+++ b/spec/migrations/20220520040416_schedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleSetLegacyOpenSourceLicenseAvailableForNonPublicProjects do
+ context 'on gitlab.com' do
+ let(:migration) { described_class::MIGRATION }
+
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ 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,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ )
+ 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
+
+ context 'on self-managed instance' do
+ let(:migration) { described_class.new }
+
+ before do
+ allow(Gitlab).to receive(:com?).and_return(false)
+ end
+
+ describe '#up' do
+ it 'does not schedule background job' do
+ expect(migration).not_to receive(:queue_batched_background_migration)
+
+ migration.up
+ end
+ end
+
+ describe '#down' do
+ it 'does not delete background job' do
+ expect(migration).not_to receive(:delete_batched_background_migration)
+
+ migration.down
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20220523171107_drop_deploy_tokens_token_column_spec.rb b/spec/migrations/20220523171107_drop_deploy_tokens_token_column_spec.rb
new file mode 100644
index 00000000000..78df6f5fc35
--- /dev/null
+++ b/spec/migrations/20220523171107_drop_deploy_tokens_token_column_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DropDeployTokensTokenColumn do
+ let(:deploy_tokens) { table(:deploy_tokens) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(deploy_tokens.column_names).to include('token')
+ }
+
+ migration.after -> {
+ deploy_tokens.reset_column_information
+
+ expect(deploy_tokens.column_names).not_to include('token')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20220524074947_finalize_backfill_null_note_discussion_ids_spec.rb b/spec/migrations/20220524074947_finalize_backfill_null_note_discussion_ids_spec.rb
new file mode 100644
index 00000000000..74ad4662b3e
--- /dev/null
+++ b/spec/migrations/20220524074947_finalize_backfill_null_note_discussion_ids_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe FinalizeBackfillNullNoteDiscussionIds, :migration do
+ subject(:migration) { described_class.new }
+
+ let(:notes) { table(:notes) }
+ let(:bg_migration_class) { Gitlab::BackgroundMigration::BackfillNoteDiscussionId }
+ 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
+ notes.create!(noteable_type: 'Issue', noteable_id: 1, discussion_id: Digest::SHA1.hexdigest('note1'))
+ notes.create!(noteable_type: 'Issue', noteable_id: 1, discussion_id: Digest::SHA1.hexdigest('note2'))
+ # update required
+ record1 = notes.create!(noteable_type: 'Issue', noteable_id: 1, discussion_id: nil)
+ record2 = notes.create!(noteable_type: 'Issue', noteable_id: 1, discussion_id: nil)
+ record3 = notes.create!(noteable_type: 'Issue', noteable_id: 1, discussion_id: nil)
+
+ expect(Gitlab::BackgroundMigration).to receive(:steal).with(bg_migration_class.name.demodulize)
+ expect(bg_migration_class).to receive(:new).twice.and_return(bg_migration)
+ expect(bg_migration).to receive(:perform).with(record1.id, record2.id)
+ expect(bg_migration).to receive(:perform).with(record3.id, record3.id)
+
+ migrate!
+ end
+end
diff --git a/spec/migrations/add_web_hook_calls_to_plan_limits_paid_tiers_spec.rb b/spec/migrations/add_web_hook_calls_to_plan_limits_paid_tiers_spec.rb
new file mode 100644
index 00000000000..63ad9367503
--- /dev/null
+++ b/spec/migrations/add_web_hook_calls_to_plan_limits_paid_tiers_spec.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddWebHookCallsToPlanLimitsPaidTiers do
+ let_it_be(:plans) { table(:plans) }
+ let_it_be(:plan_limits) { table(:plan_limits) }
+
+ context 'when on Gitlab.com' do
+ let(:free_plan) { plans.create!(name: 'free') }
+ let(:bronze_plan) { plans.create!(name: 'bronze') }
+ let(:silver_plan) { plans.create!(name: 'silver') }
+ let(:gold_plan) { plans.create!(name: 'gold') }
+ let(:premium_plan) { plans.create!(name: 'premium') }
+ let(:premium_trial_plan) { plans.create!(name: 'premium_trial') }
+ let(:ultimate_plan) { plans.create!(name: 'ultimate') }
+ let(:ultimate_trial_plan) { plans.create!(name: 'ultimate_trial') }
+ let(:opensource_plan) { plans.create!(name: 'opensource') }
+
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ # 120 is the value for 'free' migrated in `db/migrate/20210601131742_update_web_hook_calls_limit.rb`
+ plan_limits.create!(plan_id: free_plan.id, web_hook_calls: 120)
+ plan_limits.create!(plan_id: bronze_plan.id)
+ plan_limits.create!(plan_id: silver_plan.id)
+ plan_limits.create!(plan_id: gold_plan.id)
+ plan_limits.create!(plan_id: premium_plan.id)
+ plan_limits.create!(plan_id: premium_trial_plan.id)
+ plan_limits.create!(plan_id: ultimate_plan.id)
+ plan_limits.create!(plan_id: ultimate_trial_plan.id)
+ plan_limits.create!(plan_id: opensource_plan.id)
+ end
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(
+ plan_limits.pluck(:plan_id, :web_hook_calls, :web_hook_calls_mid, :web_hook_calls_low)
+ ).to contain_exactly(
+ [free_plan.id, 120, 0, 0],
+ [bronze_plan.id, 0, 0, 0],
+ [silver_plan.id, 0, 0, 0],
+ [gold_plan.id, 0, 0, 0],
+ [premium_plan.id, 0, 0, 0],
+ [premium_trial_plan.id, 0, 0, 0],
+ [ultimate_plan.id, 0, 0, 0],
+ [ultimate_trial_plan.id, 0, 0, 0],
+ [opensource_plan.id, 0, 0, 0]
+ )
+ }
+
+ migration.after -> {
+ expect(
+ plan_limits.pluck(:plan_id, :web_hook_calls, :web_hook_calls_mid, :web_hook_calls_low)
+ ).to contain_exactly(
+ [free_plan.id, 500, 500, 500],
+ [bronze_plan.id, 4_000, 2_800, 1_600],
+ [silver_plan.id, 4_000, 2_800, 1_600],
+ [gold_plan.id, 13_000, 9_000, 6_000],
+ [premium_plan.id, 4_000, 2_800, 1_600],
+ [premium_trial_plan.id, 4_000, 2_800, 1_600],
+ [ultimate_plan.id, 13_000, 9_000, 6_000],
+ [ultimate_trial_plan.id, 13_000, 9_000, 6_000],
+ [opensource_plan.id, 13_000, 9_000, 6_000]
+ )
+ }
+ end
+ end
+ end
+
+ context 'when on self hosted' do
+ let(:default_plan) { plans.create!(name: 'default') }
+
+ before do
+ allow(Gitlab).to receive(:com?).and_return(false)
+
+ plan_limits.create!(plan_id: default_plan.id)
+ end
+
+ it 'does nothing' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(
+ plan_limits.pluck(:plan_id, :web_hook_calls, :web_hook_calls_mid, :web_hook_calls_low)
+ ).to contain_exactly(
+ [default_plan.id, 0, 0, 0]
+ )
+ }
+
+ migration.after -> {
+ expect(
+ plan_limits.pluck(:plan_id, :web_hook_calls, :web_hook_calls_mid, :web_hook_calls_low)
+ ).to contain_exactly(
+ [default_plan.id, 0, 0, 0]
+ )
+ }
+ end
+ end
+ end
+end
diff --git a/spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb b/spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb
new file mode 100644
index 00000000000..a359a78ab45
--- /dev/null
+++ b/spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BulkInsertClusterEnabledGrants, :migration do
+ let(:migration) { described_class.new }
+
+ let(:cluster_enabled_grants) { table(:cluster_enabled_grants) }
+ let(:namespaces) { table(:namespaces) }
+ let(:cluster_projects) { table(:cluster_projects) }
+ let(:cluster_groups) { table(:cluster_groups) }
+ let(:clusters) { table(:clusters) }
+ let(:projects) { table(:projects) }
+
+ context 'with namespaces, cluster_groups and cluster_projects' do
+ it 'creates unique cluster_enabled_grants for root_namespaces with clusters' do
+ # Does not create grants for namespaces without clusters
+ namespaces.create!(id: 1, path: 'eee', name: 'eee', traversal_ids: [1]) # not used
+
+ # Creates unique grant for a root namespace with its own cluster
+ root_ns_with_own_cluster = namespaces.create!(id: 2, path: 'ddd', name: 'ddd', traversal_ids: [2])
+ cluster_root_ns_with_own_cluster = clusters.create!(name: 'cluster_root_ns_with_own_cluster')
+ cluster_groups.create!(
+ cluster_id: cluster_root_ns_with_own_cluster.id,
+ group_id: root_ns_with_own_cluster.id)
+
+ # Creates unique grant for namespaces with multiple sub-group clusters
+ root_ns_with_sub_group_clusters = namespaces.create!(id: 3, path: 'aaa', name: 'aaa', traversal_ids: [3])
+
+ subgroup_1 = namespaces.create!(
+ id: 4,
+ path: 'bbb',
+ name: 'bbb',
+ parent_id: root_ns_with_sub_group_clusters.id,
+ traversal_ids: [root_ns_with_sub_group_clusters.id, 4])
+ cluster_subgroup_1 = clusters.create!(name: 'cluster_subgroup_1')
+ cluster_groups.create!(cluster_id: cluster_subgroup_1.id, group_id: subgroup_1.id)
+
+ subgroup_2 = namespaces.create!(
+ id: 5,
+ path: 'ccc',
+ name: 'ccc',
+ parent_id: subgroup_1.id,
+ traversal_ids: [root_ns_with_sub_group_clusters.id, subgroup_1.id, 5])
+ cluster_subgroup_2 = clusters.create!(name: 'cluster_subgroup_2')
+ cluster_groups.create!(cluster_id: cluster_subgroup_2.id, group_id: subgroup_2.id)
+
+ # Creates unique grant for a root namespace with multiple projects clusters
+ root_ns_with_project_group_clusters = namespaces.create!(id: 6, path: 'fff', name: 'fff', traversal_ids: [6])
+
+ project_namespace_1 = namespaces.create!(id: 7, path: 'ggg', name: 'ggg', traversal_ids: [7])
+ project_1 = projects.create!(
+ name: 'project_1',
+ namespace_id: root_ns_with_project_group_clusters.id,
+ project_namespace_id: project_namespace_1.id)
+ cluster_project_1 = clusters.create!(name: 'cluster_project_1')
+ cluster_projects.create!(cluster_id: cluster_project_1.id, project_id: project_1.id)
+
+ project_namespace_2 = namespaces.create!(id: 8, path: 'hhh', name: 'hhh', traversal_ids: [8])
+ project_2 = projects.create!(
+ name: 'project_2',
+ namespace_id: root_ns_with_project_group_clusters.id,
+ project_namespace_id: project_namespace_2.id)
+ cluster_project_2 = clusters.create!(name: 'cluster_project_2')
+ cluster_projects.create!(cluster_id: cluster_project_2.id, project_id: project_2.id)
+
+ migrate!
+
+ expected_cluster_enabled_grants = [
+ root_ns_with_sub_group_clusters.id,
+ root_ns_with_own_cluster.id,
+ root_ns_with_project_group_clusters.id
+ ]
+
+ expect(cluster_enabled_grants.pluck(:namespace_id)).to match_array(expected_cluster_enabled_grants)
+ end
+ end
+
+ context 'without namespaces, cluster_groups or cluster_projects' do
+ it 'does nothing' do
+ expect { migrate! }.not_to change { cluster_enabled_grants.count }
+ end
+ end
+end
diff --git a/spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb b/spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb
new file mode 100644
index 00000000000..1517405b358
--- /dev/null
+++ b/spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CleanupBackfillIntegrationsEnableSslVerification, :migration do
+ let(:job_class_name) { 'BackfillIntegrationsEnableSslVerification' }
+
+ before do
+ # Jobs enqueued in Sidekiq.
+ Sidekiq::Testing.disable! do
+ BackgroundMigrationWorker.perform_in(10, job_class_name, [1, 2])
+ BackgroundMigrationWorker.perform_in(20, job_class_name, [3, 4])
+ end
+
+ # Jobs tracked in the database.
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: job_class_name,
+ arguments: [5, 6],
+ status: Gitlab::Database::BackgroundMigrationJob.statuses['pending']
+ )
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: job_class_name,
+ arguments: [7, 8],
+ status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
+ )
+
+ migrate!
+ end
+
+ it_behaves_like(
+ 'finalized tracked background migration',
+ Gitlab::BackgroundMigration::BackfillIntegrationsEnableSslVerification
+ )
+end
diff --git a/spec/migrations/cleanup_orphaned_routes_spec.rb b/spec/migrations/cleanup_orphaned_routes_spec.rb
new file mode 100644
index 00000000000..68598939557
--- /dev/null
+++ b/spec/migrations/cleanup_orphaned_routes_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CleanupOrphanedRoutes, :migration do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background jobs' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :routes,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ gitlab_schema: :gitlab_main
+ )
+ 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/finalize_routes_backfilling_for_projects_spec.rb b/spec/migrations/finalize_routes_backfilling_for_projects_spec.rb
new file mode 100644
index 00000000000..2bb740d0c2f
--- /dev/null
+++ b/spec/migrations/finalize_routes_backfilling_for_projects_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FinalizeRoutesBackfillingForProjects, :migration do
+ let(:batched_migrations) { table(:batched_background_migrations) }
+
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ 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('BackfillNamespaceIdForProjectRoute', :projects, :id, [])
+ end
+ end
+ end
+
+ context 'when routes backfilling migration is missing' do
+ it 'warns migration not found' do
+ expect(Gitlab::AppLogger)
+ .to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
+
+ migrate!
+ end
+ end
+
+ context 'with backfilling migration present' do
+ let!(:project_namespace_backfill) do
+ batched_migrations.create!(
+ job_class_name: 'BackfillNamespaceIdForProjectRoute',
+ table_name: :routes,
+ column_name: :id,
+ job_arguments: [],
+ interval: 2.minutes,
+ min_value: 1,
+ max_value: 2,
+ batch_size: 1000,
+ sub_batch_size: 200,
+ gitlab_schema: :gitlab_main,
+ status: 3 # finished
+ )
+ end
+
+ context 'when backfilling migration finished successfully' do
+ it 'does not raise exception' do
+ expect { migrate! }.not_to raise_error
+ end
+ end
+
+ context 'with different backfilling migration statuses' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:status, :description) do
+ 0 | 'paused'
+ 1 | 'active'
+ 4 | 'failed'
+ 5 | 'finalizing'
+ end
+
+ with_them do
+ before do
+ project_namespace_backfill.update!(status: status)
+ end
+
+ it_behaves_like 'finalizes the migration'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/queue_backfill_project_feature_package_registry_access_level_spec.rb b/spec/migrations/queue_backfill_project_feature_package_registry_access_level_spec.rb
new file mode 100644
index 00000000000..487d94b82a1
--- /dev/null
+++ b/spec/migrations/queue_backfill_project_feature_package_registry_access_level_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillProjectFeaturePackageRegistryAccessLevel do
+ let_it_be(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :projects,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/remove_invalid_integrations_spec.rb b/spec/migrations/remove_invalid_integrations_spec.rb
new file mode 100644
index 00000000000..cab2d79998e
--- /dev/null
+++ b/spec/migrations/remove_invalid_integrations_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveInvalidIntegrations, :migration do
+ describe '#up' do
+ let!(:integrations) { table(:integrations) }
+
+ let!(:valid_integration) { integrations.create!(type_new: 'Foo') }
+ let!(:invalid_integration) { integrations.create! }
+
+ it 'removes invalid integrations', :aggregate_failures do
+ expect { migrate! }
+ .to change { integrations.pluck(:id) }.to(contain_exactly(valid_integration.id))
+ end
+
+ context 'when there are many invalid integrations' do
+ before do
+ stub_const('RemoveInvalidIntegrations::BATCH_SIZE', 3)
+ 5.times { integrations.create! }
+ end
+
+ it 'removes them all' do
+ migrate!
+
+ expect(integrations.pluck(:type_new)).to all(be_present)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb b/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
index fdafc4a5a89..198644fe183 100644
--- a/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
+++ b/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
-RSpec.describe RemoveNotNullContraintOnTitleFromSprints, :migration, schema: 20220304052335 do
+RSpec.describe RemoveNotNullContraintOnTitleFromSprints, :migration do
let(:migration) { described_class.new }
let(:namespaces) { table(:namespaces) }
let(:sprints) { table(:sprints) }
diff --git a/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb b/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb
deleted file mode 100644
index 52bbd5b4f6e..00000000000
--- a/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleMigratePagesToZipStorage, :sidekiq_might_not_need_inline, schema: 20210301200959 do
- let(:migration_class) { described_class::MIGRATION }
- let(:migration_name) { migration_class.to_s.demodulize }
-
- let(:namespaces_table) { table(:namespaces) }
- let(:projects_table) { table(:projects) }
- let(:metadata_table) { table(:project_pages_metadata) }
- let(:deployments_table) { table(:pages_deployments) }
-
- let(:namespace) { namespaces_table.create!(path: "group", name: "group") }
-
- def create_project_metadata(path, deployed, with_deployment)
- project = projects_table.create!(path: path, namespace_id: namespace.id)
-
- deployment_id = nil
-
- if with_deployment
- deployment_id = deployments_table.create!(project_id: project.id, file_store: 1, file: '1', file_count: 1, file_sha256: '123', size: 1).id
- end
-
- metadata_table.create!(project_id: project.id, deployed: deployed, pages_deployment_id: deployment_id)
- end
-
- it 'correctly schedules background migrations' do
- Sidekiq::Testing.fake! do
- freeze_time do
- create_project_metadata("not-deployed-project", false, false)
-
- first_id = create_project_metadata("project1", true, false).id
- last_id = create_project_metadata("project2", true, false).id
-
- create_project_metadata("project-with-deployment", true, true)
-
- migrate!
-
- expect(migration_name).to be_scheduled_delayed_migration(5.minutes, first_id, last_id)
- expect(BackgroundMigrationWorker.jobs.size).to eq(1)
- end
- end
- end
-end
diff --git a/spec/migrations/schedule_populate_requirements_issue_id_spec.rb b/spec/migrations/schedule_populate_requirements_issue_id_spec.rb
new file mode 100644
index 00000000000..2702c000b60
--- /dev/null
+++ b/spec/migrations/schedule_populate_requirements_issue_id_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SchedulePopulateRequirementsIssueId do
+ include MigrationHelpers::WorkItemTypesHelper
+
+ let(:issues) { table(:issues) }
+ let(:requirements) { table(:requirements) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:users) { table(:users) }
+ let!(:group) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
+ let!(:project_namespace) { namespaces.create!(name: 'project-namespace', path: 'project-namespace') }
+
+ let!(:project) do
+ projects.create!(namespace_id: group.id, project_namespace_id: project_namespace.id, name: 'gitlab', path: 'gitlab')
+ end
+
+ let(:migration) { described_class::MIGRATION }
+
+ let!(:author) do
+ users.create!(
+ email: 'author@example.com',
+ notification_email: 'author@example.com',
+ name: 'author',
+ username: 'author',
+ projects_limit: 10,
+ state: 'active')
+ end
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+ end
+
+ it 'schedules jobs for all requirements without issues in sync' do
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ # Restores the previous schema so we do not have a NOT NULL
+ # constraint on requirements.issue_id column, which would
+ # prevent us to create invalid requirement records.
+ migration_context.down(previous_migration(3).version)
+
+ requirement_1 = create_requirement(iid: 1, title: 'r 1')
+
+ # Create one requirement with issue_id present, to make
+ # sure a job won't be scheduled for it
+ work_item_type_id = work_item_types_table.find_by(namespace_id: nil, name: 'Issue').id
+ issue = issues.create!(state_id: 1, work_item_type_id: work_item_type_id)
+ create_requirement(iid: 2, title: 'r 2', issue_id: issue.id)
+
+ requirement_3 = create_requirement(iid: 3, title: 'r 3')
+ requirement_4 = create_requirement(iid: 4, title: 'r 4')
+ requirement_5 = create_requirement(iid: 5, title: 'r 5')
+
+ migrate!
+
+ expect(migration).to be_scheduled_delayed_migration(120.seconds, requirement_1.id, requirement_3.id)
+ expect(migration).to be_scheduled_delayed_migration(240.seconds, requirement_4.id, requirement_5.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ end
+ end
+ end
+
+ def create_requirement(iid:, title:, issue_id: nil)
+ requirements.create!(
+ iid: iid,
+ project_id: project.id,
+ issue_id: issue_id,
+ title: title,
+ state: 1,
+ created_at: Time.now,
+ updated_at: Time.now,
+ author_id: author.id)
+ end
+end
diff --git a/spec/migrations/schedule_purging_stale_security_scans_spec.rb b/spec/migrations/schedule_purging_stale_security_scans_spec.rb
new file mode 100644
index 00000000000..b5a38634b58
--- /dev/null
+++ b/spec/migrations/schedule_purging_stale_security_scans_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SchedulePurgingStaleSecurityScans do
+ let_it_be(:namespaces) { table(:namespaces) }
+ let_it_be(:projects) { table(:projects) }
+ let_it_be(:pipelines) { table(:ci_pipelines) }
+ let_it_be(:builds) { table(:ci_builds) }
+ let_it_be(:security_scans) { table(:security_scans) }
+
+ let_it_be(:namespace) { namespaces.create!(name: "foo", path: "bar") }
+ let_it_be(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id) }
+ let_it_be(:pipeline) { pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success') }
+ let_it_be(:ci_build) { builds.create!(commit_id: pipeline.id, retried: false, type: 'Ci::Build') }
+
+ let!(:security_scan_1) { security_scans.create!(build_id: ci_build.id, scan_type: 1, created_at: 92.days.ago) }
+ let!(:security_scan_2) { security_scans.create!(build_id: ci_build.id, scan_type: 2, created_at: 91.days.ago) }
+
+ let(:com?) { false }
+ let(:dev_or_test_env?) { false }
+
+ before do
+ allow(::Gitlab).to receive(:com?).and_return(com?)
+ allow(::Gitlab).to receive(:dev_or_test_env?).and_return(dev_or_test_env?)
+
+ stub_const("#{described_class.name}::BATCH_SIZE", 1)
+ end
+
+ shared_examples_for 'schedules the background jobs' do
+ before do
+ # This will not be scheduled as it's not stale
+ security_scans.create!(build_id: ci_build.id, scan_type: 3)
+ end
+
+ around do |example|
+ freeze_time { Sidekiq::Testing.fake! { example.run } }
+ end
+
+ it 'creates 2 jobs', :aggregate_failures do
+ migrate!
+
+ expect(BackgroundMigrationWorker.jobs.size).to be(2)
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(2.minutes, security_scan_1.id, security_scan_1.id)
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(4.minutes, security_scan_2.id, security_scan_2.id)
+ end
+ end
+
+ context 'when the migration does not run on GitLab.com or `dev_or_test_env`' do
+ it 'does not run the migration' do
+ expect { migrate! }.not_to change { BackgroundMigrationWorker.jobs.size }
+ end
+ end
+
+ context 'when the migration runs on GitLab.com' do
+ let(:com?) { true }
+
+ it_behaves_like 'schedules the background jobs'
+ end
+
+ context 'when the migration runs on dev or test env' do
+ let(:dev_or_test_env?) { true }
+
+ it_behaves_like 'schedules the background jobs'
+ end
+end