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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
commit5afcbe03ead9ada87621888a31a62652b10a7e4f (patch)
tree9918b67a0d0f0bafa6542e839a8be37adf73102d /spec/migrations
parentc97c0201564848c1f53226fe19d71fdcc472f7d0 (diff)
Add latest changes from gitlab-org/gitlab@16-4-stable-eev16.4.0-rc42
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb58
-rw-r--r--spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb58
-rw-r--r--spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb58
-rw-r--r--spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb58
-rw-r--r--spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb58
-rw-r--r--spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb60
-rw-r--r--spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb60
-rw-r--r--spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb60
-rw-r--r--spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb51
-rw-r--r--spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb45
-rw-r--r--spec/migrations/20230726142555_ensure_notes_bigint_backfill_is_finished_for_self_managed_spec.rb35
-rw-r--r--spec/migrations/20230726144458_swap_notes_id_to_bigint_for_self_managed_spec.rb120
-rw-r--r--spec/migrations/20230802212443_add_current_user_todos_widget_to_epic_work_item_type_spec.rb25
-rw-r--r--spec/migrations/20230809170822_ensure_system_note_metadata_bigint_backfill_is_finished_for_self_managed_spec.rb35
-rw-r--r--spec/migrations/20230809174702_swap_system_note_metadata_note_id_to_bigint_for_self_managed_spec.rb121
-rw-r--r--spec/migrations/20230809203254_ensure_issue_user_mentions_bigint_backfill_is_finished_for_self_managed_spec.rb35
-rw-r--r--spec/migrations/20230809210550_swap_issue_user_mentions_note_id_to_bigint_for_self_managed_spec.rb127
-rw-r--r--spec/migrations/20230810113227_swap_note_diff_files_note_id_to_bigint_for_self_hosts_spec.rb156
-rw-r--r--spec/migrations/20230810124545_schedule_fixing_namespace_ids_of_vulnerability_reads_spec.rb27
-rw-r--r--spec/migrations/20230811103457_queue_backfill_nuget_normalized_version_spec.rb26
-rw-r--r--spec/migrations/20230815140656_queue_populate_denormalized_columns_for_sbom_occurrences_spec.rb26
-rw-r--r--spec/migrations/20230815160428_rename_plans_titles_with_legacy_plan_names_spec.rb23
-rw-r--r--spec/migrations/20230816152540_ensure_dum_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb36
-rw-r--r--spec/migrations/20230816152639_swap_design_user_mentions_note_id_to_big_int_for_self_managed_spec.rb122
-rw-r--r--spec/migrations/20230817111938_swap_events_target_id_to_bigint_for_self_hosts_spec.rb121
-rw-r--r--spec/migrations/20230817143637_swap_award_emoji_note_id_to_bigint_for_self_hosts_spec.rb121
-rw-r--r--spec/migrations/20230818083610_queue_backfill_users_with_defaults_spec.rb27
-rw-r--r--spec/migrations/20230818085219_queue_backfill_user_preferences_with_defaults_spec.rb27
-rw-r--r--spec/migrations/20230818142801_queue_create_compliance_standards_adherence_spec.rb50
-rw-r--r--spec/migrations/20230821081603_queue_convert_credit_card_validation_data_to_hashes_spec.rb26
-rw-r--r--spec/migrations/20230822104028_delete_project_callout_three_spec.rb21
-rw-r--r--spec/migrations/20230822151454_remove_free_user_cap_email_workers_spec.rb24
-rw-r--r--spec/migrations/20230823090001_queue_backfill_project_statistics_storage_size_with_recent_size_spec.rb26
-rw-r--r--spec/migrations/20230823140934_add_linked_items_widget_to_ticket_work_item_type_spec.rb29
-rw-r--r--spec/migrations/20230830121830_queue_update_users_set_external_if_service_account_spec.rb26
-rw-r--r--spec/migrations/20230831084632_queue_sync_scan_result_policies_spec.rb26
-rw-r--r--spec/migrations/20230906204934_restart_self_hosted_sent_notifications_bigint_conversion_spec.rb144
-rw-r--r--spec/migrations/20230906204935_restart_self_hosted_sent_notifications_backfill_spec.rb162
-rw-r--r--spec/migrations/20230907155247_queue_backfill_has_merge_request_of_vulnerability_reads_spec.rb26
-rw-r--r--spec/migrations/backfill_alert_management_prometheus_integrations_spec.rb126
-rw-r--r--spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb35
-rw-r--r--spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_for_self_managed_spec.rb135
42 files changed, 2066 insertions, 566 deletions
diff --git a/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb b/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb
deleted file mode 100644
index 3ccd92e15a4..00000000000
--- a/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RebalancePartitionIdCiPipeline, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_builds' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_pipelines,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb b/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb
deleted file mode 100644
index b983564a2d9..00000000000
--- a/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RebalancePartitionIdCiBuild, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_builds' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_builds,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb b/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb
deleted file mode 100644
index fb0e1fe17ec..00000000000
--- a/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiPipelineVariable, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_pipeline_variables' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_pipeline_variables,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb b/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb
deleted file mode 100644
index de2386c6a0d..00000000000
--- a/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiJobArtifact, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_job_artifacts' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_job_artifacts,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb b/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb
deleted file mode 100644
index 8b057afc1e9..00000000000
--- a/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiStage, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_stages' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_stages,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb b/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb
deleted file mode 100644
index f0ac8239f58..00000000000
--- a/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiBuildReportResult,
- migration: :gitlab_ci,
- feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_build_report_results' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_build_report_results,
- column_name: :build_id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb b/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb
deleted file mode 100644
index a93ba36d9ae..00000000000
--- a/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiBuildTraceMetadata,
- migration: :gitlab_ci,
- feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of ci_build_trace_metadata' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :ci_build_trace_metadata,
- column_name: :build_id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb b/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb
deleted file mode 100644
index c354d68749f..00000000000
--- a/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiBuildMetadata,
- migration: :gitlab_ci,
- feature_category: :continuous_integration do
- let(:migration) { described_class::MIGRATION }
-
- context 'when on saas' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- describe '#up' do
- it 'schedules background jobs for each batch of p_ci_builds_metadata' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- gitlab_schema: :gitlab_ci,
- table_name: :p_ci_builds_metadata,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
- end
-
- context 'when on self-managed instance' do
- let(:migration) { described_class.new }
-
- describe '#up' do
- it 'does not schedule background job' do
- expect(migration).not_to receive(:queue_batched_background_migration)
-
- migration.up
- end
- end
-
- describe '#down' do
- it 'does not delete background job' do
- expect(migration).not_to receive(:delete_batched_background_migration)
-
- migration.down
- end
- end
- end
-end
diff --git a/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb b/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb
deleted file mode 100644
index 64275855262..00000000000
--- a/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsForCiJobVariables, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:builds) { table(:ci_builds, database: :ci) }
- let(:job_variables) { table(:ci_job_variables, database: :ci) }
- let(:connection) { job_variables.connection }
-
- around do |example|
- connection.execute "ALTER TABLE #{job_variables.quoted_table_name} DISABLE TRIGGER ALL;"
-
- example.run
- ensure
- connection.execute "ALTER TABLE #{job_variables.quoted_table_name} ENABLE TRIGGER ALL;"
- end
-
- before do
- job = builds.create!(partition_id: 100)
-
- job_variables.insert_all!([
- { job_id: job.id, partition_id: 100, key: 'variable-100' },
- { job_id: job.id, partition_id: 101, key: 'variable-101' }
- ])
- end
-
- describe '#up', :aggregate_failures do
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- it 'fixes partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(job_variables.where(partition_id: 100).count).to eq(2)
- expect(job_variables.where(partition_id: 101).count).to eq(0)
- end
- end
-
- context 'when on self managed' do
- it 'does not change partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(job_variables.where(partition_id: 100).count).to eq(1)
- expect(job_variables.where(partition_id: 101).count).to eq(1)
- end
- end
- end
-end
diff --git a/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb b/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb
deleted file mode 100644
index 44031175497..00000000000
--- a/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FixPartitionIdsOnCiSourcesPipelines, migration: :gitlab_ci, feature_category: :continuous_integration do
- let(:sources_pipelines) { table(:ci_sources_pipelines, database: :ci) }
-
- before do
- sources_pipelines.insert_all!([
- { partition_id: 100, source_partition_id: 100 },
- { partition_id: 100, source_partition_id: 101 },
- { partition_id: 101, source_partition_id: 100 },
- { partition_id: 101, source_partition_id: 101 }
- ])
- end
-
- describe '#up' do
- context 'when on sass' do
- before do
- allow(Gitlab).to receive(:com?).and_return(true)
- end
-
- it 'fixes partition_id and source_partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(sources_pipelines.where(partition_id: 100).count).to eq(4)
- expect(sources_pipelines.where(partition_id: 101).count).to eq(0)
- expect(sources_pipelines.where(source_partition_id: 100).count).to eq(4)
- expect(sources_pipelines.where(source_partition_id: 101).count).to eq(0)
- end
- end
-
- context 'when on self managed' do
- it 'does not change partition_id or source_partition_id' do
- expect { migrate! }.not_to raise_error
-
- expect(sources_pipelines.where(partition_id: 100).count).to eq(2)
- expect(sources_pipelines.where(partition_id: 100).count).to eq(2)
- expect(sources_pipelines.where(source_partition_id: 101).count).to eq(2)
- expect(sources_pipelines.where(source_partition_id: 101).count).to eq(2)
- end
- end
- end
-end
diff --git a/spec/migrations/20230726142555_ensure_notes_bigint_backfill_is_finished_for_self_managed_spec.rb b/spec/migrations/20230726142555_ensure_notes_bigint_backfill_is_finished_for_self_managed_spec.rb
new file mode 100644
index 00000000000..a76ad767cf2
--- /dev/null
+++ b/spec/migrations/20230726142555_ensure_notes_bigint_backfill_is_finished_for_self_managed_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureNotesBigintBackfillIsFinishedForSelfManaged, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'notes',
+ column_name: 'id',
+ job_arguments: [['id'], ['id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for self-managed instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/20230726144458_swap_notes_id_to_bigint_for_self_managed_spec.rb b/spec/migrations/20230726144458_swap_notes_id_to_bigint_for_self_managed_spec.rb
new file mode 100644
index 00000000000..b4552cebc58
--- /dev/null
+++ b/spec/migrations/20230726144458_swap_notes_id_to_bigint_for_self_managed_spec.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapNotesIdToBigintForSelfManaged, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+
+ shared_examples 'column `id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE notes ALTER COLUMN id TYPE bigint')
+ connection.execute('ALTER TABLE notes DROP COLUMN IF EXISTS id_convert_to_bigint')
+ end
+
+ after do
+ connection.execute('ALTER TABLE notes DROP COLUMN IF EXISTS id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ notes_table.reset_column_information
+
+ expect(notes_table.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(notes_table.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ notes_table.reset_column_information
+
+ expect(notes_table.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(notes_table.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ let!(:notes_table) { table(:notes) }
+
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE notes ALTER COLUMN id TYPE bigint')
+ connection.execute('ALTER TABLE notes ADD COLUMN IF NOT EXISTS id_convert_to_bigint integer')
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE notes DROP COLUMN IF EXISTS id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(notes_table.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(notes_table.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('integer')
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE notes ALTER COLUMN id TYPE integer')
+ connection.execute('ALTER TABLE notes ADD COLUMN IF NOT EXISTS id_convert_to_bigint bigint')
+ connection.execute('ALTER TABLE notes ALTER COLUMN id_convert_to_bigint TYPE bigint')
+ connection.execute('DROP INDEX IF EXISTS index_notes_on_id_convert_to_bigint CASCADE')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_080e73845bfd() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."id_convert_to_bigint" := NEW."id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE notes DROP COLUMN IF EXISTS id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ notes_table.reset_column_information
+
+ expect(notes_table.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(notes_table.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ notes_table.reset_column_information
+
+ expect(notes_table.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(notes_table.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230802212443_add_current_user_todos_widget_to_epic_work_item_type_spec.rb b/spec/migrations/20230802212443_add_current_user_todos_widget_to_epic_work_item_type_spec.rb
new file mode 100644
index 00000000000..22a8f93b524
--- /dev/null
+++ b/spec/migrations/20230802212443_add_current_user_todos_widget_to_epic_work_item_type_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddCurrentUserTodosWidgetToEpicWorkItemType, :migration, feature_category: :team_planning do
+ it_behaves_like 'migration that adds a widget to a work item type' do
+ let(:target_type_enum_value) { described_class::EPIC_ENUM_VALUE }
+ let(:target_type) { :epic }
+ let(:widgets_for_type) do
+ {
+ 'Assignees' => 0,
+ 'Description' => 1,
+ 'Hierarchy' => 2,
+ 'Labels' => 3,
+ 'Notes' => 5,
+ 'Start and due date' => 6,
+ 'Health status' => 7,
+ 'Status' => 11,
+ 'Notifications' => 14,
+ 'Award emoji' => 16
+ }.freeze
+ end
+ end
+end
diff --git a/spec/migrations/20230809170822_ensure_system_note_metadata_bigint_backfill_is_finished_for_self_managed_spec.rb b/spec/migrations/20230809170822_ensure_system_note_metadata_bigint_backfill_is_finished_for_self_managed_spec.rb
new file mode 100644
index 00000000000..1c33872142d
--- /dev/null
+++ b/spec/migrations/20230809170822_ensure_system_note_metadata_bigint_backfill_is_finished_for_self_managed_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureSystemNoteMetadataBigintBackfillIsFinishedForSelfManaged, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'system_note_metadata',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for self-managed instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/20230809174702_swap_system_note_metadata_note_id_to_bigint_for_self_managed_spec.rb b/spec/migrations/20230809174702_swap_system_note_metadata_note_id_to_bigint_for_self_managed_spec.rb
new file mode 100644
index 00000000000..e8413b24ae9
--- /dev/null
+++ b/spec/migrations/20230809174702_swap_system_note_metadata_note_id_to_bigint_for_self_managed_spec.rb
@@ -0,0 +1,121 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapSystemNoteMetadataNoteIdToBigintForSelfManaged, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:system_note_metadata) { table(:system_note_metadata) }
+
+ shared_examples 'column `note_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE system_note_metadata ALTER COLUMN note_id TYPE bigint')
+ connection.execute('ALTER TABLE system_note_metadata DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ system_note_metadata.reset_column_information
+
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ system_note_metadata.reset_column_information
+
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `note_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE system_note_metadata ALTER COLUMN note_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE system_note_metadata ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE system_note_metadata DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE system_note_metadata ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE system_note_metadata ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint bigint')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_482bac5ec48a() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."note_id_convert_to_bigint" := NEW."note_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE system_note_metadata DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ system_note_metadata.reset_column_information
+
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ system_note_metadata.reset_column_information
+
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(system_note_metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230809203254_ensure_issue_user_mentions_bigint_backfill_is_finished_for_self_managed_spec.rb b/spec/migrations/20230809203254_ensure_issue_user_mentions_bigint_backfill_is_finished_for_self_managed_spec.rb
new file mode 100644
index 00000000000..09694a2ee8d
--- /dev/null
+++ b/spec/migrations/20230809203254_ensure_issue_user_mentions_bigint_backfill_is_finished_for_self_managed_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureIssueUserMentionsBigintBackfillIsFinishedForSelfManaged, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'issue_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for self-managed instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/20230809210550_swap_issue_user_mentions_note_id_to_bigint_for_self_managed_spec.rb b/spec/migrations/20230809210550_swap_issue_user_mentions_note_id_to_bigint_for_self_managed_spec.rb
new file mode 100644
index 00000000000..a311f876890
--- /dev/null
+++ b/spec/migrations/20230809210550_swap_issue_user_mentions_note_id_to_bigint_for_self_managed_spec.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapIssueUserMentionsNoteIdToBigintForSelfManaged, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:issue_user_mentions) { table(:issue_user_mentions) }
+
+ shared_examples 'column `note_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute('ALTER TABLE issue_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ after do
+ connection.execute('ALTER TABLE issue_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ issue_user_mentions.reset_column_information
+
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ issue_user_mentions.reset_column_information
+
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `note_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE issue_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE issue_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE issue_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint bigint')
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ connection.execute('DROP INDEX IF EXISTS index_issue_user_mentions_on_note_id_convert_to_bigint CASCADE')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_c2051020aa8b() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."note_id_convert_to_bigint" := NEW."note_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE issue_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ issue_user_mentions.reset_column_information
+
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ issue_user_mentions.reset_column_information
+
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(issue_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230810113227_swap_note_diff_files_note_id_to_bigint_for_self_hosts_spec.rb b/spec/migrations/20230810113227_swap_note_diff_files_note_id_to_bigint_for_self_hosts_spec.rb
new file mode 100644
index 00000000000..de169d9d21b
--- /dev/null
+++ b/spec/migrations/20230810113227_swap_note_diff_files_note_id_to_bigint_for_self_hosts_spec.rb
@@ -0,0 +1,156 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapNoteDiffFilesNoteIdToBigintForSelfHosts, feature_category: :database do
+ describe '#up' do
+ after(:all) do
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE note_diff_files DROP COLUMN IF EXISTS diff_note_id_convert_to_bigint')
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE note_diff_files ALTER COLUMN diff_note_id TYPE bigint')
+ connection.execute('ALTER TABLE note_diff_files DROP COLUMN IF EXISTS diff_note_id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ note_diff_files = table(:note_diff_files)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ note_diff_files.reset_column_information
+
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('bigint')
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }).to be nil
+ }
+
+ migration.after -> {
+ note_diff_files.reset_column_information
+
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('bigint')
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }).to be nil
+ }
+ end
+ end
+ end
+ end
+
+ context 'when self-managed instance with the columns already swapped' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE note_diff_files ALTER COLUMN diff_note_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE note_diff_files ADD COLUMN IF NOT EXISTS diff_note_id_convert_to_bigint integer'
+ )
+ end
+
+ it 'does not swap the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ note_diff_files = table(:note_diff_files)
+
+ migrate!
+
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('bigint')
+ expect(note_diff_files.columns.find do |c|
+ c.name == 'diff_note_id_convert_to_bigint'
+ end.sql_type).to eq('integer')
+ end
+ end
+
+ context 'when self-managed instance with the `diff_note_id_convert_to_bigint` column already dropped ' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE note_diff_files ALTER COLUMN diff_note_id TYPE bigint')
+ connection.execute('ALTER TABLE note_diff_files DROP COLUMN IF EXISTS diff_note_id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ note_diff_files = table(:note_diff_files)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ note_diff_files.reset_column_information
+
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('bigint')
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }).to be nil
+ }
+
+ migration.after -> {
+ note_diff_files.reset_column_information
+
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('bigint')
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }).to be nil
+ }
+ end
+ end
+ end
+ end
+
+ context 'when self-managed instance' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE note_diff_files ALTER COLUMN diff_note_id TYPE integer')
+ connection.execute('ALTER TABLE note_diff_files ADD COLUMN IF NOT EXISTS diff_note_id_convert_to_bigint bigint')
+ connection.execute('ALTER TABLE note_diff_files ALTER COLUMN diff_note_id_convert_to_bigint TYPE bigint')
+ connection.execute('DROP INDEX IF EXISTS index_note_diff_files_on_note_id_convert_to_bigint')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_775287b6d67a() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."diff_note_id_convert_to_bigint" := NEW."diff_note_id"; RETURN NEW; END; $$;')
+ end
+
+ it 'swaps the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ note_diff_files = table(:note_diff_files)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ note_diff_files.reset_column_information
+
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('integer')
+ expect(note_diff_files.columns.find do |c|
+ c.name == 'diff_note_id_convert_to_bigint'
+ end.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ note_diff_files.reset_column_information
+
+ expect(note_diff_files.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('bigint')
+ expect(note_diff_files.columns.find do |c|
+ c.name == 'diff_note_id_convert_to_bigint'
+ end.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230810124545_schedule_fixing_namespace_ids_of_vulnerability_reads_spec.rb b/spec/migrations/20230810124545_schedule_fixing_namespace_ids_of_vulnerability_reads_spec.rb
new file mode 100644
index 00000000000..294545bed2b
--- /dev/null
+++ b/spec/migrations/20230810124545_schedule_fixing_namespace_ids_of_vulnerability_reads_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe ScheduleFixingNamespaceIdsOfVulnerabilityReads, feature_category: :vulnerability_management do
+ let(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :vulnerability_reads,
+ column_name: :vulnerability_id,
+ interval: 2.minutes,
+ batch_size: 10_000,
+ sub_batch_size: 100
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230811103457_queue_backfill_nuget_normalized_version_spec.rb b/spec/migrations/20230811103457_queue_backfill_nuget_normalized_version_spec.rb
new file mode 100644
index 00000000000..6eb7ba0e2cd
--- /dev/null
+++ b/spec/migrations/20230811103457_queue_backfill_nuget_normalized_version_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillNugetNormalizedVersion, feature_category: :package_registry do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :packages_nuget_metadata,
+ column_name: :package_id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230815140656_queue_populate_denormalized_columns_for_sbom_occurrences_spec.rb b/spec/migrations/20230815140656_queue_populate_denormalized_columns_for_sbom_occurrences_spec.rb
new file mode 100644
index 00000000000..3976e398607
--- /dev/null
+++ b/spec/migrations/20230815140656_queue_populate_denormalized_columns_for_sbom_occurrences_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueuePopulateDenormalizedColumnsForSbomOccurrences, feature_category: :dependency_management do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :sbom_occurrences,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230815160428_rename_plans_titles_with_legacy_plan_names_spec.rb b/spec/migrations/20230815160428_rename_plans_titles_with_legacy_plan_names_spec.rb
new file mode 100644
index 00000000000..21c17a60e90
--- /dev/null
+++ b/spec/migrations/20230815160428_rename_plans_titles_with_legacy_plan_names_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RenamePlansTitlesWithLegacyPlanNames, feature_category: :subscription_management do
+ let(:plans) { table(:plans) }
+
+ let!(:premium_plan) { plans.create!(name: 'premium', title: 'Premium (Formerly Silver)') }
+ let!(:ultimate_plan) { plans.create!(name: 'ultimate', title: 'Ultimate (Formerly Gold)') }
+
+ describe '#up' do
+ it 'updates the plan titles' do
+ expect(premium_plan.title).to eq('Premium (Formerly Silver)')
+ expect(ultimate_plan.title).to eq('Ultimate (Formerly Gold)')
+
+ migrate!
+
+ expect(premium_plan.reload.title).to eq('Premium')
+ expect(ultimate_plan.reload.title).to eq('Ultimate')
+ end
+ end
+end
diff --git a/spec/migrations/20230816152540_ensure_dum_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb b/spec/migrations/20230816152540_ensure_dum_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb
new file mode 100644
index 00000000000..c8590250c62
--- /dev/null
+++ b/spec/migrations/20230816152540_ensure_dum_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe EnsureDumNoteIdBigintBackfillIsFinishedForSelfManaged, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'design_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for self-managed instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/20230816152639_swap_design_user_mentions_note_id_to_big_int_for_self_managed_spec.rb b/spec/migrations/20230816152639_swap_design_user_mentions_note_id_to_big_int_for_self_managed_spec.rb
new file mode 100644
index 00000000000..f6342fe6388
--- /dev/null
+++ b/spec/migrations/20230816152639_swap_design_user_mentions_note_id_to_big_int_for_self_managed_spec.rb
@@ -0,0 +1,122 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe SwapDesignUserMentionsNoteIdToBigIntForSelfManaged, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:design_user_mentions) { table(:design_user_mentions) }
+
+ shared_examples 'column `note_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE design_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute('ALTER TABLE design_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ design_user_mentions.reset_column_information
+
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ design_user_mentions.reset_column_information
+
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `note_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE design_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE design_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE design_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE design_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE design_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint bigint')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_3dc62927cae8() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."note_id_convert_to_bigint" := NEW."note_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE design_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ design_user_mentions.reset_column_information
+
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ design_user_mentions.reset_column_information
+
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(design_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230817111938_swap_events_target_id_to_bigint_for_self_hosts_spec.rb b/spec/migrations/20230817111938_swap_events_target_id_to_bigint_for_self_hosts_spec.rb
new file mode 100644
index 00000000000..515d4f21fc6
--- /dev/null
+++ b/spec/migrations/20230817111938_swap_events_target_id_to_bigint_for_self_hosts_spec.rb
@@ -0,0 +1,121 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapEventsTargetIdToBigintForSelfHosts, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:events) { table(:events) }
+
+ shared_examples 'column `target_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE events ALTER COLUMN target_id TYPE bigint')
+ connection.execute('ALTER TABLE events DROP COLUMN IF EXISTS target_id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ events.reset_column_information
+
+ expect(events.columns.find { |c| c.name == 'target_id' }.sql_type).to eq('bigint')
+ expect(events.columns.find { |c| c.name == 'target_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ events.reset_column_information
+
+ expect(events.columns.find { |c| c.name == 'target_id' }.sql_type).to eq('bigint')
+ expect(events.columns.find { |c| c.name == 'target_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `target_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `target_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `target_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE events ALTER COLUMN target_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE events ADD COLUMN IF NOT EXISTS target_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE events DROP COLUMN IF EXISTS target_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(events.columns.find { |c| c.name == 'target_id' }.sql_type).to eq('bigint')
+ expect(events.columns.find { |c| c.name == 'target_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE events ALTER COLUMN target_id TYPE integer')
+ connection.execute('ALTER TABLE events ADD COLUMN IF NOT EXISTS target_id_convert_to_bigint bigint')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_cd1aeb22b34a() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."target_id_convert_to_bigint" := NEW."target_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE events DROP COLUMN IF EXISTS target_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ events.reset_column_information
+
+ expect(events.columns.find { |c| c.name == 'target_id' }.sql_type).to eq('integer')
+ expect(events.columns.find { |c| c.name == 'target_id_convert_to_bigint' }.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ events.reset_column_information
+
+ expect(events.columns.find { |c| c.name == 'target_id' }.sql_type).to eq('bigint')
+ expect(events.columns.find { |c| c.name == 'target_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230817143637_swap_award_emoji_note_id_to_bigint_for_self_hosts_spec.rb b/spec/migrations/20230817143637_swap_award_emoji_note_id_to_bigint_for_self_hosts_spec.rb
new file mode 100644
index 00000000000..a9521a40d0d
--- /dev/null
+++ b/spec/migrations/20230817143637_swap_award_emoji_note_id_to_bigint_for_self_hosts_spec.rb
@@ -0,0 +1,121 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapAwardEmojiNoteIdToBigintForSelfHosts, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:award_emoji) { table(:award_emoji) }
+
+ shared_examples 'column `awardable_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE award_emoji ALTER COLUMN awardable_id TYPE bigint')
+ connection.execute('ALTER TABLE award_emoji DROP COLUMN IF EXISTS awardable_id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('bigint')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('bigint')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `awardable_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `awardable_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `awardable_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE award_emoji ALTER COLUMN awardable_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE award_emoji ADD COLUMN IF NOT EXISTS awardable_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE award_emoji DROP COLUMN IF EXISTS awardable_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('bigint')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE award_emoji ALTER COLUMN awardable_id TYPE integer')
+ connection.execute('ALTER TABLE award_emoji ADD COLUMN IF NOT EXISTS awardable_id_convert_to_bigint bigint')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_909cf0a06094() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."awardable_id_convert_to_bigint" := NEW."awardable_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE award_emoji DROP COLUMN IF EXISTS awardable_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('integer')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('bigint')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230818083610_queue_backfill_users_with_defaults_spec.rb b/spec/migrations/20230818083610_queue_backfill_users_with_defaults_spec.rb
new file mode 100644
index 00000000000..4cd72b4fa7a
--- /dev/null
+++ b/spec/migrations/20230818083610_queue_backfill_users_with_defaults_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillUsersWithDefaults, feature_category: :user_profile do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :users,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE,
+ max_batch_size: described_class::MAX_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230818085219_queue_backfill_user_preferences_with_defaults_spec.rb b/spec/migrations/20230818085219_queue_backfill_user_preferences_with_defaults_spec.rb
new file mode 100644
index 00000000000..eff14be22f6
--- /dev/null
+++ b/spec/migrations/20230818085219_queue_backfill_user_preferences_with_defaults_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillUserPreferencesWithDefaults, feature_category: :user_profile do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :user_preferences,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE,
+ max_batch_size: described_class::MAX_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230818142801_queue_create_compliance_standards_adherence_spec.rb b/spec/migrations/20230818142801_queue_create_compliance_standards_adherence_spec.rb
new file mode 100644
index 00000000000..466d0bca997
--- /dev/null
+++ b/spec/migrations/20230818142801_queue_create_compliance_standards_adherence_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueCreateComplianceStandardsAdherence, feature_category: :compliance_management do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ context 'for EE' do
+ before do
+ allow(Gitlab).to receive(:ee?).and_return(true)
+ 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: :projects,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+ end
+
+ context 'for FOSS' do
+ before do
+ allow(Gitlab).to receive(:ee?).and_return(false)
+ end
+
+ it 'does not 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).not_to have_scheduled_batched_migration
+ }
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230821081603_queue_convert_credit_card_validation_data_to_hashes_spec.rb b/spec/migrations/20230821081603_queue_convert_credit_card_validation_data_to_hashes_spec.rb
new file mode 100644
index 00000000000..36ab25ffa3e
--- /dev/null
+++ b/spec/migrations/20230821081603_queue_convert_credit_card_validation_data_to_hashes_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueConvertCreditCardValidationDataToHashes, feature_category: :user_profile do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :user_credit_card_validations,
+ column_name: :user_id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230822104028_delete_project_callout_three_spec.rb b/spec/migrations/20230822104028_delete_project_callout_three_spec.rb
new file mode 100644
index 00000000000..127af643976
--- /dev/null
+++ b/spec/migrations/20230822104028_delete_project_callout_three_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DeleteProjectCalloutThree, feature_category: :groups_and_projects do
+ let(:migration) { described_class.new }
+
+ let(:user) { table(:users).create!(name: 'test', email: 'test@example.com', projects_limit: 5) }
+ let(:namespace) { table(:namespaces).create!(name: 'name', path: 'path') }
+ let(:project) { table(:projects).create!(namespace_id: namespace.id, project_namespace_id: namespace.id) }
+ let(:project_callout) { table(:user_project_callouts) }
+
+ let!(:project_callouts_1) { project_callout.create!(project_id: project.id, user_id: user.id, feature_name: 1) }
+ let!(:project_callouts_3) { project_callout.create!(project_id: project.id, user_id: user.id, feature_name: 3) }
+
+ it 'deletes only feature name 3' do
+ expect { migrate! }.to change { project_callout.count }.from(2).to(1)
+ expect(project_callout.find_by_id(project_callouts_3.id)).to be_nil
+ end
+end
diff --git a/spec/migrations/20230822151454_remove_free_user_cap_email_workers_spec.rb b/spec/migrations/20230822151454_remove_free_user_cap_email_workers_spec.rb
new file mode 100644
index 00000000000..fd56c9a0988
--- /dev/null
+++ b/spec/migrations/20230822151454_remove_free_user_cap_email_workers_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveFreeUserCapEmailWorkers, :migration, feature_category: :onboarding do
+ describe '#up' do
+ it 'calls sidekiq_remove_jobs with correct argument' do
+ deprecated_job_classes = %w[
+ Namespaces::FreeUserCap::BackfillNotificationClearingJobsWorker
+ Namespaces::FreeUserCap::BackfillNotificationJobsWorker
+ Namespaces::FreeUserCap::NotificationClearingWorker
+ Namespaces::FreeUserCap::OverLimitNotificationWorker
+ ]
+
+ expect_next_instance_of(described_class) do |migration|
+ expect(migration).to receive(:sidekiq_remove_jobs)
+ .with({ job_klasses: deprecated_job_classes })
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/20230823090001_queue_backfill_project_statistics_storage_size_with_recent_size_spec.rb b/spec/migrations/20230823090001_queue_backfill_project_statistics_storage_size_with_recent_size_spec.rb
new file mode 100644
index 00000000000..07e15663d1d
--- /dev/null
+++ b/spec/migrations/20230823090001_queue_backfill_project_statistics_storage_size_with_recent_size_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillProjectStatisticsStorageSizeWithRecentSize, feature_category: :consumables_cost_management do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :project_statistics,
+ column_name: :project_id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230823140934_add_linked_items_widget_to_ticket_work_item_type_spec.rb b/spec/migrations/20230823140934_add_linked_items_widget_to_ticket_work_item_type_spec.rb
new file mode 100644
index 00000000000..6a83b4b1a7c
--- /dev/null
+++ b/spec/migrations/20230823140934_add_linked_items_widget_to_ticket_work_item_type_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddLinkedItemsWidgetToTicketWorkItemType, :migration, feature_category: :portfolio_management do
+ it_behaves_like 'migration that adds a widget to a work item type' do
+ let(:target_type_enum_value) { described_class::TICKET_ENUM_VALUE }
+ let(:target_type) { :ticket }
+ let(:additional_types) { { ticket: 8 } }
+ let(:widgets_for_type) do
+ {
+ 'Assignees' => 0,
+ 'Description' => 1,
+ 'Hierarchy' => 2,
+ 'Labels' => 3,
+ 'Notes' => 5,
+ 'Iteration' => 9,
+ 'Milestone' => 4,
+ 'Weight' => 8,
+ 'Current user todos' => 15,
+ 'Start and due date' => 6,
+ 'Health status' => 7,
+ 'Notifications' => 14,
+ 'Award emoji' => 16
+ }.freeze
+ end
+ end
+end
diff --git a/spec/migrations/20230830121830_queue_update_users_set_external_if_service_account_spec.rb b/spec/migrations/20230830121830_queue_update_users_set_external_if_service_account_spec.rb
new file mode 100644
index 00000000000..12839e0852b
--- /dev/null
+++ b/spec/migrations/20230830121830_queue_update_users_set_external_if_service_account_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueUpdateUsersSetExternalIfServiceAccount, feature_category: :system_access do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :users,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL.to_i,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230831084632_queue_sync_scan_result_policies_spec.rb b/spec/migrations/20230831084632_queue_sync_scan_result_policies_spec.rb
new file mode 100644
index 00000000000..3c4a7382e02
--- /dev/null
+++ b/spec/migrations/20230831084632_queue_sync_scan_result_policies_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueSyncScanResultPolicies, feature_category: :security_policy_management do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :security_orchestration_policy_configurations,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230906204934_restart_self_hosted_sent_notifications_bigint_conversion_spec.rb b/spec/migrations/20230906204934_restart_self_hosted_sent_notifications_bigint_conversion_spec.rb
new file mode 100644
index 00000000000..01dbb5d1ef8
--- /dev/null
+++ b/spec/migrations/20230906204934_restart_self_hosted_sent_notifications_bigint_conversion_spec.rb
@@ -0,0 +1,144 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+def column_type_from_table(table, column)
+ table.columns.find { |c| c.name == column }.sql_type
+end
+
+RSpec.describe RestartSelfHostedSentNotificationsBigintConversion, feature_category: :database do
+ let(:sent_notifications) { table(:sent_notifications) }
+
+ before do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(!self_hosted)
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+
+ context 'when is self-hosted' do
+ let(:self_hosted) { true }
+
+ describe '#up' do
+ context 'when id is already a bigint' do
+ it 'does nothing' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ sent_notifications.reset_column_information
+ expect(column_type_from_table(sent_notifications, 'id')).to eq('bigint')
+ }
+ migration.after -> {
+ sent_notifications.reset_column_information
+ expect(column_type_from_table(sent_notifications, 'id')).to eq('bigint')
+ }
+ end
+ end
+ end
+ end
+
+ context 'when id is an integer and id_convert_to_bigint exists' do
+ before do
+ conn = described_class.new.connection
+ conn.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE integer')
+ conn.execute('ALTER TABLE sent_notifications ADD COLUMN id_convert_to_bigint BIGINT')
+ sent_notifications.reset_column_information
+ end
+
+ after do
+ conn = described_class.new.connection
+ conn.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE bigint')
+ conn.execute('ALTER TABLE sent_notifications DROP COLUMN id_convert_to_bigint')
+ sent_notifications.reset_column_information
+ end
+
+ it 'does nothing' do
+ disable_migrations_output do
+ expect(column_type_from_table(sent_notifications, 'id')).to eq('integer')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }).not_to be_nil
+ migrate!
+ expect(column_type_from_table(sent_notifications, 'id')).to eq('integer')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }).not_to be_nil
+ end
+ end
+ end
+
+ context 'when id is an integer and id_convert_to_bigint does not exist' do
+ before do
+ conn = described_class.new.connection
+ conn.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE integer')
+ conn.execute('ALTER TABLE sent_notifications DROP COLUMN IF EXISTS id_convert_to_bigint')
+ sent_notifications.reset_column_information
+ end
+
+ after do
+ conn = described_class.new.connection
+ conn.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE bigint')
+ conn.execute('ALTER TABLE sent_notifications DROP COLUMN IF EXISTS id_convert_to_bigint')
+ sent_notifications.reset_column_information
+ end
+
+ it 'creates id_convert_to_bigint' do
+ disable_migrations_output do
+ expect(column_type_from_table(sent_notifications, 'id')).to eq('integer')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be_nil
+ migrate!
+ sent_notifications.reset_column_information
+ expect(column_type_from_table(sent_notifications, 'id')).to eq('integer')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }).not_to be_nil
+ end
+ end
+ end
+ end
+
+ describe '#down' do
+ context 'when id is an integer and id_convert_to_bigint exists' do
+ before do
+ conn = described_class.new.connection
+ conn.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE integer')
+ conn.execute('ALTER TABLE sent_notifications ADD COLUMN id_convert_to_bigint BIGINT')
+ sent_notifications.reset_column_information
+ end
+
+ after do
+ conn = described_class.new.connection
+ conn.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE bigint')
+ conn.execute('ALTER TABLE sent_notifications DROP COLUMN IF EXISTS id_convert_to_bigint')
+ sent_notifications.reset_column_information
+ end
+
+ it 'drops id_convert_to_bigint' do
+ disable_migrations_output do
+ migrate!
+ schema_migrate_down!
+ end
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be_nil
+ end
+ end
+ end
+ end
+
+ context 'when is not self-hosted' do
+ let(:self_hosted) { false }
+
+ describe '#up' do
+ it 'is a bigint and result in no change' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ sent_notifications.reset_column_information
+ expect(sent_notifications.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ }
+ migration.after -> {
+ sent_notifications.reset_column_information
+ expect(sent_notifications.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ end
+
+ # Do not need to describe #down since it's a no-op and we did reversible test above
+ end
+end
diff --git a/spec/migrations/20230906204935_restart_self_hosted_sent_notifications_backfill_spec.rb b/spec/migrations/20230906204935_restart_self_hosted_sent_notifications_backfill_spec.rb
new file mode 100644
index 00000000000..f2c9ce3d005
--- /dev/null
+++ b/spec/migrations/20230906204935_restart_self_hosted_sent_notifications_backfill_spec.rb
@@ -0,0 +1,162 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+def column_type_from_table(table, column)
+ table.columns.find { |c| c.name == column }.sql_type
+end
+
+def sent_notifications_backfills(connection)
+ res = connection.execute <<~SQL
+ SELECT * FROM batched_background_migrations WHERE table_name = 'sent_notifications'
+ SQL
+
+ res.ntuples
+end
+
+def create_previous_backfill(connection)
+ connection.execute <<~SQL
+ INSERT INTO batched_background_migrations
+ (min_value, max_value, batch_size, sub_batch_size, interval, "status",#{' '}
+ job_class_name, batch_class_name,
+ table_name, column_name, job_arguments,
+ gitlab_schema, created_at, updated_at)
+ VALUES
+ (1, 3, 20000, 1000, 120, 3,
+ 'CopyColumnUsingBackgroundMigrationJob', 'PrimaryKeyBatchingStrategy',
+ 'sent_notifications', 'id', '[["id"], ["id_convert_to_bigint"]]',
+ 'gitlab_main', NOW(), NOW())
+ SQL
+end
+
+RSpec.describe RestartSelfHostedSentNotificationsBackfill, feature_category: :database do
+ let(:sent_notifications) { table(:sent_notifications) }
+
+ before do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(!self_hosted)
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+
+ describe '#up' do
+ context 'when is self-hosted' do
+ let(:self_hosted) { true }
+
+ context 'when id is integer' do
+ before do
+ described_class.new.connection.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE integer')
+ described_class.new.connection.execute(
+ 'ALTER TABLE sent_notifications ADD COLUMN IF NOT EXISTS id_convert_to_bigint BIGINT'
+ )
+ sent_notifications.reset_column_information
+ end
+
+ after do
+ described_class.new.connection.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE bigint')
+ described_class.new.connection.execute(
+ 'ALTER TABLE sent_notifications DROP COLUMN IF EXISTS id_convert_to_bigint'
+ )
+ sent_notifications.reset_column_information
+ end
+
+ context 'when a backfill has never been done' do
+ let(:id_convert_to_bigint_sample) { 0 }
+
+ before do
+ described_class.new.connection.execute <<~SQL
+ INSERT INTO
+ sent_notifications
+ (id_convert_to_bigint, reply_key)
+ VALUES (#{id_convert_to_bigint_sample}, 4)
+ SQL
+ end
+
+ after do
+ described_class.new.connection.execute <<~SQL
+ DELETE FROM sent_notifications
+ SQL
+ end
+
+ context 'when there is a record of an incomplete backfill' do
+ before do
+ create_previous_backfill(described_class.new.connection)
+ end
+
+ after do
+ described_class.new.connection.execute <<~SQL
+ DELETE FROM batched_background_migrations
+ SQL
+ end
+
+ it 'calls delete_batched_background_migration and does not raise an error' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:delete_batched_background_migration)
+ end
+ disable_migrations_output do
+ expect { migrate! }.not_to raise_error
+ end
+ expect(sent_notifications_backfills(described_class.new.connection)).to eq 1
+ end
+ end
+
+ context 'when there is no previous record of a backfill' do
+ it 'begins a backfill' do
+ disable_migrations_output do
+ migrate!
+ end
+ expect(sent_notifications_backfills(described_class.new.connection)).to eq 1
+ end
+ end
+ end
+
+ context 'when a backfill has previously been done' do
+ let(:id_convert_to_bigint_sample) { 4 }
+
+ before do
+ described_class.new.connection.execute <<~SQL
+ INSERT INTO
+ sent_notifications
+ (id_convert_to_bigint, reply_key)
+ VALUES (#{id_convert_to_bigint_sample}, 4)
+ SQL
+ end
+
+ after do
+ described_class.new.connection.execute <<~SQL
+ DELETE FROM sent_notifications
+ SQL
+ end
+
+ it 'does not start a backfill' do
+ disable_migrations_output do
+ migrate!
+ end
+ expect(sent_notifications_backfills(described_class.new.connection)).to eq 0
+ end
+ end
+ end
+
+ context 'when id is a bigint' do
+ it 'does not start a backfill' do
+ disable_migrations_output do
+ migrate!
+ end
+ expect(sent_notifications_backfills(described_class.new.connection)).to eq 0
+ end
+ end
+ end
+
+ context 'when is not self-hosted' do
+ let(:self_hosted) { false }
+
+ it 'does not start a backfill' do
+ disable_migrations_output do
+ migrate!
+ end
+ expect(sent_notifications_backfills(described_class.new.connection)).to eq 0
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230907155247_queue_backfill_has_merge_request_of_vulnerability_reads_spec.rb b/spec/migrations/20230907155247_queue_backfill_has_merge_request_of_vulnerability_reads_spec.rb
new file mode 100644
index 00000000000..7214e0114d4
--- /dev/null
+++ b/spec/migrations/20230907155247_queue_backfill_has_merge_request_of_vulnerability_reads_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillHasMergeRequestOfVulnerabilityReads, feature_category: :database do
+ let!(:batched_migration) { described_class::MIGRATION_NAME }
+
+ 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: :vulnerability_reads,
+ column_name: :vulnerability_id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/backfill_alert_management_prometheus_integrations_spec.rb b/spec/migrations/backfill_alert_management_prometheus_integrations_spec.rb
new file mode 100644
index 00000000000..dcc364aa44a
--- /dev/null
+++ b/spec/migrations/backfill_alert_management_prometheus_integrations_spec.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillAlertManagementPrometheusIntegrations, feature_category: :incident_management do
+ let(:namespace_class) { table(:namespaces) }
+ let(:project_class) { table(:projects) }
+ let(:settings_class) { table(:project_alerting_settings) }
+ let(:http_integrations_class) { table(:alert_management_http_integrations) }
+ let(:integration_class) { table(:integrations) }
+
+ let!(:namespace_1) { namespace_class.create!(name: "namespace_1", path: "namespace_1") }
+ let!(:namespace_2) { namespace_class.create!(name: "namespace_2", path: "namespace_2") }
+ let!(:namespace_3) { namespace_class.create!(name: "namespace_3", path: "namespace_3") }
+ let!(:project_1) { project_class.create!(project_namespace_id: namespace_1.id, namespace_id: namespace_1.id) }
+ let!(:project_2) { project_class.create!(project_namespace_id: namespace_2.id, namespace_id: namespace_1.id) }
+ let!(:project_3) { project_class.create!(project_namespace_id: namespace_3.id, namespace_id: namespace_1.id) }
+
+ let!(:http_integrations) do
+ [
+ create_http_integration(project_2, 'legacy', name: 'Legacy HTTP'),
+ create_http_integration(project_2, 'other', name: 'Other Prometheus', type: 1)
+ ]
+ end
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 1)
+
+ # disabled integration
+ create_prometheus_integration(project_1, active: false)
+ create_alerting_settings(project_1, token: :a)
+
+ # enabled integration
+ create_prometheus_integration(project_2, active: true)
+ create_alerting_settings(project_2, token: :b)
+
+ # settings without integration
+ create_alerting_settings(project_3, token: :c)
+
+ # Should ignore: another type of integration in the same project
+ integration_class.create!(
+ project_id: project_3.id,
+ type_new: 'Integrations::Bamboo',
+ active: true
+ )
+ end
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(http_integrations_class.all).to match_array(http_integrations)
+ }
+
+ migration.after -> {
+ expect(http_integrations_class.all).to contain_exactly(
+ *http_integrations,
+ expected_http_integration(project_1, token: :a, active: false),
+ expected_http_integration(project_2, token: :b, active: true),
+ expected_http_integration(project_3, token: :c, active: false)
+ )
+ }
+ end
+ end
+
+ context 'with existing synced http integrations' do
+ let(:synced_integration) do
+ create_http_integration(project_2, 'legacy-prometheus', name: 'Prometheus', active: false)
+ end
+
+ let!(:http_integrations) { [synced_integration] }
+
+ it 'does not overwrite synced attributes' do
+ expect { migrate! }.to not_change { synced_integration.attributes }
+
+ expect(http_integrations_class.all).to contain_exactly(
+ expected_http_integration(project_1, token: :a, active: false),
+ synced_integration,
+ expected_http_integration(project_3, token: :c, active: false)
+ )
+ end
+ end
+
+ private
+
+ def create_prometheus_integration(project, active: true, **args)
+ integration_class.create!(
+ project_id: project.id,
+ type_new: 'Integrations::Prometheus',
+ active: active,
+ **args
+ )
+ end
+
+ def create_alerting_settings(project, token:)
+ settings_class.create!(
+ project_id: project.id,
+ encrypted_token: "token_#{token}",
+ encrypted_token_iv: "iv_#{token}"
+ )
+ end
+
+ def create_http_integration(project, endpoint_id, type: 0, **args)
+ http_integrations_class.create!(
+ project_id: project.id,
+ active: true,
+ encrypted_token_iv: 'iv',
+ encrypted_token: 'token',
+ endpoint_identifier: endpoint_id,
+ type_identifier: type,
+ **args
+ )
+ end
+
+ def expected_http_integration(project, token:, active:)
+ having_attributes(
+ project_id: project.id,
+ active: active,
+ encrypted_token: "token_#{token}",
+ encrypted_token_iv: "iv_#{token}",
+ name: 'Prometheus',
+ endpoint_identifier: 'legacy-prometheus',
+ type_identifier: 1
+ )
+ end
+end
diff --git a/spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb b/spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb
new file mode 100644
index 00000000000..482cca67e46
--- /dev/null
+++ b/spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_self_managed_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureMrUserMentionsNoteIdBigintBackfillIsFinishedForSelfManaged, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'merge_request_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for self-managed instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_for_self_managed_spec.rb b/spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_for_self_managed_spec.rb
new file mode 100644
index 00000000000..5cba691e20e
--- /dev/null
+++ b/spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_for_self_managed_spec.rb
@@ -0,0 +1,135 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapMergeRequestUserMentionsNoteIdToBigintForSelfManaged, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:merge_request_user_mentions) { table(:merge_request_user_mentions) }
+
+ shared_examples 'column `note_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE merge_request_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute('ALTER TABLE merge_request_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ after do
+ connection.execute('ALTER TABLE merge_request_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ merge_request_user_mentions.reset_column_information
+
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ merge_request_user_mentions.reset_column_information
+
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `note_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE merge_request_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE merge_request_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE merge_request_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE merge_request_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute(
+ 'ALTER TABLE merge_request_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint bigint'
+ )
+ connection.execute('ALTER TABLE merge_request_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ connection.execute(
+ 'DROP INDEX IF EXISTS index_merge_request_user_mentions_on_note_id_convert_to_bigint CASCADE'
+ )
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_bfcbace4260d() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."note_id_convert_to_bigint" := NEW."note_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE merge_request_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ merge_request_user_mentions.reset_column_information
+
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(merge_request_user_mentions.columns.find do |c|
+ c.name == 'note_id_convert_to_bigint'
+ end.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ merge_request_user_mentions.reset_column_information
+
+ expect(merge_request_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(merge_request_user_mentions.columns.find do |c|
+ c.name == 'note_id_convert_to_bigint'
+ end.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end