diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-20 14:18:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-20 14:18:08 +0300 |
commit | 5afcbe03ead9ada87621888a31a62652b10a7e4f (patch) | |
tree | 9918b67a0d0f0bafa6542e839a8be37adf73102d /spec/migrations | |
parent | c97c0201564848c1f53226fe19d71fdcc472f7d0 (diff) |
Add latest changes from gitlab-org/gitlab@16-4-stable-eev16.4.0-rc42
Diffstat (limited to 'spec/migrations')
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 |