diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-19 23:18:09 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-19 23:18:09 +0000 |
commit | 6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch) | |
tree | dc4d20fe6064752c0bd323187252c77e0a89144b /spec/migrations | |
parent | 9868dae7fc0655bd7ce4a6887d4e6d487690eeed (diff) | |
download | gitlab-ce-6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde.tar.gz |
Add latest changes from gitlab-org/gitlab@15-4-stable-eev15.4.0-rc42
Diffstat (limited to 'spec/migrations')
26 files changed, 740 insertions, 28 deletions
diff --git a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb b/spec/migrations/20210804150320_create_base_work_item_types_spec.rb index 6df8e1b2ebf..ae510826fe1 100644 --- a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb +++ b/spec/migrations/20210804150320_create_base_work_item_types_spec.rb @@ -10,9 +10,9 @@ RSpec.describe CreateBaseWorkItemTypes, :migration do let(:base_types) do { - issue: 0, - incident: 1, - test_case: 2, + issue: 0, + incident: 1, + test_case: 2, requirement: 3 } end diff --git a/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb b/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb index f734456b0b6..c88f94c6426 100644 --- a/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb +++ b/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb @@ -48,7 +48,7 @@ RSpec.describe RemoveDuplicateProjectAuthorizations, :migration do project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::REPORTER end - it { expect { subject }.to change { ProjectAuthorization.count}.from(3).to(1) } + it { expect { subject }.to change { ProjectAuthorization.count }.from(3).to(1) } it 'retains the highest access level' do subject diff --git a/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb b/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb index 1957a973ee1..552602983d9 100644 --- a/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb +++ b/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb @@ -10,9 +10,9 @@ RSpec.describe UpsertBaseWorkItemTypes, :migration do let(:base_types) do { - issue: 0, - incident: 1, - test_case: 2, + issue: 0, + incident: 1, + test_case: 2, requirement: 3 } end diff --git a/spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb b/spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb index c90eabbe4eb..69ee10eb0d1 100644 --- a/spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb +++ b/spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb @@ -39,7 +39,7 @@ RSpec.describe UpdateReportTypeForExistingApprovalProjectRules, :migration do end context 'with the rule name set to another value (e.g., Test Rule)' do - let(:rule_name) { 'Test Rule'} + let(:rule_name) { 'Test Rule' } it 'does not update report_type' do expect { migrate! }.not_to change { approval_project_rule.reload.report_type } diff --git a/spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb b/spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb index 6a82ed016af..ef6dd94d9e3 100644 --- a/spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb +++ b/spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb @@ -33,11 +33,11 @@ RSpec.describe MigrateRemainingU2fRegistrations, :migration do device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5), { key_handle: SecureRandom.random_bytes(255) }) public_key ||= Base64.strict_encode64(device.origin_public_key_raw) u2f_registrations.create!({ id: id, - certificate: Base64.strict_encode64(device.cert_raw), - key_handle: U2F.urlsafe_encode64(device.key_handle_raw), - public_key: public_key, - counter: 5, - name: name, - user_id: user.id }) + certificate: Base64.strict_encode64(device.cert_raw), + key_handle: U2F.urlsafe_encode64(device.key_handle_raw), + public_key: public_key, + counter: 5, + name: name, + user_id: user.id }) end end diff --git a/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb b/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb index b80e4703f07..34a6e2fdd12 100644 --- a/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb +++ b/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb @@ -10,11 +10,11 @@ RSpec.describe AddTaskToWorkItemTypes, :migration do let(:base_types) do { - issue: 0, - incident: 1, - test_case: 2, + issue: 0, + incident: 1, + test_case: 2, requirement: 3, - task: 4 + task: 4 } end diff --git a/spec/migrations/20220601110011_schedule_remove_self_managed_wiki_notes_spec.rb b/spec/migrations/20220601110011_schedule_remove_self_managed_wiki_notes_spec.rb new file mode 100644 index 00000000000..44e80980b27 --- /dev/null +++ b/spec/migrations/20220601110011_schedule_remove_self_managed_wiki_notes_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleRemoveSelfManagedWikiNotes do + let_it_be(:batched_migration) { described_class::MIGRATION } + + it 'schedules 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: :notes, + column_name: :id, + interval: described_class::INTERVAL + ) + } + end + end + + context 'with com? or staging?' do + before do + allow(::Gitlab).to receive(:com?).and_return(true) + allow(::Gitlab).to receive(:staging?).and_return(false) + end + + it 'does not schedule 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/20220606080509_fix_incorrect_job_artifacts_expire_at_spec.rb b/spec/migrations/20220606080509_fix_incorrect_job_artifacts_expire_at_spec.rb new file mode 100644 index 00000000000..5921dd64c0e --- /dev/null +++ b/spec/migrations/20220606080509_fix_incorrect_job_artifacts_expire_at_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixIncorrectJobArtifactsExpireAt, migration: :gitlab_ci do + let_it_be(:batched_migration) { described_class::MIGRATION } + + it 'does not schedule background jobs when Gitlab.com is true' do + allow(Gitlab).to receive(:com?).and_return(true) + + 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 + + it 'schedules background job on non Gitlab.com' do + allow(Gitlab).to receive(:com?).and_return(false) + + 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( + gitlab_schema: :gitlab_ci, + table_name: :ci_job_artifacts, + column_name: :id, + interval: described_class::INTERVAL, + batch_size: described_class::BATCH_SIZE + ) + } + end + end +end diff --git a/spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb b/spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb new file mode 100644 index 00000000000..fdd97f2d008 --- /dev/null +++ b/spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleDisableLegacyOpenSourceLicenceForRecentPublicProjects, schema: 20220801155858 do + context 'when on gitlab.com' do + let(:background_migration) { described_class::MIGRATION } + let(:migration) { described_class.new } + + before do + allow(Gitlab).to receive(:com?).and_return(true) + migration.up + end + + describe '#up' do + it 'schedules background jobs for each batch of projects' do + expect(background_migration).to( + have_scheduled_batched_migration( + table_name: :projects, + column_name: :id, + interval: described_class::INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migration.down + + expect(described_class::MIGRATION).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instances' do + let(:migration) { described_class.new } + + before do + allow(Gitlab).to receive(:com?).and_return(false) + end + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20220809002011_schedule_destroy_invalid_group_members_spec.rb b/spec/migrations/20220809002011_schedule_destroy_invalid_group_members_spec.rb new file mode 100644 index 00000000000..31dd4344d9f --- /dev/null +++ b/spec/migrations/20220809002011_schedule_destroy_invalid_group_members_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleDestroyInvalidGroupMembers, :migration do + let_it_be(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background jobs for each batch of members' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :members, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb b/spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb new file mode 100644 index 00000000000..5a5e2362a53 --- /dev/null +++ b/spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe UpdateStartDateForIterationsCadences, :freeze_time do + let(:migration) { described_class.new } + let(:namespaces) { table(:namespaces) } + let(:sprints) { table(:sprints) } + let(:iterations_cadences) { table(:iterations_cadences) } + + let!(:group1) { namespaces.create!(name: 'abc', path: 'abc') } + let!(:group2) { namespaces.create!(name: 'def', path: 'def') } + + let(:first_upcoming_start_date) { Date.current + 2.weeks } + let(:original_cadence_start_date) { Date.current - 1.week } + + # rubocop: disable Layout/LineLength + let!(:auto_cadence1) { iterations_cadences.create!(start_date: original_cadence_start_date, group_id: group1.id, title: "ic") } + let!(:auto_cadence2) { iterations_cadences.create!(start_date: original_cadence_start_date, group_id: group1.id, title: "ic") } + let!(:auto_cadence3) { iterations_cadences.create!(start_date: nil, group_id: group2.id, title: "ic") } + let!(:manual_cadence1) { iterations_cadences.create!(start_date: Date.current, group_id: group1.id, automatic: false, title: "ic") } + let!(:manual_cadence2) { iterations_cadences.create!(start_date: Date.current, group_id: group2.id, automatic: false, title: "ic") } + # rubocop: enable Layout/LineLength + + def cadence_params(cadence) + { iterations_cadence_id: cadence.id, group_id: cadence.group_id } + end + + before do + # Past iteratioin + sprints.create!(id: 1, iid: 1, **cadence_params(auto_cadence1), + start_date: Date.current - 1.week, due_date: Date.current - 1.day) + # Current iteraition + sprints.create!(id: 3, iid: 5, **cadence_params(auto_cadence1), + start_date: Date.current, due_date: Date.current + 1.week) + # First upcoming iteration + sprints.create!(id: 4, iid: 8, **cadence_params(auto_cadence1), + start_date: first_upcoming_start_date, due_date: first_upcoming_start_date + 1.week) + # Second upcoming iteration + sprints.create!(id: 5, iid: 9, **cadence_params(auto_cadence1), + start_date: first_upcoming_start_date + 2.weeks, due_date: first_upcoming_start_date + 3.weeks) + + sprints.create!(id: 6, iid: 1, **cadence_params(manual_cadence2), + start_date: Date.current, due_date: Date.current + 1.week) + sprints.create!(id: 7, iid: 5, **cadence_params(manual_cadence2), + start_date: Date.current + 2.weeks, due_date: Date.current + 3.weeks) + end + + describe '#up' do + it "updates the start date of an automatic cadence to the start date of its first upcoming sprint record." do + expect { migration.up } + .to change { auto_cadence1.reload.start_date }.to(first_upcoming_start_date) + .and not_change { auto_cadence2.reload.start_date } # the cadence doesn't have any upcoming iteration. + .and not_change { auto_cadence3.reload.start_date } # the cadence is empty; it has no iterations. + .and not_change { manual_cadence1.reload.start_date } # manual cadence don't need to be touched. + .and not_change { manual_cadence2.reload.start_date } # manual cadence don't need to be touched. + end + end + + describe '#down' do + it "updates the start date of an automatic cadence to the start date of its earliest sprint record." do + migration.up + + expect { migration.down } + .to change { auto_cadence1.reload.start_date }.to(original_cadence_start_date) + .and not_change { auto_cadence2.reload.start_date } # the cadence is empty; it has no iterations. + .and not_change { manual_cadence1.reload.start_date } # manual cadence don't need to be touched. + .and not_change { manual_cadence2.reload.start_date } # manual cadence don't need to be touched. + end + end +end diff --git a/spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb b/spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb new file mode 100644 index 00000000000..c53dd9de649 --- /dev/null +++ b/spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "spec_helper" + +require_migration! + +RSpec.describe AddVulnerabilityAdvisoryForeignKeyToSbomVulnerableComponentVersions do + let(:table) { described_class::SOURCE_TABLE } + let(:column) { described_class::COLUMN } + let(:foreign_key) { -> { described_class.new.foreign_keys_for(table, column).first } } + + it "creates and drops the foreign key" do + reversible_migration do |migration| + migration.before -> do + expect(foreign_key.call).to be(nil) + end + + migration.after -> do + expect(foreign_key.call).to have_attributes(column: column.to_s) + end + end + end +end diff --git a/spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb b/spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb new file mode 100644 index 00000000000..b9cb6891681 --- /dev/null +++ b/spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "spec_helper" + +require_migration! + +RSpec.describe AddSbomComponentVersionForeignKeyToSbomVulnerableComponentVersions do + let(:table) { described_class::SOURCE_TABLE } + let(:column) { described_class::COLUMN } + let(:foreign_key) { -> { described_class.new.foreign_keys_for(table, column).first } } + + it "creates and drops the foreign key" do + reversible_migration do |migration| + migration.before -> do + expect(foreign_key.call).to be(nil) + end + + migration.after -> do + expect(foreign_key.call).to have_attributes(column: column.to_s) + end + end + end +end diff --git a/spec/migrations/20220901035725_schedule_destroy_invalid_project_members_spec.rb b/spec/migrations/20220901035725_schedule_destroy_invalid_project_members_spec.rb new file mode 100644 index 00000000000..ed9f7e3cd44 --- /dev/null +++ b/spec/migrations/20220901035725_schedule_destroy_invalid_project_members_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleDestroyInvalidProjectMembers, :migration do + let_it_be(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background jobs for each batch of members' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :members, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb b/spec/migrations/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb new file mode 100644 index 00000000000..e4ac094ab48 --- /dev/null +++ b/spec/migrations/20220906074449_schedule_disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleDisableLegacyOpenSourceLicenseForProjectsLessThanOneMb do + let_it_be(:migration) { described_class.new } + let_it_be(:post_migration) { described_class::MIGRATION } + + context 'when on gitlab.com' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of project_settings' do + migration.up + + expect(post_migration).to( + have_scheduled_batched_migration( + table_name: :project_settings, + column_name: :project_id, + interval: described_class::INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migration.down + + expect(post_migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + before do + allow(Gitlab).to receive(:com?).and_return(false) + end + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20220913030624_cleanup_attention_request_related_system_notes_spec.rb b/spec/migrations/20220913030624_cleanup_attention_request_related_system_notes_spec.rb new file mode 100644 index 00000000000..7338a6ab9ae --- /dev/null +++ b/spec/migrations/20220913030624_cleanup_attention_request_related_system_notes_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe CleanupAttentionRequestRelatedSystemNotes, :migration do + let(:notes) { table(:notes) } + let(:system_note_metadata) { table(:system_note_metadata) } + + it 'removes all notes with attention request related system_note_metadata' do + notes.create!(id: 1, note: 'Attention request note', noteable_type: 'MergeRequest') + notes.create!(id: 2, note: 'Attention request remove note', noteable_type: 'MergeRequest') + notes.create!(id: 3, note: 'MergeRequest note', noteable_type: 'MergeRequest') + notes.create!(id: 4, note: 'Commit note', noteable_type: 'Commit') + system_note_metadata.create!(id: 11, action: 'attention_requested', note_id: 1) + system_note_metadata.create!(id: 22, action: 'attention_request_removed', note_id: 2) + system_note_metadata.create!(id: 33, action: 'merged', note_id: 3) + + expect { migrate! }.to change(notes, :count).by(-2) + + expect(system_note_metadata.where(action: %w[attention_requested attention_request_removed]).size).to eq(0) + expect(notes.where(noteable_type: 'MergeRequest').size).to eq(1) + expect(notes.where(noteable_type: 'Commit').size).to eq(1) + expect(system_note_metadata.where(action: 'merged').size).to eq(1) + end +end diff --git a/spec/migrations/backfill_namespace_id_on_issues_spec.rb b/spec/migrations/backfill_namespace_id_on_issues_spec.rb new file mode 100644 index 00000000000..2721d7ce8f1 --- /dev/null +++ b/spec/migrations/backfill_namespace_id_on_issues_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe BackfillNamespaceIdOnIssues, :migration do + let(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background jobs for each batch of issues' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :issues, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/change_task_system_note_wording_to_checklist_item_spec.rb b/spec/migrations/change_task_system_note_wording_to_checklist_item_spec.rb new file mode 100644 index 00000000000..039ee92f8bd --- /dev/null +++ b/spec/migrations/change_task_system_note_wording_to_checklist_item_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ChangeTaskSystemNoteWordingToChecklistItem, :migration do + let(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules a batched background migration' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :system_note_metadata, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/confirm_support_bot_user_spec.rb b/spec/migrations/confirm_support_bot_user_spec.rb index f6bcab4aa7d..c60c7fe45f7 100644 --- a/spec/migrations/confirm_support_bot_user_spec.rb +++ b/spec/migrations/confirm_support_bot_user_spec.rb @@ -52,7 +52,7 @@ RSpec.describe ConfirmSupportBotUser, :migration do end it 'does not change the `created_at` attribute' do - expect { migrate!}.not_to change { support_bot.reload.created_at }.from(nil) + expect { migrate! }.not_to change { support_bot.reload.created_at }.from(nil) end end diff --git a/spec/migrations/move_security_findings_table_to_gitlab_partitions_dynamic_schema_spec.rb b/spec/migrations/move_security_findings_table_to_gitlab_partitions_dynamic_schema_spec.rb new file mode 100644 index 00000000000..b5bb86edce2 --- /dev/null +++ b/spec/migrations/move_security_findings_table_to_gitlab_partitions_dynamic_schema_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe MoveSecurityFindingsTableToGitlabPartitionsDynamicSchema do + let(:partitions_sql) do + <<~SQL + SELECT + partitions.relname AS partition_name + FROM pg_inherits + JOIN pg_class parent ON pg_inherits.inhparent = parent.oid + JOIN pg_class partitions ON pg_inherits.inhrelid = partitions.oid + WHERE + parent.relname = 'security_findings' + SQL + end + + describe '#up' do + it 'changes the `security_findings` table to be partitioned' do + expect { migrate! }.to change { security_findings_partitioned? }.from(false).to(true) + .and change { execute(partitions_sql) }.from([]).to(['security_findings_1']) + end + end + + describe '#down' do + context 'when there is a partition' do + let(:users) { table(:users) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:scanners) { table(:vulnerability_scanners) } + let(:security_scans) { table(:security_scans) } + let(:security_findings) { table(:security_findings) } + + let(:user) { users.create!(email: 'test@gitlab.com', projects_limit: 5) } + let(:namespace) { namespaces.create!(name: 'gtlb', path: 'gitlab', type: Namespaces::UserNamespace.sti_name) } + let(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id, name: 'foo') } + let(:scanner) { scanners.create!(project_id: project.id, external_id: 'bandit', name: 'Bandit') } + let(:security_scan) { security_scans.create!(build_id: 1, scan_type: 1) } + + let(:security_findings_count_sql) { 'SELECT COUNT(*) FROM security_findings' } + + before do + migrate! + + security_findings.create!( + scan_id: security_scan.id, + scanner_id: scanner.id, + uuid: SecureRandom.uuid, + severity: 0, + confidence: 0 + ) + end + + it 'creates the original table with the data from the existing partition' do + expect { schema_migrate_down! }.to change { security_findings_partitioned? }.from(true).to(false) + .and not_change { execute(security_findings_count_sql) }.from([1]) + end + + context 'when there are more than one partitions' do + before do + migrate! + + execute(<<~SQL) + CREATE TABLE gitlab_partitions_dynamic.security_findings_11 + PARTITION OF security_findings FOR VALUES IN (11) + SQL + end + + it 'creates the original table from the latest existing partition' do + expect { schema_migrate_down! }.to change { security_findings_partitioned? }.from(true).to(false) + .and change { execute(security_findings_count_sql) }.from([1]).to([0]) + end + end + end + + context 'when there is no partition' do + before do + migrate! + + execute(partitions_sql).each do |partition_name| + execute("DROP TABLE gitlab_partitions_dynamic.#{partition_name}") + end + end + + it 'creates the original table' do + expect { schema_migrate_down! }.to change { security_findings_partitioned? }.from(true).to(false) + end + end + end + + def security_findings_partitioned? + sql = <<~SQL + SELECT + COUNT(*) + FROM + pg_partitioned_table + INNER JOIN pg_class ON pg_class.oid = pg_partitioned_table.partrelid + WHERE pg_class.relname = 'security_findings' + SQL + + execute(sql).first != 0 + end + + def execute(sql) + ActiveRecord::Base.connection.execute(sql).values.flatten + end +end diff --git a/spec/migrations/orphaned_invited_members_cleanup_spec.rb b/spec/migrations/orphaned_invited_members_cleanup_spec.rb new file mode 100644 index 00000000000..4427e707f56 --- /dev/null +++ b/spec/migrations/orphaned_invited_members_cleanup_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe OrphanedInvitedMembersCleanup, :migration do + describe '#up', :aggregate_failures do + it 'removes accepted members with no associated user' do + user = create_user!('testuser1') + + create_member(invite_token: nil, invite_accepted_at: 1.day.ago) + record2 = create_member(invite_token: nil, invite_accepted_at: 1.day.ago, user_id: user.id) + record3 = create_member(invite_token: 'foo2', invite_accepted_at: nil) + record4 = create_member(invite_token: 'foo3', invite_accepted_at: 1.day.ago) + + migrate! + + expect(table(:members).all.pluck(:id)).to match_array([record2.id, record3.id, record4.id]) + end + end + + private + + def create_user!(name) + email = "#{name}@example.com" + + table(:users).create!( + name: name, + email: email, + username: name, + projects_limit: 0 + ) + end + + def create_member(**extra_attributes) + defaults = { + access_level: 10, + source_id: 1, + source_type: "Project", + notification_level: 0, + type: 'ProjectMember' + } + + table(:members).create!(defaults.merge(extra_attributes)) + end +end diff --git a/spec/migrations/reschedule_issue_work_item_type_id_backfill_spec.rb b/spec/migrations/reschedule_issue_work_item_type_id_backfill_spec.rb new file mode 100644 index 00000000000..126d49790a5 --- /dev/null +++ b/spec/migrations/reschedule_issue_work_item_type_id_backfill_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RescheduleIssueWorkItemTypeIdBackfill, :migration do + let_it_be(:migration) { described_class::MIGRATION } + let_it_be(:interval) { 2.minutes } + let_it_be(:issue_type_enum) { { issue: 0, incident: 1, test_case: 2, requirement: 3, task: 4 } } + let_it_be(:base_work_item_type_ids) do + table(:work_item_types).where(namespace_id: nil).order(:base_type).each_with_object({}) do |type, hash| + hash[type.base_type] = type.id + end + end + + describe '#up' do + it 'correctly schedules background migrations' do + Sidekiq::Testing.fake! do + freeze_time do + migrate! + + scheduled_migrations = Gitlab::Database::BackgroundMigration::BatchedMigration.where( + job_class_name: migration + ) + work_item_types = table(:work_item_types).where(namespace_id: nil) + + expect(scheduled_migrations.count).to eq(work_item_types.count) + + [:issue, :incident, :test_case, :requirement, :task].each do |issue_type| + expect(migration).to have_scheduled_batched_migration( + table_name: :issues, + column_name: :id, + job_arguments: [issue_type_enum[issue_type], base_work_item_type_ids[issue_type_enum[issue_type]]], + interval: interval, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE, + batch_class_name: described_class::BATCH_CLASS_NAME + ) + end + end + end + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/reset_job_token_scope_enabled_again_spec.rb b/spec/migrations/reset_job_token_scope_enabled_again_spec.rb index da6817f6f21..8f9e12852e1 100644 --- a/spec/migrations/reset_job_token_scope_enabled_again_spec.rb +++ b/spec/migrations/reset_job_token_scope_enabled_again_spec.rb @@ -9,8 +9,8 @@ RSpec.describe ResetJobTokenScopeEnabledAgain do let(:projects) { table(:projects) } let(:namespaces) { table(:namespaces) } let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } - let(:project_1) { projects.create!(name: 'proj-1', path: 'gitlab-org', namespace_id: namespace.id)} - let(:project_2) { projects.create!(name: 'proj-2', path: 'gitlab-org', namespace_id: namespace.id)} + let(:project_1) { projects.create!(name: 'proj-1', path: 'gitlab-org', namespace_id: namespace.id) } + let(:project_2) { projects.create!(name: 'proj-2', path: 'gitlab-org', namespace_id: namespace.id) } before do settings.create!(id: 1, project_id: project_1.id, job_token_scope_enabled: true) diff --git a/spec/migrations/reset_job_token_scope_enabled_spec.rb b/spec/migrations/reset_job_token_scope_enabled_spec.rb index 40dfe4de34b..fb7bd78c11f 100644 --- a/spec/migrations/reset_job_token_scope_enabled_spec.rb +++ b/spec/migrations/reset_job_token_scope_enabled_spec.rb @@ -9,8 +9,8 @@ RSpec.describe ResetJobTokenScopeEnabled do let(:projects) { table(:projects) } let(:namespaces) { table(:namespaces) } let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } - let(:project_1) { projects.create!(name: 'proj-1', path: 'gitlab-org', namespace_id: namespace.id)} - let(:project_2) { projects.create!(name: 'proj-2', path: 'gitlab-org', namespace_id: namespace.id)} + let(:project_1) { projects.create!(name: 'proj-1', path: 'gitlab-org', namespace_id: namespace.id) } + let(:project_2) { projects.create!(name: 'proj-2', path: 'gitlab-org', namespace_id: namespace.id) } before do settings.create!(id: 1, project_id: project_1.id, job_token_scope_enabled: true) diff --git a/spec/migrations/reset_severity_levels_to_new_default_spec.rb b/spec/migrations/reset_severity_levels_to_new_default_spec.rb index 18dc001db16..c352f1f3cee 100644 --- a/spec/migrations/reset_severity_levels_to_new_default_spec.rb +++ b/spec/migrations/reset_severity_levels_to_new_default_spec.rb @@ -6,10 +6,10 @@ require_migration! RSpec.describe ResetSeverityLevelsToNewDefault do let(:approval_project_rules) { table(:approval_project_rules) } - let(:projects) { table(:projects)} - let(:namespaces) { table(:namespaces)} - let(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace')} - let(:project) { projects.create!(name: 'project', path: 'project', namespace_id: namespace.id)} + let(:projects) { table(:projects) } + let(:namespaces) { table(:namespaces) } + let(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') } + let(:project) { projects.create!(name: 'project', path: 'project', namespace_id: namespace.id) } let(:approval_project_rule) { approval_project_rules.create!(name: 'rule', project_id: project.id, severity_levels: severity_levels) } context 'without having all severity levels selected' do @@ -27,7 +27,7 @@ RSpec.describe ResetSeverityLevelsToNewDefault do it 'changes severity_levels to the default value' do expect(approval_project_rule.severity_levels).to eq(severity_levels) - expect { migrate! }.to change {approval_project_rule.reload.severity_levels}.from(severity_levels).to(default_levels) + expect { migrate! }.to change { approval_project_rule.reload.severity_levels }.from(severity_levels).to(default_levels) end end end diff --git a/spec/migrations/schedule_backfill_cluster_agents_has_vulnerabilities_spec.rb b/spec/migrations/schedule_backfill_cluster_agents_has_vulnerabilities_spec.rb new file mode 100644 index 00000000000..675cc332e69 --- /dev/null +++ b/spec/migrations/schedule_backfill_cluster_agents_has_vulnerabilities_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleBackfillClusterAgentsHasVulnerabilities do + let_it_be(:batched_migration) { described_class::MIGRATION } + + it 'schedules background jobs for each batch of cluster agents' 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: :cluster_agents, + column_name: :id, + interval: described_class::DELAY_INTERVAL + ) + } + end + end +end |