summaryrefslogtreecommitdiff
path: root/spec/migrations
diff options
context:
space:
mode:
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb44
-rw-r--r--spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb114
-rw-r--r--spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb44
-rw-r--r--spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb25
-rw-r--r--spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb42
-rw-r--r--spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb120
-rw-r--r--spec/migrations/20210514063252_schedule_cleanup_orphaned_lfs_objects_projects_spec.rb37
-rw-r--r--spec/migrations/20210601073400_fix_total_stage_in_vsa_spec.rb30
-rw-r--r--spec/migrations/20210601080039_group_protected_environments_add_index_and_constraint_spec.rb29
-rw-r--r--spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb3
-rw-r--r--spec/migrations/20210804150320_create_base_work_item_types_spec.rb3
-rw-r--r--spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb2
-rw-r--r--spec/migrations/20211012134316_clean_up_migrate_merge_request_diff_commit_users_spec.rb2
-rw-r--r--spec/migrations/20211028155449_schedule_fix_merge_request_diff_commit_users_migration_spec.rb2
-rw-r--r--spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb2
-rw-r--r--spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb2
-rw-r--r--spec/migrations/20220502015011_clean_up_fix_merge_request_diff_commit_users_spec.rb2
-rw-r--r--spec/migrations/20221018050323_add_objective_and_keyresult_to_work_item_types_spec.rb2
-rw-r--r--spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb24
-rw-r--r--spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb53
-rw-r--r--spec/migrations/20221220131020_bump_default_partition_id_value_for_ci_tables_spec.rb78
-rw-r--r--spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb22
-rw-r--r--spec/migrations/20221222092958_sync_new_amount_used_with_amount_used_spec.rb54
-rw-r--r--spec/migrations/20221223123019_delete_queued_jobs_for_vulnerabilities_feedback_migration_spec.rb33
-rw-r--r--spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb55
-rw-r--r--spec/migrations/20230116111252_finalize_todo_sanitization_spec.rb57
-rw-r--r--spec/migrations/add_new_trail_plans_spec.rb95
-rw-r--r--spec/migrations/backfill_clusters_integration_prometheus_enabled_spec.rb80
-rw-r--r--spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb103
-rw-r--r--spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb34
-rw-r--r--spec/migrations/change_web_hook_events_default_spec.rb36
-rw-r--r--spec/migrations/clean_up_pending_builds_table_spec.rb48
-rw-r--r--spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb48
-rw-r--r--spec/migrations/cleanup_move_container_registry_enabled_to_project_feature_spec.rb45
-rw-r--r--spec/migrations/cleanup_mr_attention_request_todos_spec.rb2
-rw-r--r--spec/migrations/confirm_support_bot_user_spec.rb86
-rw-r--r--spec/migrations/delete_security_findings_without_uuid_spec.rb36
-rw-r--r--spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb73
-rw-r--r--spec/migrations/migrate_elastic_index_settings_spec.rb44
-rw-r--r--spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb59
-rw-r--r--spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb61
-rw-r--r--spec/migrations/queue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb18
-rw-r--r--spec/migrations/remove_hipchat_service_records_spec.rb23
-rw-r--r--spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb27
-rw-r--r--spec/migrations/schedule_add_primary_email_to_emails_if_user_confirmed_spec.rb31
-rw-r--r--spec/migrations/schedule_backfill_draft_status_on_merge_requests_corrected_regex_spec.rb3
-rw-r--r--spec/migrations/schedule_disable_expiration_policies_linked_to_no_container_images_spec.rb47
-rw-r--r--spec/migrations/schedule_update_timelogs_project_id_spec.rb33
-rw-r--r--spec/migrations/schedule_update_users_where_two_factor_auth_required_from_group_spec.rb29
-rw-r--r--spec/migrations/second_recount_epic_cache_counts_spec.rb32
-rw-r--r--spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb2
-rw-r--r--spec/migrations/update_invalid_web_hooks_spec.rb30
52 files changed, 441 insertions, 1565 deletions
diff --git a/spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb b/spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb
deleted file mode 100644
index 18aa8e92560..00000000000
--- a/spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe BackfillTotalTupleCountForBatchedMigrations, :migration, schema: 20210406140057,
- feature_category: :database do
- let!(:table_name) { 'projects' }
-
- let!(:migrations) { table(:batched_background_migrations) }
-
- let!(:migration) do
- migrations.create!(
- created_at: Time.now,
- updated_at: Time.now,
- min_value: 1,
- max_value: 10_000,
- batch_size: 1_000,
- sub_batch_size: 100,
- interval: 120,
- status: 0,
- job_class_name: 'Foo',
- table_name: table_name,
- column_name: :id,
- total_tuple_count: nil
- )
- end
-
- describe '#up' do
- before do
- expect(Gitlab::Database::PgClass).to receive(:for_table).with(table_name).and_return(estimate)
- end
-
- let(:estimate) { double('estimate', cardinality_estimate: 42) }
-
- it 'updates total_tuple_count attribute' do
- migrate!
-
- migrations.all.each do |migration|
- expect(migration.total_tuple_count).to eq(estimate.cardinality_estimate)
- end
- end
- end
-end
diff --git a/spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb b/spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb
deleted file mode 100644
index 258bf7a3e69..00000000000
--- a/spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleDropInvalidVulnerabilities, :migration, feature_category: :value_stream_management do
- let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
- let!(:users) { table(:users) }
- let!(:user) { create_user! }
- let!(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
-
- let!(:scanners) { table(:vulnerability_scanners) }
- let!(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
- let!(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
-
- let!(:vulnerabilities) { table(:vulnerabilities) }
- let!(:vulnerability_with_finding) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:vulnerability_without_finding) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
- let!(:primary_identifier) do
- vulnerability_identifiers.create!(
- project_id: project.id,
- external_type: 'uuid-v5',
- external_id: 'uuid-v5',
- fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
- name: 'Identifier for UUIDv5')
- end
-
- let!(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
- let!(:finding) do
- create_finding!(
- vulnerability_id: vulnerability_with_finding.id,
- project_id: project.id,
- scanner_id: scanner.id,
- primary_identifier_id: primary_identifier.id
- )
- end
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- around do |example|
- freeze_time { Sidekiq::Testing.fake! { example.run } }
- end
-
- it 'schedules background migrations' do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- expect(described_class::MIGRATION).to be_scheduled_migration(vulnerability_with_finding.id, vulnerability_with_finding.id)
- expect(described_class::MIGRATION).to be_scheduled_migration(vulnerability_without_finding.id, vulnerability_without_finding.id)
- end
-
- private
-
- def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
- vulnerabilities.create!(
- project_id: project_id,
- author_id: author_id,
- title: title,
- severity: severity,
- confidence: confidence,
- report_type: report_type
- )
- end
-
- # rubocop:disable Metrics/ParameterLists
- def create_finding!(
- vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:,
- name: "test", severity: 7, confidence: 7, report_type: 0,
- project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
- metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
- vulnerabilities_findings.create!(
- vulnerability_id: vulnerability_id,
- project_id: project_id,
- name: name,
- severity: severity,
- confidence: confidence,
- report_type: report_type,
- project_fingerprint: project_fingerprint,
- scanner_id: scanner_id,
- primary_identifier_id: primary_identifier_id,
- location_fingerprint: location_fingerprint,
- metadata_version: metadata_version,
- raw_metadata: raw_metadata,
- uuid: uuid
- )
- end
- # rubocop:enable Metrics/ParameterLists
-
- def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
- users.create!(
- name: name,
- email: email,
- username: name,
- projects_limit: 0,
- user_type: user_type,
- confirmed_at: Time.current
- )
- end
-end
diff --git a/spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb b/spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb
deleted file mode 100644
index 688fc5eb23a..00000000000
--- a/spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-#
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe CopyAdoptionSnapshotNamespace, :migration, schema: 20210430124630, feature_category: :devops_reports do
- let(:namespaces_table) { table(:namespaces) }
- let(:segments_table) { table(:analytics_devops_adoption_segments) }
- let(:snapshots_table) { table(:analytics_devops_adoption_snapshots) }
-
- it 'updates all snapshots without namespace set' do
- namespaces_table.create!(id: 123, name: 'group1', path: 'group1')
- namespaces_table.create!(id: 124, name: 'group2', path: 'group2')
-
- segments_table.create!(id: 1, namespace_id: 123)
- segments_table.create!(id: 2, namespace_id: 124)
-
- create_snapshot(id: 1, segment_id: 1)
- create_snapshot(id: 2, segment_id: 2)
- create_snapshot(id: 3, segment_id: 2, namespace_id: 123)
-
- migrate!
-
- expect(snapshots_table.find(1).namespace_id).to eq 123
- expect(snapshots_table.find(2).namespace_id).to eq 124
- expect(snapshots_table.find(3).namespace_id).to eq 123
- end
-
- def create_snapshot(**additional_params)
- defaults = {
- recorded_at: Time.zone.now,
- issue_opened: true,
- merge_request_opened: true,
- merge_request_approved: true,
- runner_configured: true,
- pipeline_succeeded: true,
- deploy_succeeded: true,
- end_time: Time.zone.now.end_of_month
- }
-
- snapshots_table.create!(defaults.merge(additional_params))
- end
-end
diff --git a/spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb b/spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb
deleted file mode 100644
index 0fb3029ec6a..00000000000
--- a/spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe CopyAdoptionSegmentsNamespace, :migration, feature_category: :devops_reports do
- let(:namespaces_table) { table(:namespaces) }
- let(:segments_table) { table(:analytics_devops_adoption_segments) }
-
- before do
- namespaces_table.create!(id: 123, name: 'group1', path: 'group1')
- namespaces_table.create!(id: 124, name: 'group2', path: 'group2')
-
- segments_table.create!(id: 1, namespace_id: 123, display_namespace_id: nil)
- segments_table.create!(id: 2, namespace_id: 124, display_namespace_id: 123)
- end
-
- it 'updates all segments without display namespace' do
- migrate!
-
- expect(segments_table.find(1).display_namespace_id).to eq 123
- expect(segments_table.find(2).display_namespace_id).to eq 123
- end
-end
diff --git a/spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb b/spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb
deleted file mode 100644
index 07a90c2d276..00000000000
--- a/spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe AddProjectValueStreamIdToProjectStages, schema: 20210503105022,
- feature_category: :value_stream_management do
- let(:stages) { table(:analytics_cycle_analytics_project_stages) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
-
- let(:namespace) { table(:namespaces).create!(name: 'ns1', path: 'nsq1') }
-
- before do
- project = projects.create!(name: 'p1', namespace_id: namespace.id)
-
- stages.create!(
- project_id: project.id,
- created_at: Time.now,
- updated_at: Time.now,
- start_event_identifier: 1,
- end_event_identifier: 2,
- name: 'stage 1'
- )
-
- stages.create!(
- project_id: project.id,
- created_at: Time.now,
- updated_at: Time.now,
- start_event_identifier: 3,
- end_event_identifier: 4,
- name: 'stage 2'
- )
- end
-
- it 'deletes the existing rows' do
- migrate!
-
- expect(stages.count).to eq(0)
- end
-end
diff --git a/spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb b/spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb
deleted file mode 100644
index b514c92c52d..00000000000
--- a/spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb
+++ /dev/null
@@ -1,120 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleDropInvalidVulnerabilities2, :migration, feature_category: :value_stream_management do
- let!(:background_migration_jobs) { table(:background_migration_jobs) }
-
- let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
- let!(:users) { table(:users) }
- let!(:user) { create_user! }
- let!(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
-
- let!(:scanners) { table(:vulnerability_scanners) }
- let!(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
- let!(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
-
- let!(:vulnerabilities) { table(:vulnerabilities) }
- let!(:vulnerability_with_finding) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:vulnerability_without_finding) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
- let!(:primary_identifier) do
- vulnerability_identifiers.create!(
- project_id: project.id,
- external_type: 'uuid-v5',
- external_id: 'uuid-v5',
- fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
- name: 'Identifier for UUIDv5')
- end
-
- let!(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
- let!(:finding) do
- create_finding!(
- vulnerability_id: vulnerability_with_finding.id,
- project_id: project.id,
- scanner_id: scanner.id,
- primary_identifier_id: primary_identifier.id
- )
- end
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- around do |example|
- freeze_time { Sidekiq::Testing.fake! { example.run } }
- end
-
- it 'schedules background migrations' do
- migrate!
-
- expect(background_migration_jobs.count).to eq(2)
- expect(background_migration_jobs.first.arguments).to eq([vulnerability_with_finding.id, vulnerability_with_finding.id])
- expect(background_migration_jobs.second.arguments).to eq([vulnerability_without_finding.id, vulnerability_without_finding.id])
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, vulnerability_with_finding.id, vulnerability_with_finding.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, vulnerability_without_finding.id, vulnerability_without_finding.id)
- end
-
- private
-
- def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
- vulnerabilities.create!(
- project_id: project_id,
- author_id: author_id,
- title: title,
- severity: severity,
- confidence: confidence,
- report_type: report_type
- )
- end
-
- # rubocop:disable Metrics/ParameterLists
- def create_finding!(
- vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:,
- name: "test", severity: 7, confidence: 7, report_type: 0,
- project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
- metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
- vulnerabilities_findings.create!(
- vulnerability_id: vulnerability_id,
- project_id: project_id,
- name: name,
- severity: severity,
- confidence: confidence,
- report_type: report_type,
- project_fingerprint: project_fingerprint,
- scanner_id: scanner_id,
- primary_identifier_id: primary_identifier_id,
- location_fingerprint: location_fingerprint,
- metadata_version: metadata_version,
- raw_metadata: raw_metadata,
- uuid: uuid
- )
- end
- # rubocop:enable Metrics/ParameterLists
-
- def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
- users.create!(
- name: name,
- email: email,
- username: name,
- projects_limit: 0,
- user_type: user_type,
- confirmed_at: Time.current
- )
- end
-end
diff --git a/spec/migrations/20210514063252_schedule_cleanup_orphaned_lfs_objects_projects_spec.rb b/spec/migrations/20210514063252_schedule_cleanup_orphaned_lfs_objects_projects_spec.rb
deleted file mode 100644
index 8a76f0847e9..00000000000
--- a/spec/migrations/20210514063252_schedule_cleanup_orphaned_lfs_objects_projects_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleCleanupOrphanedLfsObjectsProjects, schema: 20210511165250, feature_category: :git_lfs do
- let(:lfs_objects_projects) { table(:lfs_objects_projects) }
- let(:projects) { table(:projects) }
- let(:namespaces) { table(:namespaces) }
- let(:lfs_objects) { table(:lfs_objects) }
-
- let(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') }
- let(:project) { projects.create!(namespace_id: namespace.id) }
- let(:another_project) { projects.create!(namespace_id: namespace.id) }
- let(:lfs_object) { lfs_objects.create!(oid: 'abcdef', size: 1) }
- let(:another_lfs_object) { lfs_objects.create!(oid: '1abcde', size: 2) }
-
- describe '#up' do
- it 'schedules CleanupOrphanedLfsObjectsProjects background jobs' do
- stub_const("#{described_class}::BATCH_SIZE", 2)
-
- lfs_objects_project1 = lfs_objects_projects.create!(project_id: project.id, lfs_object_id: lfs_object.id)
- lfs_objects_project2 = lfs_objects_projects.create!(project_id: another_project.id, lfs_object_id: lfs_object.id)
- lfs_objects_project3 = lfs_objects_projects.create!(project_id: project.id, lfs_object_id: another_lfs_object.id)
- lfs_objects_project4 = lfs_objects_projects.create!(project_id: another_project.id, lfs_object_id: another_lfs_object.id)
-
- freeze_time do
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, lfs_objects_project1.id, lfs_objects_project2.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, lfs_objects_project3.id, lfs_objects_project4.id)
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- end
- end
- end
-end
diff --git a/spec/migrations/20210601073400_fix_total_stage_in_vsa_spec.rb b/spec/migrations/20210601073400_fix_total_stage_in_vsa_spec.rb
deleted file mode 100644
index 24a71e48035..00000000000
--- a/spec/migrations/20210601073400_fix_total_stage_in_vsa_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixTotalStageInVsa, :migration, schema: 20210518001450, feature_category: :devops_reports do
- let(:namespaces) { table(:namespaces) }
- let(:group_value_streams) { table(:analytics_cycle_analytics_group_value_streams) }
- let(:group_stages) { table(:analytics_cycle_analytics_group_stages) }
-
- let!(:group) { namespaces.create!(name: 'ns1', path: 'ns1', type: 'Group') }
- let!(:group_vs_1) { group_value_streams.create!(name: 'default', group_id: group.id) }
- let!(:group_vs_2) { group_value_streams.create!(name: 'other', group_id: group.id) }
- let!(:group_vs_3) { group_value_streams.create!(name: 'another', group_id: group.id) }
- let!(:group_stage_total) { group_stages.create!(name: 'Total', custom: false, group_id: group.id, group_value_stream_id: group_vs_1.id, start_event_identifier: 1, end_event_identifier: 2) }
- let!(:group_stage_different_name) { group_stages.create!(name: 'Issue', custom: false, group_id: group.id, group_value_stream_id: group_vs_2.id, start_event_identifier: 1, end_event_identifier: 2) }
- let!(:group_stage_total_custom) { group_stages.create!(name: 'Total', custom: true, group_id: group.id, group_value_stream_id: group_vs_3.id, start_event_identifier: 1, end_event_identifier: 2) }
-
- it 'deduplicates issue_metrics table' do
- migrate!
-
- group_stage_total.reload
- group_stage_different_name.reload
- group_stage_total_custom.reload
-
- expect(group_stage_total.custom).to eq(true)
- expect(group_stage_different_name.custom).to eq(false)
- expect(group_stage_total_custom.custom).to eq(true)
- end
-end
diff --git a/spec/migrations/20210601080039_group_protected_environments_add_index_and_constraint_spec.rb b/spec/migrations/20210601080039_group_protected_environments_add_index_and_constraint_spec.rb
deleted file mode 100644
index 592497805de..00000000000
--- a/spec/migrations/20210601080039_group_protected_environments_add_index_and_constraint_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe GroupProtectedEnvironmentsAddIndexAndConstraint, feature_category: :continuous_delivery do
- let(:migration) { described_class.new }
- let(:protected_environments) { table(:protected_environments) }
- let(:group) { table(:namespaces).create!(name: 'group', path: 'group') }
- let(:project) { table(:projects).create!(name: 'project', path: 'project', namespace_id: group.id) }
-
- describe '#down' do
- it 'deletes only group-level configurations' do
- migration.up
-
- project_protections = [
- protected_environments.create!(project_id: project.id, name: 'production'),
- protected_environments.create!(project_id: project.id, name: 'staging')
- ]
- protected_environments.create!(group_id: group.id, name: 'production')
- protected_environments.create!(group_id: group.id, name: 'staging')
-
- migration.down
-
- expect(protected_environments.pluck(:id))
- .to match_array project_protections.map(&:id)
- end
- end
-end
diff --git a/spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb b/spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb
index 604504d2206..0f202129e82 100644
--- a/spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb
+++ b/spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb
@@ -3,7 +3,8 @@
require 'spec_helper'
require_migration!
-RSpec.describe RescheduleMergeRequestDiffUsersBackgroundMigration, :migration, feature_category: :code_review do
+RSpec.describe RescheduleMergeRequestDiffUsersBackgroundMigration,
+ :migration, feature_category: :code_review_workflow do
let(:migration) { described_class.new }
describe '#up' do
diff --git a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb b/spec/migrations/20210804150320_create_base_work_item_types_spec.rb
index 5626b885626..e7f76eb0ae0 100644
--- a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb
+++ b/spec/migrations/20210804150320_create_base_work_item_types_spec.rb
@@ -17,7 +17,8 @@ RSpec.describe CreateBaseWorkItemTypes, :migration, feature_category: :team_plan
}
end
- after(:all) do
+ # We use append_after to make sure this runs after the schema was reset to its latest state
+ append_after(:all) do
# Make sure base types are recreated after running the migration
# because migration specs are not run in a transaction
reset_work_item_types
diff --git a/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb b/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb
index 2a19dc025a7..4c7ef9ac1e8 100644
--- a/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb
+++ b/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe UpsertBaseWorkItemTypes, :migration, feature_category: :team_plan
}
end
- after(:all) do
+ append_after(:all) do
# Make sure base types are recreated after running the migration
# because migration specs are not run in a transaction
reset_work_item_types
diff --git a/spec/migrations/20211012134316_clean_up_migrate_merge_request_diff_commit_users_spec.rb b/spec/migrations/20211012134316_clean_up_migrate_merge_request_diff_commit_users_spec.rb
index f627ea825b3..a61e450d9ab 100644
--- a/spec/migrations/20211012134316_clean_up_migrate_merge_request_diff_commit_users_spec.rb
+++ b/spec/migrations/20211012134316_clean_up_migrate_merge_request_diff_commit_users_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration! 'clean_up_migrate_merge_request_diff_commit_users'
-RSpec.describe CleanUpMigrateMergeRequestDiffCommitUsers, :migration, feature_category: :code_review do
+RSpec.describe CleanUpMigrateMergeRequestDiffCommitUsers, :migration, feature_category: :code_review_workflow do
describe '#up' do
context 'when there are pending jobs' do
it 'processes the jobs immediately' do
diff --git a/spec/migrations/20211028155449_schedule_fix_merge_request_diff_commit_users_migration_spec.rb b/spec/migrations/20211028155449_schedule_fix_merge_request_diff_commit_users_migration_spec.rb
index c7a0b938ca1..968d9cf176c 100644
--- a/spec/migrations/20211028155449_schedule_fix_merge_request_diff_commit_users_migration_spec.rb
+++ b/spec/migrations/20211028155449_schedule_fix_merge_request_diff_commit_users_migration_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration! 'schedule_fix_merge_request_diff_commit_users_migration'
-RSpec.describe ScheduleFixMergeRequestDiffCommitUsersMigration, :migration, feature_category: :code_review do
+RSpec.describe ScheduleFixMergeRequestDiffCommitUsersMigration, :migration, feature_category: :code_review_workflow do
let(:migration) { described_class.new }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
diff --git a/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb b/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb
index 32edd3615ff..db68e895b61 100644
--- a/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb
+++ b/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe AddTaskToWorkItemTypes, :migration, feature_category: :team_plann
}
end
- after(:all) do
+ append_after(:all) do
# Make sure base types are recreated after running the migration
# because migration specs are not run in a transaction
reset_work_item_types
diff --git a/spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb b/spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb
index 1760535e66f..85fe3d712a2 100644
--- a/spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb
+++ b/spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe CleanupDraftDataFromFaultyRegex, feature_category: :code_review do
+RSpec.describe CleanupDraftDataFromFaultyRegex, feature_category: :code_review_workflow do
let(:merge_requests) { table(:merge_requests) }
let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
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 e316ad25214..47d407618d2 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
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration! 'clean_up_fix_merge_request_diff_commit_users'
-RSpec.describe CleanUpFixMergeRequestDiffCommitUsers, :migration, feature_category: :code_review do
+RSpec.describe CleanUpFixMergeRequestDiffCommitUsers, :migration, feature_category: :code_review_workflow do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:project_namespace) { namespaces.create!(name: 'project2', path: 'project2', type: 'Project') }
diff --git a/spec/migrations/20221018050323_add_objective_and_keyresult_to_work_item_types_spec.rb b/spec/migrations/20221018050323_add_objective_and_keyresult_to_work_item_types_spec.rb
index 3ab33367303..6284608becb 100644
--- a/spec/migrations/20221018050323_add_objective_and_keyresult_to_work_item_types_spec.rb
+++ b/spec/migrations/20221018050323_add_objective_and_keyresult_to_work_item_types_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe AddObjectiveAndKeyresultToWorkItemTypes, :migration, feature_cate
}
end
- after(:all) do
+ append_after(:all) do
# Make sure base types are recreated after running the migration
# because migration specs are not run in a transaction
reset_work_item_types
diff --git a/spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb b/spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb
new file mode 100644
index 00000000000..da6532a822a
--- /dev/null
+++ b/spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CleanupOAuthAccessTokensWithNullExpiresIn, feature_category: :authentication_and_authorization do
+ let(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules background jobs for each batch of oauth_access_tokens' 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: :oauth_access_tokens,
+ column_name: :id,
+ interval: described_class::INTERVAL
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb b/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb
new file mode 100644
index 00000000000..d7aa53ec35b
--- /dev/null
+++ b/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleBackfillReleasesAuthorId, feature_category: :release_orchestration do
+ context 'when there are releases without author' do
+ let(:releases_table) { table(:releases) }
+ let(:user_table) { table(:users) }
+ let(:date_time) { DateTime.now }
+ let!(:batched_migration) { described_class::MIGRATION }
+ let!(:test_user) do
+ user_table.create!(name: 'test',
+ email: 'test@example.com',
+ username: 'test',
+ projects_limit: 10)
+ end
+
+ before do
+ releases_table.create!(tag: 'tag1', name: 'tag1',
+ released_at: (date_time - 1.minute), author_id: test_user.id)
+ releases_table.create!(tag: 'tag2', name: 'tag2',
+ released_at: (date_time - 2.minutes), author_id: test_user.id)
+ releases_table.new(tag: 'tag3', name: 'tag3',
+ released_at: (date_time - 3.minutes), author_id: nil).save!(validate: false)
+ releases_table.new(tag: 'tag4', name: 'tag4',
+ released_at: (date_time - 4.minutes), author_id: nil).save!(validate: false)
+ end
+
+ 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: :releases,
+ column_name: :id,
+ interval: described_class::JOB_DELAY_INTERVAL,
+ job_arguments: [User.find_by(user_type: :ghost)&.id]
+ )
+ }
+ end
+ end
+ end
+
+ context 'when there are no releases without author' do
+ it 'does not schedule batched migration' do
+ expect(described_class.new.up).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/20221220131020_bump_default_partition_id_value_for_ci_tables_spec.rb b/spec/migrations/20221220131020_bump_default_partition_id_value_for_ci_tables_spec.rb
new file mode 100644
index 00000000000..c4bd243e79f
--- /dev/null
+++ b/spec/migrations/20221220131020_bump_default_partition_id_value_for_ci_tables_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe BumpDefaultPartitionIdValueForCiTables, :migration, feature_category: :continuous_integration do
+ context 'when on sass' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ it 'changes default values' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(default_values).not_to include(101)
+ }
+
+ migration.after -> {
+ expect(default_values).to match_array([101])
+ }
+ end
+ end
+
+ context 'with tables already changed' do
+ before do
+ active_record_base.connection.execute(<<~SQL)
+ ALTER TABLE ci_builds ALTER COLUMN partition_id SET DEFAULT 101
+ SQL
+ end
+
+ after do
+ schema_migrate_down!
+ end
+
+ let(:alter_query) do
+ /ALTER TABLE "ci_builds" ALTER COLUMN "partition_id" SET DEFAULT 101/
+ end
+
+ it 'skips updating already changed tables' do
+ recorder = ActiveRecord::QueryRecorder.new { migrate! }
+
+ expect(recorder.log.any?(alter_query)).to be_falsey
+ expect(default_values).to match_array([101])
+ end
+ end
+ end
+
+ context 'when self-managed' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(false)
+ end
+
+ it 'does not change default values' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(default_values).not_to include(101)
+ }
+
+ migration.after -> {
+ expect(default_values).not_to include(101)
+ }
+ end
+ end
+ end
+
+ def default_values
+ values = described_class::TABLES.flat_map do |table_name, columns|
+ active_record_base
+ .connection
+ .columns(table_name)
+ .select { |column| columns.include?(column.name.to_sym) }
+ .map { |column| column.default&.to_i }
+ end
+
+ values.uniq
+ end
+end
diff --git a/spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb b/spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb
new file mode 100644
index 00000000000..6f9cfe4764a
--- /dev/null
+++ b/spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveTempIndexForProjectStatisticsUploadSizeMigration,
+feature_category: :subscription_cost_management do
+ let(:table_name) { 'project_statistics' }
+ let(:index_name) { described_class::INDEX_NAME }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy
+ }
+
+ migration.after -> {
+ expect(subject.index_exists_by_name?(table_name, index_name)).to be_falsy
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20221222092958_sync_new_amount_used_with_amount_used_spec.rb b/spec/migrations/20221222092958_sync_new_amount_used_with_amount_used_spec.rb
new file mode 100644
index 00000000000..158560a2432
--- /dev/null
+++ b/spec/migrations/20221222092958_sync_new_amount_used_with_amount_used_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe SyncNewAmountUsedWithAmountUsed, migration: :gitlab_ci, feature_category: :continuous_integration do
+ let(:project_usages) { table(:ci_project_monthly_usages) }
+ let(:migration) { described_class.new }
+
+ before do
+ # Disabling the trigger temporarily to allow records being created with out-of-sync
+ # `new_amount_used` and `amount_used`. This will simulate existing records before
+ # we add the trigger.
+ ActiveRecord::Base.connection
+ .execute("ALTER TABLE ci_project_monthly_usages DISABLE TRIGGER sync_projects_amount_used_columns")
+
+ this_month = Time.now.utc.beginning_of_month
+ last_month = 1.month.ago.utc.beginning_of_month
+ last_year = 1.year.ago.utc.beginning_of_month
+
+ project_usages.create!(project_id: 1, date: last_year)
+ project_usages.create!(project_id: 1, date: this_month, amount_used: 10, new_amount_used: 0)
+ project_usages.create!(project_id: 1, date: last_month, amount_used: 20, new_amount_used: 0)
+
+ project_usages.create!(project_id: 2, date: last_year)
+ project_usages.create!(project_id: 2, date: this_month, amount_used: 30, new_amount_used: 0)
+ project_usages.create!(project_id: 2, date: last_month, amount_used: 40, new_amount_used: 0)
+
+ ActiveRecord::Base.connection
+ .execute("ALTER TABLE ci_project_monthly_usages ENABLE TRIGGER sync_projects_amount_used_columns")
+ end
+
+ describe '#up' do
+ it "doesnt change new_amount_used values" do
+ data = project_usages.all
+ data.each do |item|
+ expect { migration.up }.to not_change { item.new_amount_used }
+ end
+ end
+ end
+
+ describe '#down' do
+ it 'updates `new_amount_used` with values from `amount_used`' do
+ expect(project_usages.where(new_amount_used: 0).count).to eq(6)
+
+ migration.down
+
+ expect(project_usages.where(new_amount_used: 0).count).to eq(2)
+ expect(project_usages.order(:id).pluck(:new_amount_used))
+ .to contain_exactly(0, 0, 10, 20, 30, 40)
+ end
+ end
+end
diff --git a/spec/migrations/20221223123019_delete_queued_jobs_for_vulnerabilities_feedback_migration_spec.rb b/spec/migrations/20221223123019_delete_queued_jobs_for_vulnerabilities_feedback_migration_spec.rb
new file mode 100644
index 00000000000..c5e1a255653
--- /dev/null
+++ b/spec/migrations/20221223123019_delete_queued_jobs_for_vulnerabilities_feedback_migration_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DeleteQueuedJobsForVulnerabilitiesFeedbackMigration, feature_category: :vulnerability_management do
+ let!(:migration) { described_class.new }
+ let(:batched_background_migrations) { table(:batched_background_migrations) }
+
+ before do
+ batched_background_migrations.create!(
+ max_value: 10,
+ batch_size: 250,
+ sub_batch_size: 50,
+ interval: 300,
+ job_class_name: 'MigrateVulnerabilitiesFeedbackToVulnerabilitiesStateTransition',
+ table_name: 'vulnerability_feedback',
+ column_name: 'id',
+ job_arguments: [],
+ gitlab_schema: "gitlab_main"
+ )
+ end
+
+ describe "#up" do
+ it "deletes all batched migration records" do
+ expect(batched_background_migrations.count).to eq(1)
+
+ migration.up
+
+ expect(batched_background_migrations.count).to eq(0)
+ end
+ end
+end
diff --git a/spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb b/spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb
new file mode 100644
index 00000000000..aa82ca2661b
--- /dev/null
+++ b/spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe SyncNewAmountUsedWithAmountUsedOnCiNamespaceMonthlyUsagesTable, migration: :gitlab_ci,
+feature_category: :continuous_integration do
+ let(:namespace_usages) { table(:ci_namespace_monthly_usages) }
+ let(:migration) { described_class.new }
+
+ before do
+ # Disabling the trigger temporarily to allow records being created with out-of-sync
+ # `new_amount_used` and `amount_used`. This will simulate existing records before
+ # we add the trigger.
+ ActiveRecord::Base.connection
+ .execute("ALTER TABLE ci_namespace_monthly_usages DISABLE TRIGGER sync_namespaces_amount_used_columns")
+
+ this_month = Time.now.utc.beginning_of_month
+ last_month = 1.month.ago.utc.beginning_of_month
+ last_year = 1.year.ago.utc.beginning_of_month
+
+ namespace_usages.create!(namespace_id: 1, date: last_year)
+ namespace_usages.create!(namespace_id: 1, date: this_month, amount_used: 10, new_amount_used: 0)
+ namespace_usages.create!(namespace_id: 1, date: last_month, amount_used: 20, new_amount_used: 0)
+
+ namespace_usages.create!(namespace_id: 2, date: last_year)
+ namespace_usages.create!(namespace_id: 2, date: this_month, amount_used: 30, new_amount_used: 0)
+ namespace_usages.create!(namespace_id: 2, date: last_month, amount_used: 40, new_amount_used: 0)
+
+ ActiveRecord::Base.connection
+ .execute("ALTER TABLE ci_namespace_monthly_usages ENABLE TRIGGER sync_namespaces_amount_used_columns")
+ end
+
+ describe '#up' do
+ it "doesnt change new_amount_used values" do
+ data = namespace_usages.all
+ data.each do |item|
+ expect { migration.up }.to not_change { item.new_amount_used }
+ end
+ end
+ end
+
+ describe '#down' do
+ it 'updates `new_amount_used` with values from `amount_used`' do
+ expect(namespace_usages.where(new_amount_used: 0).count).to eq(6)
+
+ migration.down
+
+ expect(namespace_usages.where(new_amount_used: 0).count).to eq(2)
+ expect(namespace_usages.order(:id).pluck(:new_amount_used))
+ .to contain_exactly(0, 0, 10, 20, 30, 40)
+ end
+ end
+end
diff --git a/spec/migrations/20230116111252_finalize_todo_sanitization_spec.rb b/spec/migrations/20230116111252_finalize_todo_sanitization_spec.rb
new file mode 100644
index 00000000000..cd7828bbae4
--- /dev/null
+++ b/spec/migrations/20230116111252_finalize_todo_sanitization_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FinalizeTodoSanitization, :migration, feature_category: :portfolio_management do
+ let(:batched_migrations) { table(:batched_background_migrations) }
+
+ let!(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ let!(:sanitize_todos_migration) do
+ batched_migrations.create!(
+ job_class_name: 'SanitizeConfidentialTodos',
+ table_name: :notes,
+ 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 migration finished successfully' do
+ it 'does not raise exception' do
+ expect { migrate! }.not_to raise_error
+ end
+ end
+
+ context 'with different 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
+ sanitize_todos_migration.update!(status: status)
+ end
+
+ it 'finalizes the migration' do
+ allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
+ expect(runner).to receive(:finalize).with('SanitizeConfidentialTodos', :members, :id, [])
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/add_new_trail_plans_spec.rb b/spec/migrations/add_new_trail_plans_spec.rb
deleted file mode 100644
index 6f8de8435c6..00000000000
--- a/spec/migrations/add_new_trail_plans_spec.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe AddNewTrailPlans, :migration, feature_category: :purchase do
- describe '#up' do
- before do
- allow(Gitlab).to receive(:com?).and_return true
- end
-
- it 'creates 2 entries within the plans table' do
- expect { migrate! }.to change { AddNewTrailPlans::Plan.count }.by 2
- expect(AddNewTrailPlans::Plan.last(2).pluck(:name)).to match_array(%w(ultimate_trial premium_trial))
- end
-
- it 'creates 2 entries for plan limits' do
- expect { migrate! }.to change { AddNewTrailPlans::PlanLimits.count }.by 2
- end
-
- context 'when the plan limits for gold and silver exists' do
- before do
- table(:plans).create!(id: 1, name: 'gold', title: 'Gold')
- table(:plan_limits).create!(id: 1, plan_id: 1, storage_size_limit: 2000)
- table(:plans).create!(id: 2, name: 'silver', title: 'Silver')
- table(:plan_limits).create!(id: 2, plan_id: 2, storage_size_limit: 1000)
- end
-
- it 'duplicates the gold and silvers plan limits entries' do
- migrate!
-
- ultimate_plan_limits = AddNewTrailPlans::Plan.find_by(name: 'ultimate_trial').limits
- expect(ultimate_plan_limits.storage_size_limit).to be 2000
-
- premium_plan_limits = AddNewTrailPlans::Plan.find_by(name: 'premium_trial').limits
- expect(premium_plan_limits.storage_size_limit).to be 1000
- end
- end
-
- context 'when the instance is not SaaS' do
- before do
- allow(Gitlab).to receive(:com?).and_return false
- end
-
- it 'does not create plans and plan limits and returns' do
- expect { migrate! }.not_to change { AddNewTrailPlans::Plan.count }
- expect { migrate! }.not_to change { AddNewTrailPlans::Plan.count }
- end
- end
- end
-
- describe '#down' do
- before do
- table(:plans).create!(id: 3, name: 'other')
- table(:plan_limits).create!(plan_id: 3)
- end
-
- context 'when the instance is SaaS' do
- before do
- allow(Gitlab).to receive(:com?).and_return true
- end
-
- it 'removes the newly added ultimate and premium trial entries' do
- migrate!
-
- expect { described_class.new.down }.to change { AddNewTrailPlans::Plan.count }.by(-2)
- expect(AddNewTrailPlans::Plan.find_by(name: 'premium_trial')).to be_nil
- expect(AddNewTrailPlans::Plan.find_by(name: 'ultimate_trial')).to be_nil
-
- other_plan = AddNewTrailPlans::Plan.find_by(name: 'other')
- expect(other_plan).to be_persisted
- expect(AddNewTrailPlans::PlanLimits.count).to eq(1)
- expect(AddNewTrailPlans::PlanLimits.first.plan_id).to eq(other_plan.id)
- end
- end
-
- context 'when the instance is not SaaS' do
- before do
- allow(Gitlab).to receive(:com?).and_return false
- table(:plans).create!(id: 1, name: 'ultimate_trial', title: 'Ultimate Trial')
- table(:plans).create!(id: 2, name: 'premium_trial', title: 'Premium Trial')
- table(:plan_limits).create!(id: 1, plan_id: 1)
- table(:plan_limits).create!(id: 2, plan_id: 2)
- end
-
- it 'does not delete plans and plan limits and returns' do
- migrate!
-
- expect { described_class.new.down }.not_to change { AddNewTrailPlans::Plan.count }
- expect(AddNewTrailPlans::PlanLimits.count).to eq(3)
- end
- end
- end
-end
diff --git a/spec/migrations/backfill_clusters_integration_prometheus_enabled_spec.rb b/spec/migrations/backfill_clusters_integration_prometheus_enabled_spec.rb
deleted file mode 100644
index 1c7745a64ef..00000000000
--- a/spec/migrations/backfill_clusters_integration_prometheus_enabled_spec.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe BackfillClustersIntegrationPrometheusEnabled, :migration, feature_category: :clusters_applications_prometheus do
- def create_cluster!(label = rand(2**64).to_s)
- table(:clusters).create!(
- name: "cluster: #{label}",
- created_at: 1.day.ago,
- updated_at: 1.day.ago
- )
- end
-
- def create_clusters_applications_prometheus!(label, status:, cluster_id: nil)
- table(:clusters_applications_prometheus).create!(
- cluster_id: cluster_id || create_cluster!(label).id,
- status: status,
- version: "#{label}: version",
- created_at: 1.day.ago, # artificially aged
- updated_at: 1.day.ago, # artificially aged
- encrypted_alert_manager_token: "#{label}: token",
- encrypted_alert_manager_token_iv: "#{label}: iv"
- )
- end
-
- def create_clusters_integration_prometheus!
- table(:clusters_integration_prometheus).create!(
- cluster_id: create_cluster!.id,
- enabled: false,
- created_at: 1.day.ago,
- updated_at: 1.day.ago
- )
- end
-
- RSpec::Matchers.define :be_enabled_and_match_application_values do |application|
- match do |actual|
- actual.enabled == true &&
- actual.encrypted_alert_manager_token == application.encrypted_alert_manager_token &&
- actual.encrypted_alert_manager_token_iv == application.encrypted_alert_manager_token_iv
- end
- end
-
- describe '#up' do
- it 'backfills the enabled status and alert manager credentials from clusters_applications_prometheus' do
- status_installed = 3
- status_externally_installed = 11
- status_installable = 0
-
- existing_integration = create_clusters_integration_prometheus!
- unaffected_existing_integration = create_clusters_integration_prometheus!
- app_installed = create_clusters_applications_prometheus!('installed', status: status_installed)
- app_installed_existing_integration = create_clusters_applications_prometheus!('installed, existing integration', status: status_installed, cluster_id: existing_integration.cluster_id)
- app_externally_installed = create_clusters_applications_prometheus!('externally installed', status: status_externally_installed)
- app_other_status = create_clusters_applications_prometheus!('other status', status: status_installable)
-
- migrate!
-
- integrations = table(:clusters_integration_prometheus).all.index_by(&:cluster_id)
-
- expect(unaffected_existing_integration.reload).to eq unaffected_existing_integration
-
- integration_installed = integrations[app_installed.cluster_id]
- expect(integration_installed).to be_enabled_and_match_application_values(app_installed)
- expect(integration_installed.updated_at).to be >= 1.minute.ago # recently updated
- expect(integration_installed.updated_at).to eq(integration_installed.created_at) # recently created
-
- expect(existing_integration.reload).to be_enabled_and_match_application_values(app_installed_existing_integration)
- expect(existing_integration.updated_at).to be >= 1.minute.ago # recently updated
- expect(existing_integration.updated_at).not_to eq(existing_integration.created_at) # but not recently created
-
- integration_externally_installed = integrations[app_externally_installed.cluster_id]
- expect(integration_externally_installed).to be_enabled_and_match_application_values(app_externally_installed)
- expect(integration_externally_installed.updated_at).to be >= 1.minute.ago # recently updated
- expect(integration_externally_installed.updated_at).to eq(integration_externally_installed.created_at) # recently created
-
- expect(integrations[app_other_status.cluster_id]).to be_nil
- end
- end
-end
diff --git a/spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb b/spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb
deleted file mode 100644
index aa77a5c228a..00000000000
--- a/spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb
+++ /dev/null
@@ -1,103 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe BackfillEscalationPoliciesForOncallSchedules, feature_category: :incident_management do
- let!(:projects) { table(:projects) }
- let!(:schedules) { table(:incident_management_oncall_schedules) }
- let!(:policies) { table(:incident_management_escalation_policies) }
- let!(:rules) { table(:incident_management_escalation_rules) }
-
- # Project with no schedules
- let!(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab') }
- let!(:project_a) { projects.create!(namespace_id: namespace.id) }
-
- context 'with backfill-able schedules' do
- # Project with one schedule
- let!(:project_b) { projects.create!(namespace_id: namespace.id) }
- let!(:schedule_b1) { schedules.create!(project_id: project_b.id, iid: 1, name: 'Schedule B1') }
-
- # Project with multiple schedules
- let!(:project_c) { projects.create!(namespace_id: namespace.id) }
- let!(:schedule_c1) { schedules.create!(project_id: project_c.id, iid: 1, name: 'Schedule C1') }
- let!(:schedule_c2) { schedules.create!(project_id: project_c.id, iid: 2, name: 'Schedule C2') }
-
- # Project with a single schedule which already has a policy
- let!(:project_d) { projects.create!(namespace_id: namespace.id) }
- let!(:schedule_d1) { schedules.create!(project_id: project_d.id, iid: 1, name: 'Schedule D1') }
- let!(:policy_d1) { policies.create!(project_id: project_d.id, name: 'Policy D1') }
- let!(:rule_d1) { rules.create!(policy_id: policy_d1.id, oncall_schedule_id: schedule_d1.id, status: 2, elapsed_time_seconds: 60) }
-
- # Project with a multiple schedule, one of which already has a policy
- let!(:project_e) { projects.create!(namespace_id: namespace.id) }
- let!(:schedule_e1) { schedules.create!(project_id: project_e.id, iid: 1, name: 'Schedule E1') }
- let!(:schedule_e2) { schedules.create!(project_id: project_e.id, iid: 2, name: 'Schedule E2') }
- let!(:policy_e1) { policies.create!(project_id: project_e.id, name: 'Policy E1') }
- let!(:rule_e1) { rules.create!(policy_id: policy_e1.id, oncall_schedule_id: schedule_e2.id, status: 2, elapsed_time_seconds: 60) }
-
- # Project with a multiple schedule, with multiple policies
- let!(:project_f) { projects.create!(namespace_id: namespace.id) }
- let!(:schedule_f1) { schedules.create!(project_id: project_f.id, iid: 1, name: 'Schedule F1') }
- let!(:schedule_f2) { schedules.create!(project_id: project_f.id, iid: 2, name: 'Schedule F2') }
- let!(:policy_f1) { policies.create!(project_id: project_f.id, name: 'Policy F1') }
- let!(:rule_f1) { rules.create!(policy_id: policy_f1.id, oncall_schedule_id: schedule_f1.id, status: 2, elapsed_time_seconds: 60) }
- let!(:rule_f2) { rules.create!(policy_id: policy_f1.id, oncall_schedule_id: schedule_f2.id, status: 2, elapsed_time_seconds: 60) }
- let!(:policy_f2) { policies.create!(project_id: project_f.id, name: 'Policy F2') }
- let!(:rule_f3) { rules.create!(policy_id: policy_f2.id, oncall_schedule_id: schedule_f2.id, status: 1, elapsed_time_seconds: 10) }
-
- it 'backfills escalation policies correctly' do
- expect { migrate! }
- .to change(policies, :count).by(2)
- .and change(rules, :count).by(3)
-
- new_policy_b1, new_policy_c1 = new_polices = policies.last(2)
- new_rules = rules.last(3)
-
- expect(new_polices).to all have_attributes(name: 'On-call Escalation Policy')
- expect(new_policy_b1.description).to eq('Immediately notify Schedule B1')
- expect(new_policy_c1.description).to eq('Immediately notify Schedule C1')
- expect(policies.pluck(:project_id)).to eq(
- [
- project_d.id,
- project_e.id,
- project_f.id,
- project_f.id,
- project_b.id,
- project_c.id
- ])
-
- expect(new_rules).to all have_attributes(status: 1, elapsed_time_seconds: 0)
- expect(rules.pluck(:policy_id)).to eq(
- [
- rule_d1.policy_id,
- rule_e1.policy_id,
- rule_f1.policy_id,
- rule_f2.policy_id,
- rule_f3.policy_id,
- new_policy_b1.id,
- new_policy_c1.id,
- new_policy_c1.id
- ])
- expect(rules.pluck(:oncall_schedule_id)).to eq(
- [
- rule_d1.oncall_schedule_id,
- rule_e1.oncall_schedule_id,
- rule_f1.oncall_schedule_id,
- rule_f2.oncall_schedule_id,
- rule_f3.oncall_schedule_id,
- schedule_b1.id,
- schedule_c1.id,
- schedule_c2.id
- ])
- end
- end
-
- context 'with no schedules' do
- it 'does nothing' do
- expect { migrate! }
- .to not_change(policies, :count)
- .and not_change(rules, :count)
- end
- end
-end
diff --git a/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb b/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb
deleted file mode 100644
index ae2656eaf98..00000000000
--- a/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe BackfillNugetTemporaryPackagesToProcessingStatus, :migration, feature_category: :package_registry do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:packages) { table(:packages_packages) }
-
- before do
- namespace = namespaces.create!(id: 123, name: 'test_namespace', path: 'test_namespace')
- project = projects.create!(id: 111, name: 'sample_project', path: 'sample_project', namespace_id: namespace.id)
-
- packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 4, status: 0, project_id: project.id)
- packages.create!(name: 'foo', version: '0.1.1', package_type: 4, status: 0, project_id: project.id)
- packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 4, status: 2, project_id: project.id)
- packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 1, status: 2, project_id: project.id)
- packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 1, status: 0, project_id: project.id)
- end
-
- it 'updates the applicable packages to processing status', :aggregate_failures do
- expect(packages.where(status: 0).count).to eq(3)
- expect(packages.where(status: 2).count).to eq(2)
- expect(packages.where(name: 'NuGet.Temporary.Package', package_type: 4, status: 0).count).to eq(1)
-
- migrate!
-
- expect(packages.where(status: 0).count).to eq(2)
- expect(packages.where(status: 2).count).to eq(3)
- expect(packages.where(name: 'NuGet.Temporary.Package', package_type: 4, status: 0).count).to eq(0)
- end
-end
diff --git a/spec/migrations/change_web_hook_events_default_spec.rb b/spec/migrations/change_web_hook_events_default_spec.rb
deleted file mode 100644
index c6c3f285ff1..00000000000
--- a/spec/migrations/change_web_hook_events_default_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ChangeWebHookEventsDefault, feature_category: :integrations do
- let(:web_hooks) { table(:web_hooks) }
- let(:projects) { table(:projects) }
- let(:groups) { table(:namespaces) }
-
- let(:group) { groups.create!(name: 'gitlab', path: 'gitlab-org') }
- let(:project) { projects.create!(name: 'gitlab', path: 'gitlab', namespace_id: group.id) }
- let(:hook) { web_hooks.create!(project_id: project.id, type: 'ProjectHook') }
- let(:group_hook) { web_hooks.create!(group_id: group.id, type: 'GroupHook') }
-
- before do
- # Simulate the wrong schema
- %w(push_events issues_events merge_requests_events tag_push_events).each do |column|
- ActiveRecord::Base.connection.execute "ALTER TABLE web_hooks ALTER COLUMN #{column} DROP DEFAULT"
- end
- end
-
- it 'sets default values' do
- migrate!
-
- expect(hook.push_events).to be true
- expect(hook.issues_events).to be false
- expect(hook.merge_requests_events).to be false
- expect(hook.tag_push_events).to be false
-
- expect(group_hook.push_events).to be true
- expect(group_hook.issues_events).to be false
- expect(group_hook.merge_requests_events).to be false
- expect(group_hook.tag_push_events).to be false
- end
-end
diff --git a/spec/migrations/clean_up_pending_builds_table_spec.rb b/spec/migrations/clean_up_pending_builds_table_spec.rb
deleted file mode 100644
index e044d4a702b..00000000000
--- a/spec/migrations/clean_up_pending_builds_table_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe CleanUpPendingBuildsTable, :suppress_gitlab_schemas_validate_connection,
-feature_category: :continuous_integration do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:queue) { table(:ci_pending_builds) }
- let(:builds) { table(:ci_builds) }
-
- before do
- namespaces.create!(id: 123, name: 'sample', path: 'sample')
- projects.create!(id: 123, name: 'sample', path: 'sample', namespace_id: 123)
-
- builds.create!(id: 1, project_id: 123, status: 'pending', type: 'Ci::Build')
- builds.create!(id: 2, project_id: 123, status: 'pending', type: 'GenericCommitStatus')
- builds.create!(id: 3, project_id: 123, status: 'success', type: 'Ci::Bridge')
- builds.create!(id: 4, project_id: 123, status: 'success', type: 'Ci::Build')
- builds.create!(id: 5, project_id: 123, status: 'running', type: 'Ci::Build')
- builds.create!(id: 6, project_id: 123, status: 'created', type: 'Ci::Build')
-
- queue.create!(id: 1, project_id: 123, build_id: 1)
- queue.create!(id: 2, project_id: 123, build_id: 4)
- queue.create!(id: 3, project_id: 123, build_id: 5)
- end
-
- it 'removes duplicated data from pending builds table' do
- migrate!
-
- expect(queue.all.count).to eq 1
- expect(queue.first.id).to eq 1
- expect(builds.all.count).to eq 6
- end
-
- context 'when there are multiple batches' do
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- end
-
- it 'iterates the data correctly' do
- migrate!
-
- expect(queue.all.count).to eq 1
- end
- end
-end
diff --git a/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb b/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb
deleted file mode 100644
index 6027199c11c..00000000000
--- a/spec/migrations/cleanup_after_add_primary_email_to_emails_if_user_confirmed_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe CleanupAfterAddPrimaryEmailToEmailsIfUserConfirmed, :sidekiq, feature_category: :users do
- let(:migration) { described_class.new }
- let(:users) { table(:users) }
- let(:emails) { table(:emails) }
-
- 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 'consume any pending background migration job' do
- expect_next_instance_of(Gitlab::BackgroundMigration::JobCoordinator) do |coordinator|
- expect(coordinator).to receive(:steal).with('AddPrimaryEmailToEmailsIfUserConfirmed').twice
- end
-
- migration.up
- end
-
- it 'adds the primary email to emails for leftover confirmed users that do not have their primary email in the 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
-
- 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/cleanup_move_container_registry_enabled_to_project_feature_spec.rb b/spec/migrations/cleanup_move_container_registry_enabled_to_project_feature_spec.rb
deleted file mode 100644
index 1badde62526..00000000000
--- a/spec/migrations/cleanup_move_container_registry_enabled_to_project_feature_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe CleanupMoveContainerRegistryEnabledToProjectFeature, :migration, feature_category: :navigation do
- let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') }
- let(:non_null_project_features) { { pages_access_level: 20 } }
- let(:bg_class_name) { 'MoveContainerRegistryEnabledToProjectFeature' }
-
- let!(:project1) { table(:projects).create!(namespace_id: namespace.id, name: 'project 1', container_registry_enabled: true) }
- let!(:project2) { table(:projects).create!(namespace_id: namespace.id, name: 'project 2', container_registry_enabled: false) }
- let!(:project3) { table(:projects).create!(namespace_id: namespace.id, name: 'project 3', container_registry_enabled: nil) }
-
- let!(:project4) { table(:projects).create!(namespace_id: namespace.id, name: 'project 4', container_registry_enabled: true) }
- let!(:project5) { table(:projects).create!(namespace_id: namespace.id, name: 'project 5', container_registry_enabled: false) }
- let!(:project6) { table(:projects).create!(namespace_id: namespace.id, name: 'project 6', container_registry_enabled: nil) }
-
- let!(:project_feature1) { table(:project_features).create!(project_id: project1.id, container_registry_access_level: 20, **non_null_project_features) }
- let!(:project_feature2) { table(:project_features).create!(project_id: project2.id, container_registry_access_level: 0, **non_null_project_features) }
- let!(:project_feature3) { table(:project_features).create!(project_id: project3.id, container_registry_access_level: 0, **non_null_project_features) }
-
- let!(:project_feature4) { table(:project_features).create!(project_id: project4.id, container_registry_access_level: 0, **non_null_project_features) }
- let!(:project_feature5) { table(:project_features).create!(project_id: project5.id, container_registry_access_level: 20, **non_null_project_features) }
- let!(:project_feature6) { table(:project_features).create!(project_id: project6.id, container_registry_access_level: 20, **non_null_project_features) }
-
- let!(:background_migration_job1) { table(:background_migration_jobs).create!(class_name: bg_class_name, arguments: [project4.id, project5.id], status: 0) }
- let!(:background_migration_job2) { table(:background_migration_jobs).create!(class_name: bg_class_name, arguments: [project6.id, project6.id], status: 0) }
- let!(:background_migration_job3) { table(:background_migration_jobs).create!(class_name: bg_class_name, arguments: [project1.id, project3.id], status: 1) }
-
- it 'steals remaining jobs, updates any remaining rows and deletes background_migration_jobs rows' do
- expect(Gitlab::BackgroundMigration).to receive(:steal).with(bg_class_name).and_call_original
-
- migrate!
-
- expect(project_feature1.reload.container_registry_access_level).to eq(20)
- expect(project_feature2.reload.container_registry_access_level).to eq(0)
- expect(project_feature3.reload.container_registry_access_level).to eq(0)
- expect(project_feature4.reload.container_registry_access_level).to eq(20)
- expect(project_feature5.reload.container_registry_access_level).to eq(0)
- expect(project_feature6.reload.container_registry_access_level).to eq(0)
-
- expect(table(:background_migration_jobs).where(class_name: bg_class_name).count).to eq(0)
- end
-end
diff --git a/spec/migrations/cleanup_mr_attention_request_todos_spec.rb b/spec/migrations/cleanup_mr_attention_request_todos_spec.rb
index 4fa2419aa7c..cea72003ccd 100644
--- a/spec/migrations/cleanup_mr_attention_request_todos_spec.rb
+++ b/spec/migrations/cleanup_mr_attention_request_todos_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe CleanupMrAttentionRequestTodos, :migration, feature_category: :code_review do
+RSpec.describe CleanupMrAttentionRequestTodos, :migration, feature_category: :code_review_workflow do
let(:projects) { table(:projects) }
let(:namespaces) { table(:namespaces) }
let(:users) { table(:users) }
diff --git a/spec/migrations/confirm_support_bot_user_spec.rb b/spec/migrations/confirm_support_bot_user_spec.rb
deleted file mode 100644
index 863bdb13585..00000000000
--- a/spec/migrations/confirm_support_bot_user_spec.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ConfirmSupportBotUser, :migration, feature_category: :users do
- let(:users) { table(:users) }
-
- context 'when support bot user is currently unconfirmed' do
- let!(:support_bot) do
- create_user!(
- created_at: 2.days.ago,
- user_type: User::USER_TYPES['support_bot']
- )
- end
-
- it 'updates the `confirmed_at` attribute' do
- expect { migrate! }.to change { support_bot.reload.confirmed_at }
- end
-
- it 'sets `confirmed_at` to be the same as their `created_at` attribute' do
- migrate!
-
- expect(support_bot.reload.confirmed_at).to eq(support_bot.created_at)
- end
- end
-
- context 'when support bot user is already confirmed' do
- let!(:confirmed_support_bot) do
- create_user!(
- user_type: User::USER_TYPES['support_bot'],
- confirmed_at: 1.day.ago
- )
- end
-
- it 'does not change their `confirmed_at` attribute' do
- expect { migrate! }.not_to change { confirmed_support_bot.reload.confirmed_at }
- end
- end
-
- context 'when support bot user created_at is null' do
- let!(:support_bot) do
- create_user!(
- user_type: User::USER_TYPES['support_bot'],
- confirmed_at: nil,
- record_timestamps: false
- )
- end
-
- it 'updates the `confirmed_at` attribute' do
- expect { migrate! }.to change { support_bot.reload.confirmed_at }.from(nil)
- end
-
- it 'does not change the `created_at` attribute' do
- expect { migrate! }.not_to change { support_bot.reload.created_at }.from(nil)
- end
- end
-
- context 'with human users that are currently unconfirmed' do
- let!(:unconfirmed_human) do
- create_user!(
- name: 'human',
- email: 'human@example.com',
- user_type: nil
- )
- end
-
- it 'does not update their `confirmed_at` attribute' do
- expect { migrate! }.not_to change { unconfirmed_human.reload.confirmed_at }
- end
- end
-
- private
-
- def create_user!(user_type:, name: 'GitLab Support Bot', email: 'support@example.com', created_at: Time.now, confirmed_at: nil, record_timestamps: true)
- users.create!(
- name: name,
- email: email,
- username: name,
- projects_limit: 0,
- user_type: user_type,
- confirmed_at: confirmed_at,
- record_timestamps: record_timestamps
- )
- end
-end
diff --git a/spec/migrations/delete_security_findings_without_uuid_spec.rb b/spec/migrations/delete_security_findings_without_uuid_spec.rb
deleted file mode 100644
index e4c17288384..00000000000
--- a/spec/migrations/delete_security_findings_without_uuid_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DeleteSecurityFindingsWithoutUuid, :suppress_gitlab_schemas_validate_connection,
-feature_category: :vulnerability_management do
- let(:users) { table(:users) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:ci_pipelines) { table(:ci_pipelines) }
- let(:ci_builds) { table(:ci_builds) }
- let(:ci_artifacts) { table(:ci_job_artifacts) }
- let(:scanners) { table(:vulnerability_scanners) }
- let(:security_scans) { table(:security_scans) }
- let(:security_findings) { table(:security_findings) }
- let(:sast_file_type) { 5 }
- let(:sast_scan_type) { 1 }
-
- let(:user) { users.create!(email: 'test@gitlab.com', projects_limit: 5) }
- let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
- let(:project) { projects.create!(namespace_id: namespace.id, name: 'foo') }
- let(:ci_pipeline) { ci_pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success') }
- let(:ci_build) { ci_builds.create!(commit_id: ci_pipeline.id, retried: false, type: 'Ci::Build') }
- let(:ci_artifact) { ci_artifacts.create!(project_id: project.id, job_id: ci_build.id, file_type: sast_file_type, file_format: 1) }
- let(:scanner) { scanners.create!(project_id: project.id, external_id: 'bandit', name: 'Bandit') }
- let(:security_scan) { security_scans.create!(build_id: ci_build.id, scan_type: sast_scan_type) }
-
- let!(:finding_1) { security_findings.create!(scan_id: security_scan.id, scanner_id: scanner.id, severity: 0, confidence: 0, project_fingerprint: Digest::SHA1.hexdigest(SecureRandom.uuid)) }
- let!(:finding_2) { security_findings.create!(scan_id: security_scan.id, scanner_id: scanner.id, severity: 0, confidence: 0, project_fingerprint: Digest::SHA1.hexdigest(SecureRandom.uuid), uuid: SecureRandom.uuid) }
-
- it 'successfully runs and does not schedule any job' do
- expect { migrate! }.to change { described_class::SecurityFinding.count }.by(-1)
- .and change { described_class::SecurityFinding.where(id: finding_1) }
- 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
deleted file mode 100644
index 9358b71132c..00000000000
--- a/spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe InsertCiDailyPipelineScheduleTriggersPlanLimits, feature_category: :purchase do
- let!(:plans) { table(:plans) }
- let!(: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') }
-
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
-
- plan_limits.create!(plan_id: free_plan.id)
- plan_limits.create!(plan_id: bronze_plan.id)
- plan_limits.create!(plan_id: silver_plan.id)
- plan_limits.create!(plan_id: gold_plan.id)
- end
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(plan_limits.pluck(:plan_id, :ci_daily_pipeline_schedule_triggers)).to contain_exactly(
- [free_plan.id, 0],
- [bronze_plan.id, 0],
- [silver_plan.id, 0],
- [gold_plan.id, 0]
- )
- }
-
- migration.after -> {
- expect(plan_limits.pluck(:plan_id, :ci_daily_pipeline_schedule_triggers)).to contain_exactly(
- [free_plan.id, 24],
- [bronze_plan.id, 288],
- [silver_plan.id, 288],
- [gold_plan.id, 288]
- )
- }
- 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, :ci_daily_pipeline_schedule_triggers)).to contain_exactly(
- [default_plan.id, 0]
- )
- }
-
- migration.after -> {
- expect(plan_limits.pluck(:plan_id, :ci_daily_pipeline_schedule_triggers)).to contain_exactly(
- [default_plan.id, 0]
- )
- }
- end
- end
- end
-end
diff --git a/spec/migrations/migrate_elastic_index_settings_spec.rb b/spec/migrations/migrate_elastic_index_settings_spec.rb
deleted file mode 100644
index b67c4d902c7..00000000000
--- a/spec/migrations/migrate_elastic_index_settings_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe MigrateElasticIndexSettings, feature_category: :global_search do
- let(:elastic_index_settings) { table(:elastic_index_settings) }
- let(:application_settings) { table(:application_settings) }
-
- context 'with application_settings present' do
- before do
- application_settings.create!(elasticsearch_replicas: 2, elasticsearch_shards: 15)
- end
-
- it 'migrates settings' do
- migrate!
-
- settings = elastic_index_settings.all
-
- expect(settings.size).to eq 1
-
- setting = settings.first
-
- expect(setting.number_of_replicas).to eq(2)
- expect(setting.number_of_shards).to eq(15)
- end
- end
-
- context 'without application_settings present' do
- it 'migrates settings' do
- migrate!
-
- settings = elastic_index_settings.all
-
- expect(settings.size).to eq 1
-
- setting = elastic_index_settings.first
-
- expect(setting.number_of_replicas).to eq(1)
- expect(setting.number_of_shards).to eq(5)
- end
- end
-end
diff --git a/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb b/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb
deleted file mode 100644
index 25e0ef439bd..00000000000
--- a/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe MoveContainerRegistryEnabledToProjectFeatures3, :migration, feature_category: :container_registry do
- let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') }
-
- let!(:background_jobs) do
- table(:background_migration_jobs).create!(class_name: described_class::MIGRATION, arguments: [-1, -2])
- table(:background_migration_jobs).create!(class_name: described_class::MIGRATION, arguments: [-3, -4])
- end
-
- let!(:projects) do
- [
- table(:projects).create!(namespace_id: namespace.id, name: 'project 1'),
- table(:projects).create!(namespace_id: namespace.id, name: 'project 2'),
- table(:projects).create!(namespace_id: namespace.id, name: 'project 3'),
- table(:projects).create!(namespace_id: namespace.id, name: 'project 4')
- ]
- end
-
- before do
- stub_const("#{described_class.name}::BATCH_SIZE", 3)
- end
-
- around do |example|
- Sidekiq::Testing.fake! do
- freeze_time do
- example.call
- end
- end
- end
-
- it 'schedules jobs for ranges of projects' do
- # old entries in background_migration_jobs should be deleted.
- expect(table(:background_migration_jobs).count).to eq(2)
- expect(table(:background_migration_jobs).first.arguments).to eq([-1, -2])
- expect(table(:background_migration_jobs).second.arguments).to eq([-3, -4])
-
- migrate!
-
- # Since track_jobs is true, each job should have an entry in the background_migration_jobs
- # table.
- expect(table(:background_migration_jobs).count).to eq(2)
- expect(table(:background_migration_jobs).first.arguments).to eq([projects[0].id, projects[2].id])
- expect(table(:background_migration_jobs).second.arguments).to eq([projects[3].id, projects[3].id])
-
- expect(described_class::MIGRATION)
- .to be_scheduled_delayed_migration(2.minutes, projects[0].id, projects[2].id)
-
- expect(described_class::MIGRATION)
- .to be_scheduled_delayed_migration(4.minutes, projects[3].id, projects[3].id)
- end
-
- it 'schedules jobs according to the configured batch size' do
- expect { migrate! }.to change { BackgroundMigrationWorker.jobs.size }.by(2)
- end
-end
diff --git a/spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb b/spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb
deleted file mode 100644
index 66fd5eb5ae5..00000000000
--- a/spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe PopulateDismissalInformationForVulnerabilities, feature_category: :vulnerability_management do
- let(:users) { table(:users) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:vulnerabilities) { table(:vulnerabilities) }
-
- let(:existing_dismissed_at) { Time.now }
- let(:states) { { detected: 1, dismissed: 2, resolved: 3, confirmed: 4 } }
- let!(:namespace) { namespaces.create!(name: "foo", path: "bar") }
- let!(:user_1) { users.create!(name: 'John Doe', email: 'john_doe+1@example.com', projects_limit: 5) }
- let!(:user_2) { users.create!(name: 'John Doe', email: 'john_doe+2@example.com', projects_limit: 5) }
- let!(:project) { projects.create!(namespace_id: namespace.id) }
- let!(:vulnerability_params) do
- {
- project_id: project.id,
- author_id: user_1.id,
- title: 'Vulnerability',
- severity: 5,
- confidence: 5,
- report_type: 5
- }
- end
-
- let!(:detected_vulnerability) { vulnerabilities.create!(**vulnerability_params, state: states[:detected]) }
- let!(:resolved_vulnerability) { vulnerabilities.create!(**vulnerability_params, state: states[:resolved]) }
- let!(:confirmed_vulnerability) { vulnerabilities.create!(**vulnerability_params, state: states[:confirmed]) }
-
- let!(:dismissed_vulnerability_1) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], updated_by_id: user_2.id) }
- let!(:dismissed_vulnerability_2) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], last_edited_by_id: user_2.id) }
- let!(:dismissed_vulnerability_3) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], dismissed_at: existing_dismissed_at, author_id: user_2.id) }
- let!(:dismissed_vulnerability_4) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], dismissed_by_id: user_1.id, author_id: user_2.id) }
- let!(:dismissed_vulnerability_5) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], dismissed_at: existing_dismissed_at, dismissed_by_id: user_1.id, updated_by_id: user_2.id) }
-
- around do |example|
- freeze_time { example.run }
- end
-
- it 'updates the dismissal information for vulnerabilities' do
- expect { migrate! }.to change { dismissed_vulnerability_1.reload.dismissed_at }.from(nil).to(dismissed_vulnerability_1.updated_at)
- .and change { dismissed_vulnerability_1.reload.dismissed_by_id }.from(nil).to(user_2.id)
- .and change { dismissed_vulnerability_2.reload.dismissed_at }.from(nil).to(dismissed_vulnerability_2.updated_at)
- .and change { dismissed_vulnerability_2.reload.dismissed_by_id }.from(nil).to(user_2.id)
- .and change { dismissed_vulnerability_3.reload.dismissed_by_id }.from(nil).to(user_2.id)
- .and change { dismissed_vulnerability_4.reload.dismissed_at }.from(nil).to(dismissed_vulnerability_4.updated_at)
- .and not_change { dismissed_vulnerability_3.reload.dismissed_at }.from(existing_dismissed_at)
- .and not_change { dismissed_vulnerability_4.reload.dismissed_by_id }.from(user_1.id)
- .and not_change { dismissed_vulnerability_5.reload.dismissed_at }.from(existing_dismissed_at)
- .and not_change { dismissed_vulnerability_5.reload.dismissed_by_id }.from(user_1.id)
- .and not_change { detected_vulnerability.reload.dismissed_at }.from(nil)
- .and not_change { detected_vulnerability.reload.dismissed_by_id }.from(nil)
- .and not_change { resolved_vulnerability.reload.dismissed_at }.from(nil)
- .and not_change { resolved_vulnerability.reload.dismissed_by_id }.from(nil)
- .and not_change { confirmed_vulnerability.reload.dismissed_at }.from(nil)
- .and not_change { confirmed_vulnerability.reload.dismissed_by_id }.from(nil)
- end
-end
diff --git a/spec/migrations/queue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb b/spec/migrations/queue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb
new file mode 100644
index 00000000000..8209f317550
--- /dev/null
+++ b/spec/migrations/queue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillAdminModeScopeForPersonalAccessTokens,
+ feature_category: :authentication_and_authorization do
+ describe '#up' do
+ it 'schedules background migration' do
+ migrate!
+
+ expect(described_class::MIGRATION).to have_scheduled_batched_migration(
+ table_name: :personal_access_tokens,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL)
+ end
+ end
+end
diff --git a/spec/migrations/remove_hipchat_service_records_spec.rb b/spec/migrations/remove_hipchat_service_records_spec.rb
deleted file mode 100644
index b89572b069e..00000000000
--- a/spec/migrations/remove_hipchat_service_records_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RemoveHipchatServiceRecords, feature_category: :integrations do
- let(:services) { table(:services) }
-
- before do
- services.create!(type: 'HipchatService')
- services.create!(type: 'SomeOtherType')
- end
-
- it 'removes services records of type HipchatService' do
- expect(services.count).to eq(2)
-
- migrate!
-
- expect(services.count).to eq(1)
- expect(services.first.type).to eq('SomeOtherType')
- expect(services.where(type: 'HipchatService')).to be_empty
- end
-end
diff --git a/spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb b/spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb
deleted file mode 100644
index eabf6271ded..00000000000
--- a/spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-require_migration!('add_not_valid_foreign_key_to_group_hooks')
-
-RSpec.describe RemoveRecordsWithoutGroupFromWebhooksTable, schema: 20210330091751, feature_category: :integrations do
- let(:web_hooks) { table(:web_hooks) }
- let(:groups) { table(:namespaces) }
-
- before do
- group = groups.create!(name: 'gitlab', path: 'gitlab-org')
- web_hooks.create!(group_id: group.id, type: 'GroupHook')
- web_hooks.create!(group_id: nil)
-
- AddNotValidForeignKeyToGroupHooks.new.down
- web_hooks.create!(group_id: non_existing_record_id, type: 'GroupHook')
- AddNotValidForeignKeyToGroupHooks.new.up
- end
-
- it 'removes group hooks where the referenced group does not exist', :aggregate_failures do
- expect { RemoveRecordsWithoutGroupFromWebhooksTable.new.up }.to change { web_hooks.count }.by(-1)
- expect(web_hooks.where.not(group_id: groups.select(:id)).count).to eq(0)
- expect(web_hooks.where.not(group_id: nil).count).to eq(1)
- end
-end
diff --git a/spec/migrations/schedule_add_primary_email_to_emails_if_user_confirmed_spec.rb b/spec/migrations/schedule_add_primary_email_to_emails_if_user_confirmed_spec.rb
deleted file mode 100644
index 98d3e9b7c7c..00000000000
--- a/spec/migrations/schedule_add_primary_email_to_emails_if_user_confirmed_spec.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleAddPrimaryEmailToEmailsIfUserConfirmed, :sidekiq, feature_category: :users do
- let(:migration) { described_class.new }
- let(:users) { table(:users) }
-
- let!(:user_1) { users.create!(name: 'confirmed-user-1', email: 'confirmed-1@example.com', confirmed_at: 1.day.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: 'confirmed-user-4', email: 'confirmed-4@example.com', confirmed_at: 1.day.ago, projects_limit: 100) }
-
- before do
- stub_const("#{described_class.name}::BATCH_SIZE", 2)
- stub_const("#{described_class.name}::INTERVAL", 2.minutes.to_i)
- end
-
- it 'schedules addition of primary email to emails in delayed batches' do
- Sidekiq::Testing.fake! do
- freeze_time do
- migration.up
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, user_1.id, user_2.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, user_3.id, user_4.id)
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- end
- end
- end
-end
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
index 8a14bf58698..a3bec40c3f0 100644
--- 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
@@ -4,7 +4,8 @@ require 'spec_helper'
require_migration!
-RSpec.describe ScheduleBackfillDraftStatusOnMergeRequestsCorrectedRegex, :sidekiq, feature_category: :code_review do
+RSpec.describe ScheduleBackfillDraftStatusOnMergeRequestsCorrectedRegex,
+ :sidekiq, feature_category: :code_review_workflow do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:merge_requests) { table(:merge_requests) }
diff --git a/spec/migrations/schedule_disable_expiration_policies_linked_to_no_container_images_spec.rb b/spec/migrations/schedule_disable_expiration_policies_linked_to_no_container_images_spec.rb
deleted file mode 100644
index ebcc3fda0a3..00000000000
--- a/spec/migrations/schedule_disable_expiration_policies_linked_to_no_container_images_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe ScheduleDisableExpirationPoliciesLinkedToNoContainerImages, feature_category: :container_registry do
- let!(:projects) { table(:projects) }
- let!(:container_expiration_policies) { table(:container_expiration_policies) }
- let!(:container_repositories) { table(:container_repositories) }
- let!(:namespaces) { table(:namespaces) }
- let!(:namespace) { namespaces.create!(name: 'test', path: 'test') }
-
- let!(:policy1) { create_expiration_policy(id: 1, enabled: true) }
- let!(:policy2) { create_expiration_policy(id: 2, enabled: false) }
- let!(:policy3) { create_expiration_policy(id: 3, enabled: false) }
- let!(:policy4) { create_expiration_policy(id: 4, enabled: true) }
- let!(:policy5) { create_expiration_policy(id: 5, enabled: false) }
- let!(:policy6) { create_expiration_policy(id: 6, enabled: false) }
- let!(:policy7) { create_expiration_policy(id: 7, enabled: true) }
- let!(:policy8) { create_expiration_policy(id: 8, enabled: true) }
- let!(:policy9) { create_expiration_policy(id: 9, enabled: true) }
-
- it 'schedules background migrations', :aggregate_failures do
- stub_const("#{described_class}::BATCH_SIZE", 2)
-
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 4)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 7, 8)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(6.minutes, 9, 9)
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(3)
- end
- end
- end
-
- def create_expiration_policy(id:, enabled:)
- project = projects.create!(id: id, namespace_id: namespace.id, name: "gitlab-#{id}")
- container_expiration_policies.create!(
- enabled: enabled,
- project_id: project.id
- )
- end
-end
diff --git a/spec/migrations/schedule_update_timelogs_project_id_spec.rb b/spec/migrations/schedule_update_timelogs_project_id_spec.rb
deleted file mode 100644
index 5ce3f7dd36c..00000000000
--- a/spec/migrations/schedule_update_timelogs_project_id_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleUpdateTimelogsProjectId, feature_category: :team_planning do
- let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
- let!(:project) { table(:projects).create!(namespace_id: namespace.id) }
- let!(:issue) { table(:issues).create!(project_id: project.id) }
- let!(:merge_request) { table(:merge_requests).create!(target_project_id: project.id, source_branch: 'master', target_branch: 'feature') }
- let!(:timelog1) { table(:timelogs).create!(issue_id: issue.id, time_spent: 60) }
- let!(:timelog2) { table(:timelogs).create!(merge_request_id: merge_request.id, time_spent: 600) }
- let!(:timelog3) { table(:timelogs).create!(merge_request_id: merge_request.id, time_spent: 60) }
- let!(:timelog4) { table(:timelogs).create!(issue_id: issue.id, time_spent: 600) }
-
- it 'correctly schedules background migrations' do
- stub_const("#{described_class}::BATCH_SIZE", 2)
-
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(described_class::MIGRATION)
- .to be_scheduled_delayed_migration(2.minutes, timelog1.id, timelog2.id)
-
- expect(described_class::MIGRATION)
- .to be_scheduled_delayed_migration(4.minutes, timelog3.id, timelog4.id)
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- end
- end
- end
-end
diff --git a/spec/migrations/schedule_update_users_where_two_factor_auth_required_from_group_spec.rb b/spec/migrations/schedule_update_users_where_two_factor_auth_required_from_group_spec.rb
deleted file mode 100644
index c9f22c02a0b..00000000000
--- a/spec/migrations/schedule_update_users_where_two_factor_auth_required_from_group_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleUpdateUsersWhereTwoFactorAuthRequiredFromGroup, feature_category: :require_two_factor_authentication_from_group do
- let(:users) { table(:users) }
- let!(:user_1) { users.create!(require_two_factor_authentication_from_group: false, name: "user1", email: "user1@example.com", projects_limit: 1) }
- let!(:user_2) { users.create!(require_two_factor_authentication_from_group: true, name: "user2", email: "user2@example.com", projects_limit: 1) }
- let!(:user_3) { users.create!(require_two_factor_authentication_from_group: false, name: "user3", email: "user3@example.com", projects_limit: 1) }
-
- before do
- stub_const("#{described_class.name}::BATCH_SIZE", 1)
- end
-
- it 'schedules jobs for users that do not require two factor authentication' do
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
- 2.minutes, user_1.id, user_1.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
- 4.minutes, user_3.id, user_3.id)
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- end
- end
- end
-end
diff --git a/spec/migrations/second_recount_epic_cache_counts_spec.rb b/spec/migrations/second_recount_epic_cache_counts_spec.rb
new file mode 100644
index 00000000000..ab4357264be
--- /dev/null
+++ b/spec/migrations/second_recount_epic_cache_counts_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SecondRecountEpicCacheCounts, :migration, feature_category: :portfolio_management do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules a batched background migration' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :epics,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ max_batch_size: described_class::MAX_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
diff --git a/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb b/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
index fdbd8093fa5..ffd25152a45 100644
--- a/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
+++ b/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe SliceMergeRequestDiffCommitMigrations, :migration, feature_category: :code_review do
+RSpec.describe SliceMergeRequestDiffCommitMigrations, :migration, feature_category: :code_review_workflow do
let(:migration) { described_class.new }
describe '#up' do
diff --git a/spec/migrations/update_invalid_web_hooks_spec.rb b/spec/migrations/update_invalid_web_hooks_spec.rb
deleted file mode 100644
index 9e69d3637b8..00000000000
--- a/spec/migrations/update_invalid_web_hooks_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe UpdateInvalidWebHooks, feature_category: :integrations do
- let(:web_hooks) { table(:web_hooks) }
- let(:groups) { table(:namespaces) }
- let(:projects) { table(:projects) }
-
- before do
- group = groups.create!(name: 'gitlab', path: 'gitlab-org')
- project = projects.create!(namespace_id: group.id)
-
- web_hooks.create!(group_id: group.id, type: 'GroupHook')
- web_hooks.create!(project_id: project.id, type: 'ProjectHook')
- web_hooks.create!(group_id: group.id, project_id: project.id, type: 'ProjectHook')
- end
-
- it 'clears group_id when ProjectHook type and project_id are present', :aggregate_failures do
- expect(web_hooks.where.not(group_id: nil).where.not(project_id: nil).count).to eq(1)
-
- migrate!
-
- expect(web_hooks.where.not(group_id: nil).where.not(project_id: nil).count).to eq(0)
- expect(web_hooks.where(type: 'GroupHook').count).to eq(1)
- expect(web_hooks.where(type: 'ProjectHook').count).to eq(2)
- end
-end