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