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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-17 19:05:49 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-17 19:05:49 +0300
commit43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch)
treedceebdc68925362117480a5d672bcff122fb625b /spec/migrations
parent20c84b99005abd1c82101dfeff264ac50d2df211 (diff)
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb69
-rw-r--r--spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb21
-rw-r--r--spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb21
-rw-r--r--spec/migrations/20210906130643_drop_temporary_columns_and_triggers_for_taggings_spec.rb23
-rw-r--r--spec/migrations/20210907013944_cleanup_bigint_conversion_for_ci_builds_metadata_spec.rb23
-rw-r--r--spec/migrations/20210907211557_finalize_ci_builds_bigint_conversion_spec.rb18
-rw-r--r--spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb48
-rw-r--r--spec/migrations/20210914095310_cleanup_orphan_project_access_tokens_spec.rb47
-rw-r--r--spec/migrations/20210915022415_cleanup_bigint_conversion_for_ci_builds_spec.rb23
-rw-r--r--spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb47
-rw-r--r--spec/migrations/20210922021816_drop_int4_columns_for_ci_job_artifacts_spec.rb23
-rw-r--r--spec/migrations/20210922025631_drop_int4_column_for_ci_sources_pipelines_spec.rb21
-rw-r--r--spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb21
-rw-r--r--spec/migrations/20210922091402_drop_int4_column_for_push_event_payloads_spec.rb21
-rw-r--r--spec/migrations/20211006060436_schedule_populate_topics_total_projects_count_cache_spec.rb29
-rw-r--r--spec/migrations/20211012134316_clean_up_migrate_merge_request_diff_commit_users_spec.rb48
-rw-r--r--spec/migrations/20211018152654_schedule_remove_duplicate_vulnerabilities_findings3_spec.rb166
-rw-r--r--spec/migrations/20211028155449_schedule_fix_merge_request_diff_commit_users_migration_spec.rb63
-rw-r--r--spec/migrations/20211101222614_consume_remaining_user_namespace_jobs_spec.rb21
-rw-r--r--spec/migrations/20211110143306_add_not_null_constraint_to_security_findings_uuid_spec.rb23
-rw-r--r--spec/migrations/20211110151350_schedule_drop_invalid_security_findings_spec.rb72
-rw-r--r--spec/migrations/20211116091751_change_namespace_type_default_to_user_spec.rb5
-rw-r--r--spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb190
-rw-r--r--spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb43
-rw-r--r--spec/migrations/20211126115449_encrypt_static_objects_external_storage_auth_token_spec.rb78
-rw-r--r--spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb54
-rw-r--r--spec/migrations/20211130165043_backfill_sequence_column_for_sprints_table_spec.rb42
-rw-r--r--spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb2
-rw-r--r--spec/migrations/20220124130028_dedup_runner_projects_spec.rb2
-rw-r--r--spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb2
-rw-r--r--spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb4
-rw-r--r--spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb2
-rw-r--r--spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb2
-rw-r--r--spec/migrations/20220324032250_migrate_shimo_confluence_service_category_spec.rb5
-rw-r--r--spec/migrations/20220329175119_remove_leftover_ci_job_artifact_deletions_spec.rb2
-rw-r--r--spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb12
-rw-r--r--spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb2
-rw-r--r--spec/migrations/20220601152916_add_user_id_and_ip_address_success_index_to_authentication_events_spec.rb2
-rw-r--r--spec/migrations/20220606082910_add_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb2
-rw-r--r--spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb2
-rw-r--r--spec/migrations/20220628012902_finalise_project_namespace_members_spec.rb8
-rw-r--r--spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb4
-rw-r--r--spec/migrations/20220802204737_remove_deactivated_user_highest_role_stats_spec.rb2
-rw-r--r--spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb30
-rw-r--r--spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb2
-rw-r--r--spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb2
-rw-r--r--spec/migrations/20220921144258_remove_orphan_group_token_users_spec.rb16
-rw-r--r--spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb4
-rw-r--r--spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb8
-rw-r--r--spec/migrations/20221018050323_add_objective_and_keyresult_to_work_item_types_spec.rb35
-rw-r--r--spec/migrations/20221018193635_ensure_task_note_renaming_background_migration_finished_spec.rb6
-rw-r--r--spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb4
-rw-r--r--spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb2
-rw-r--r--spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb4
-rw-r--r--spec/migrations/20221209235940_cleanup_o_auth_access_tokens_with_null_expires_in_spec.rb2
-rw-r--r--spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb30
-rw-r--r--spec/migrations/20221221110733_remove_temp_index_for_project_statistics_upload_size_migration_spec.rb2
-rw-r--r--spec/migrations/20230105172120_sync_new_amount_used_with_amount_used_on_ci_namespace_monthly_usages_table_spec.rb2
-rw-r--r--spec/migrations/20230118144623_schedule_migration_for_remediation_spec.rb25
-rw-r--r--spec/migrations/20230125195503_queue_backfill_compliance_violations_spec.rb32
-rw-r--r--spec/migrations/20230130182412_schedule_create_vulnerability_links_migration_spec.rb (renamed from spec/migrations/backfill_user_namespace_spec.rb)11
-rw-r--r--spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb6
-rw-r--r--spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb27
-rw-r--r--spec/migrations/20230202211434_migrate_redis_slot_keys_spec.rb54
-rw-r--r--spec/migrations/20230208125736_schedule_migration_for_links_spec.rb25
-rw-r--r--spec/migrations/20230209222452_schedule_remove_project_group_link_with_missing_groups_spec.rb32
-rw-r--r--spec/migrations/20230214181633_finalize_ci_build_needs_big_int_conversion_spec.rb43
-rw-r--r--spec/migrations/20230220102212_swap_columns_ci_build_needs_big_int_conversion_spec.rb60
-rw-r--r--spec/migrations/20230221093533_add_tmp_partial_index_on_vulnerability_report_types_spec.rb22
-rw-r--r--spec/migrations/20230221214519_remove_incorrectly_onboarded_namespaces_from_onboarding_progress_spec.rb59
-rw-r--r--spec/migrations/20230223065753_finalize_nullify_creator_id_of_orphaned_projects_spec.rb97
-rw-r--r--spec/migrations/20230224085743_update_issues_internal_id_scope_spec.rb28
-rw-r--r--spec/migrations/20230224144233_migrate_evidences_from_raw_metadata_spec.rb25
-rw-r--r--spec/migrations/20230228142350_add_notifications_work_item_widget_spec.rb8
-rw-r--r--spec/migrations/20230302185739_queue_fix_vulnerability_reads_has_issues_spec.rb27
-rw-r--r--spec/migrations/20230302811133_re_migrate_redis_slot_keys_spec.rb77
-rw-r--r--spec/migrations/20230303105806_queue_delete_orphaned_packages_dependencies_spec.rb26
-rw-r--r--spec/migrations/20230309071242_delete_security_policy_bot_users_spec.rb24
-rw-r--r--spec/migrations/20230313142631_backfill_ml_candidates_package_id_spec.rb61
-rw-r--r--spec/migrations/20230313150531_reschedule_migration_for_remediation_spec.rb31
-rw-r--r--spec/migrations/20230314144640_reschedule_migration_for_links_spec.rb25
-rw-r--r--spec/migrations/20230317004428_migrate_daily_redis_hll_events_to_weekly_aggregation_spec.rb124
-rw-r--r--spec/migrations/20230317162059_add_current_user_todos_work_item_widget_spec.rb8
-rw-r--r--spec/migrations/20230321153035_add_package_id_created_at_desc_index_to_package_files_spec.rb20
-rw-r--r--spec/migrations/20230321163947_backfill_ml_candidates_project_id_spec.rb50
-rw-r--r--spec/migrations/20230321170823_backfill_ml_candidates_internal_id_spec.rb64
-rw-r--r--spec/migrations/20230322085041_remove_user_namespace_records_from_vsa_aggregation_spec.rb41
-rw-r--r--spec/migrations/20230322145403_add_project_id_foreign_key_to_packages_npm_metadata_caches_spec.rb24
-rw-r--r--spec/migrations/20230323101138_add_award_emoji_work_item_widget_spec.rb8
-rw-r--r--spec/migrations/20230327103401_queue_migrate_human_user_type_spec.rb26
-rw-r--r--spec/migrations/20230327123333_backfill_product_analytics_data_collector_host_spec.rb47
-rw-r--r--spec/migrations/20230328030101_add_secureflag_training_provider_spec.rb25
-rw-r--r--spec/migrations/20230328100534_truncate_error_tracking_tables_spec.rb56
-rw-r--r--spec/migrations/20230329100222_drop_software_licenses_temp_index_spec.rb20
-rw-r--r--spec/migrations/20230330103104_reschedule_migrate_evidences_spec.rb25
-rw-r--r--spec/migrations/20230403085957_add_tmp_partial_index_on_vulnerability_report_types2_spec.rb49
-rw-r--r--spec/migrations/20230405200858_requeue_backfill_project_wiki_repositories_spec.rb26
-rw-r--r--spec/migrations/20230406121544_queue_backfill_design_management_repositories_spec.rb26
-rw-r--r--spec/migrations/20230411153310_cleanup_bigint_conversion_for_sent_notifications_spec.rb21
-rw-r--r--spec/migrations/20230412141541_reschedule_links_avoiding_duplication_spec.rb31
-rw-r--r--spec/migrations/20230412185837_queue_populate_vulnerability_dismissal_fields_spec.rb37
-rw-r--r--spec/migrations/20230412214119_finalize_encrypt_ci_trigger_token_spec.rb96
-rw-r--r--spec/migrations/20230418215853_add_assignee_widget_to_incidents_spec.rb47
-rw-r--r--spec/migrations/20230419105225_remove_phabricator_from_application_settings_spec.rb22
-rw-r--r--spec/migrations/20230426102200_fix_import_sources_on_application_settings_after_phabricator_removal_spec.rb34
-rw-r--r--spec/migrations/20230428085332_remove_shimo_zentao_integration_records_spec.rb46
-rw-r--r--spec/migrations/20230502102832_schedule_index_to_members_on_source_and_type_and_access_level_spec.rb22
-rw-r--r--spec/migrations/20230502120021_schedule_index_to_project_authorizations_on_project_user_access_level_spec.rb22
-rw-r--r--spec/migrations/20230504084524_remove_gitlab_import_source_spec.rb22
-rw-r--r--spec/migrations/20230508150219_reschedule_evidences_handling_unicode_spec.rb31
-rw-r--r--spec/migrations/20230508175057_backfill_corrected_secure_files_expirations_spec.rb24
-rw-r--r--spec/migrations/20230509131736_add_default_organization_spec.rb20
-rw-r--r--spec/migrations/20230510062502_queue_cleanup_personal_access_tokens_with_nil_expires_at_spec.rb26
-rw-r--r--spec/migrations/add_open_source_plan_spec.rb86
-rw-r--r--spec/migrations/backfill_current_value_with_progress_work_item_progresses_spec.rb48
-rw-r--r--spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb2
-rw-r--r--spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb2
-rw-r--r--spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb2
-rw-r--r--spec/migrations/cleanup_vulnerability_state_transitions_with_same_from_state_to_state_spec.rb2
-rw-r--r--spec/migrations/delete_migrate_shared_vulnerability_scanners_spec.rb58
-rw-r--r--spec/migrations/disable_job_token_scope_when_unused_spec.rb10
-rw-r--r--spec/migrations/drop_packages_events_table_spec.rb24
-rw-r--r--spec/migrations/ensure_award_emoji_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_commit_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_design_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_epic_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_issue_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb37
-rw-r--r--spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_self_hosts_spec.rb25
-rw-r--r--spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_note_diff_files_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_notes_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_snippet_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_suggestions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_system_note_metadata_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_timelogs_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_todos_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb35
-rw-r--r--spec/migrations/ensure_unique_debian_packages_spec.rb56
-rw-r--r--spec/migrations/ensure_vum_bigint_backfill_is_finished_for_gl_dot_com_spec.rb35
-rw-r--r--spec/migrations/finalize_invalid_member_cleanup_spec.rb4
-rw-r--r--spec/migrations/finalize_issues_iid_scoping_to_namespace_spec.rb72
-rw-r--r--spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb8
-rw-r--r--spec/migrations/finalize_orphaned_routes_cleanup_spec.rb8
-rw-r--r--spec/migrations/finalize_project_namespaces_backfill_spec.rb8
-rw-r--r--spec/migrations/finalize_routes_backfilling_for_projects_spec.rb8
-rw-r--r--spec/migrations/finalize_traversal_ids_background_migrations_spec.rb60
-rw-r--r--spec/migrations/insert_daily_invites_trial_plan_limits_spec.rb51
-rw-r--r--spec/migrations/queue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb18
-rw-r--r--spec/migrations/queue_backfill_prepared_at_data_spec.rb24
-rw-r--r--spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_features_spec.rb28
-rw-r--r--spec/migrations/remove_invalid_deploy_access_level_spec.rb48
-rw-r--r--spec/migrations/remove_packages_events_package_id_fk_spec.rb23
-rw-r--r--spec/migrations/remove_saml_provider_and_identities_non_root_group_spec.rb53
-rw-r--r--spec/migrations/remove_schedule_and_status_from_pending_alert_escalations_spec.rb37
-rw-r--r--spec/migrations/remove_scim_token_and_scim_identity_non_root_group_spec.rb58
-rw-r--r--spec/migrations/requeue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb19
-rw-r--r--spec/migrations/rerun_remove_invalid_deploy_access_level_spec.rb86
-rw-r--r--spec/migrations/reschedule_incident_work_item_type_id_backfill_spec.rb70
-rw-r--r--spec/migrations/schedule_backfill_draft_status_on_merge_requests_corrected_regex_spec.rb2
-rw-r--r--spec/migrations/schedule_fixing_security_scan_statuses_spec.rb4
-rw-r--r--spec/migrations/schedule_migrate_shared_vulnerability_identifiers_spec.rb32
-rw-r--r--spec/migrations/schedule_purging_stale_security_scans_spec.rb2
-rw-r--r--spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb90
-rw-r--r--spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb2
-rw-r--r--spec/migrations/set_email_confirmation_setting_from_soft_email_confirmation_ff_spec.rb62
-rw-r--r--spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb70
-rw-r--r--spec/migrations/start_backfill_ci_queuing_tables_spec.rb2
-rw-r--r--spec/migrations/swap_award_emoji_note_id_to_bigint_for_gitlab_dot_com_spec.rb67
-rw-r--r--spec/migrations/swap_commit_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_design_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_epic_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_2_spec.rb84
-rw-r--r--spec/migrations/swap_merge_request_metrics_id_to_bigint_for_gitlab_dot_com_spec.rb76
-rw-r--r--spec/migrations/swap_merge_request_metrics_id_to_bigint_for_self_hosts_spec.rb155
-rw-r--r--spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_spec.rb66
-rw-r--r--spec/migrations/swap_note_diff_files_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_sent_notifications_id_columns_spec.rb71
-rw-r--r--spec/migrations/swap_snippet_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_suggestions_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_system_note_metadata_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_timelogs_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_todos_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/swap_vulnerability_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/migrations/sync_new_amount_used_for_ci_namespace_monthly_usages_spec.rb2
-rw-r--r--spec/migrations/sync_new_amount_used_for_ci_project_monthly_usages_spec.rb2
-rw-r--r--spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb2
-rw-r--r--spec/migrations/update_application_settings_protected_paths_spec.rb2
-rw-r--r--spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb22
188 files changed, 4549 insertions, 1880 deletions
diff --git a/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb b/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb
deleted file mode 100644
index 4c7ef9ac1e8..00000000000
--- a/spec/migrations/20210831203408_upsert_base_work_item_types_spec.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe UpsertBaseWorkItemTypes, :migration, feature_category: :team_planning do
- include MigrationHelpers::WorkItemTypesHelper
-
- let!(:work_item_types) { table(:work_item_types) }
-
- let(:base_types) do
- {
- issue: 0,
- incident: 1,
- test_case: 2,
- requirement: 3
- }
- end
-
- 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
- end
-
- context 'when no default types exist' do
- it 'creates default data' do
- # Need to delete all as base types are seeded before entire test suite
- work_item_types.delete_all
-
- expect(work_item_types.count).to eq(0)
-
- reversible_migration do |migration|
- migration.before -> {
- # Depending on whether the migration has been run before,
- # the size could be 4, or 0, so we don't set any expectations
- # as we don't delete base types on migration reverse
- }
-
- migration.after -> {
- expect(work_item_types.count).to eq(4)
- expect(work_item_types.all.pluck(:base_type)).to match_array(base_types.values)
- }
- end
- end
- end
-
- context 'when default types already exist' do
- it 'does not create default types again' do
- # Database needs to be in a similar state as when this migration was created
- work_item_types.delete_all
- work_item_types.find_or_create_by!(name: 'Issue', namespace_id: nil, base_type: base_types[:issue], icon_name: 'issue-type-issue')
- work_item_types.find_or_create_by!(name: 'Incident', namespace_id: nil, base_type: base_types[:incident], icon_name: 'issue-type-incident')
- work_item_types.find_or_create_by!(name: 'Test Case', namespace_id: nil, base_type: base_types[:test_case], icon_name: 'issue-type-test-case')
- work_item_types.find_or_create_by!(name: 'Requirement', namespace_id: nil, base_type: base_types[:requirement], icon_name: 'issue-type-requirements')
-
- reversible_migration do |migration|
- migration.before -> {
- expect(work_item_types.all.pluck(:base_type)).to match_array(base_types.values)
- }
-
- migration.after -> {
- expect(work_item_types.count).to eq(4)
- expect(work_item_types.all.pluck(:base_type)).to match_array(base_types.values)
- }
- end
- end
- end
-end
diff --git a/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb b/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb
deleted file mode 100644
index 0d89851cac1..00000000000
--- a/spec/migrations/20210902144144_drop_temporary_columns_and_triggers_for_ci_build_needs_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildNeeds, feature_category: :pipeline_authoring do
- let(:ci_build_needs_table) { table(:ci_build_needs) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(ci_build_needs_table.column_names).to include('build_id_convert_to_bigint')
- }
-
- migration.after -> {
- ci_build_needs_table.reset_column_information
- expect(ci_build_needs_table.column_names).not_to include('build_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb b/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb
deleted file mode 100644
index eef4c7bc9fd..00000000000
--- a/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildTraceChunks, feature_category: :continuous_integration do
- let(:ci_build_trace_chunks_table) { table(:ci_build_trace_chunks) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(ci_build_trace_chunks_table.column_names).to include('build_id_convert_to_bigint')
- }
-
- migration.after -> {
- ci_build_trace_chunks_table.reset_column_information
- expect(ci_build_trace_chunks_table.column_names).not_to include('build_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210906130643_drop_temporary_columns_and_triggers_for_taggings_spec.rb b/spec/migrations/20210906130643_drop_temporary_columns_and_triggers_for_taggings_spec.rb
deleted file mode 100644
index 208cbac2ae9..00000000000
--- a/spec/migrations/20210906130643_drop_temporary_columns_and_triggers_for_taggings_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropTemporaryColumnsAndTriggersForTaggings, feature_category: :continuous_integration do
- let(:taggings_table) { table(:taggings) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(taggings_table.column_names).to include('id_convert_to_bigint')
- expect(taggings_table.column_names).to include('taggable_id_convert_to_bigint')
- }
-
- migration.after -> {
- taggings_table.reset_column_information
- expect(taggings_table.column_names).not_to include('id_convert_to_bigint')
- expect(taggings_table.column_names).not_to include('taggable_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210907013944_cleanup_bigint_conversion_for_ci_builds_metadata_spec.rb b/spec/migrations/20210907013944_cleanup_bigint_conversion_for_ci_builds_metadata_spec.rb
deleted file mode 100644
index 63664803fba..00000000000
--- a/spec/migrations/20210907013944_cleanup_bigint_conversion_for_ci_builds_metadata_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe CleanupBigintConversionForCiBuildsMetadata, feature_category: :continuous_integration do
- let(:ci_builds_metadata) { table(:ci_builds_metadata) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(ci_builds_metadata.column_names).to include('id_convert_to_bigint')
- expect(ci_builds_metadata.column_names).to include('build_id_convert_to_bigint')
- }
-
- migration.after -> {
- ci_builds_metadata.reset_column_information
- expect(ci_builds_metadata.column_names).not_to include('id_convert_to_bigint')
- expect(ci_builds_metadata.column_names).not_to include('build_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210907211557_finalize_ci_builds_bigint_conversion_spec.rb b/spec/migrations/20210907211557_finalize_ci_builds_bigint_conversion_spec.rb
deleted file mode 100644
index 663b90f3fa7..00000000000
--- a/spec/migrations/20210907211557_finalize_ci_builds_bigint_conversion_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe FinalizeCiBuildsBigintConversion, :migration, schema: 20210907182359, feature_category: :continuous_integration do
- context 'with an unexpected FK fk_3f0c88d7dc' do
- it 'removes the FK and migrates successfully' do
- # Add the unexpected FK
- subject.add_foreign_key(:ci_sources_pipelines, :ci_builds, column: :source_job_id, name: 'fk_3f0c88d7dc')
-
- expect { migrate! }.to change { subject.foreign_key_exists?(:ci_sources_pipelines, :ci_builds, column: :source_job_id, name: 'fk_3f0c88d7dc') }.from(true).to(false)
-
- # Additional check: The actually expected FK should still exist
- expect(subject.foreign_key_exists?(:ci_sources_pipelines, :ci_builds, column: :source_job_id, name: 'fk_be5624bf37')).to be_truthy
- end
- end
-end
diff --git a/spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb b/spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb
deleted file mode 100644
index e9d34fad76d..00000000000
--- a/spec/migrations/20210910194952_update_report_type_for_existing_approval_project_rules_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe UpdateReportTypeForExistingApprovalProjectRules, :migration, feature_category: :source_code_management do
- using RSpec::Parameterized::TableSyntax
-
- let(:group) { table(:namespaces).create!(name: 'user', path: 'user') }
- let(:project) { table(:projects).create!(namespace_id: group.id) }
- let(:approval_project_rule) { table(:approval_project_rules).create!(name: rule_name, rule_type: rule_type, project_id: project.id) }
- let(:rule_type) { 2 }
- let(:rule_name) { 'Vulnerability-Check' }
-
- context 'with rule_type set to :report_approver' do
- where(:rule_name, :report_type) do
- [
- ['Vulnerability-Check', 1],
- ['License-Check', 2],
- ['Coverage-Check', 3]
- ]
- end
-
- with_them do
- context "with names associated with report type" do
- it 'updates report_type' do
- expect { migrate! }.to change { approval_project_rule.reload.report_type }.from(nil).to(report_type)
- end
- end
- end
- end
-
- context 'with rule_type set to another value (e.g., :regular)' do
- let(:rule_type) { 0 }
-
- it 'does not update report_type' do
- expect { migrate! }.not_to change { approval_project_rule.reload.report_type }
- end
- end
-
- context 'with the rule name set to another value (e.g., Test Rule)' do
- let(:rule_name) { 'Test Rule' }
-
- it 'does not update report_type' do
- expect { migrate! }.not_to change { approval_project_rule.reload.report_type }
- end
- end
-end
diff --git a/spec/migrations/20210914095310_cleanup_orphan_project_access_tokens_spec.rb b/spec/migrations/20210914095310_cleanup_orphan_project_access_tokens_spec.rb
deleted file mode 100644
index a198ae9e473..00000000000
--- a/spec/migrations/20210914095310_cleanup_orphan_project_access_tokens_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe CleanupOrphanProjectAccessTokens, :migration, feature_category: :user_profile do
- def create_user(**extra_options)
- defaults = { state: 'active', projects_limit: 0, email: "#{extra_options[:username]}@example.com" }
-
- table(:users).create!(defaults.merge(extra_options))
- end
-
- def create_membership(**extra_options)
- defaults = { access_level: 30, notification_level: 0, source_id: 1, source_type: 'Project' }
-
- table(:members).create!(defaults.merge(extra_options))
- end
-
- let!(:regular_user) { create_user(username: 'regular') }
- let!(:orphan_bot) { create_user(username: 'orphaned_bot', user_type: 6) }
- let!(:used_bot) do
- create_user(username: 'used_bot', user_type: 6).tap do |bot|
- create_membership(user_id: bot.id)
- end
- end
-
- it 'marks all bots without memberships as deactivated' do
- expect do
- migrate!
- regular_user.reload
- orphan_bot.reload
- used_bot.reload
- end.to change {
- [regular_user.state, orphan_bot.state, used_bot.state]
- }.from(%w[active active active]).to(%w[active deactivated active])
- end
-
- it 'schedules for deletion all bots without memberships' do
- job_class = 'DeleteUserWorker'.safe_constantize
-
- if job_class
- expect(job_class).to receive(:bulk_perform_async).with([[orphan_bot.id, orphan_bot.id, skip_authorization: true]])
-
- migrate!
- end
- end
-end
diff --git a/spec/migrations/20210915022415_cleanup_bigint_conversion_for_ci_builds_spec.rb b/spec/migrations/20210915022415_cleanup_bigint_conversion_for_ci_builds_spec.rb
deleted file mode 100644
index 808c5371018..00000000000
--- a/spec/migrations/20210915022415_cleanup_bigint_conversion_for_ci_builds_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe CleanupBigintConversionForCiBuilds, feature_category: :continuous_integration do
- let(:ci_builds) { table(:ci_builds) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(ci_builds.column_names).to include('id_convert_to_bigint')
- expect(ci_builds.column_names).to include('stage_id_convert_to_bigint')
- }
-
- migration.after -> {
- ci_builds.reset_column_information
- expect(ci_builds.column_names).not_to include('id_convert_to_bigint')
- expect(ci_builds.column_names).not_to include('stage_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
deleted file mode 100644
index b3d1b41c330..00000000000
--- a/spec/migrations/20210918201050_remove_old_pending_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-def create_background_migration_jobs(ids, status, created_at)
- proper_status = case status
- when :pending
- Gitlab::Database::BackgroundMigrationJob.statuses['pending']
- when :succeeded
- Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
- else
- raise ArgumentError
- end
-
- background_migration_jobs.create!(
- class_name: 'RecalculateVulnerabilitiesOccurrencesUuid',
- arguments: Array(ids),
- status: proper_status,
- created_at: created_at
- )
-end
-
-RSpec.describe RemoveOldPendingJobsForRecalculateVulnerabilitiesOccurrencesUuid, :migration,
-feature_category: :vulnerability_management do
- let!(:background_migration_jobs) { table(:background_migration_jobs) }
- let!(:before_target_date) { -Float::INFINITY..(DateTime.new(2021, 8, 17, 23, 59, 59)) }
- let!(:after_target_date) { (DateTime.new(2021, 8, 18, 0, 0, 0))..Float::INFINITY }
-
- context 'when old RecalculateVulnerabilitiesOccurrencesUuid jobs are pending' do
- before do
- create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 5, 5, 0, 2))
- create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 5, 5, 0, 4))
-
- create_background_migration_jobs([1, 2, 3], :succeeded, DateTime.new(2021, 8, 18, 0, 0))
- create_background_migration_jobs([4, 5, 6], :pending, DateTime.new(2021, 8, 18, 0, 2))
- create_background_migration_jobs([7, 8, 9], :pending, DateTime.new(2021, 8, 18, 0, 4))
- end
-
- it 'removes old, pending jobs' do
- migrate!
-
- expect(background_migration_jobs.where(created_at: before_target_date).count).to eq(1)
- expect(background_migration_jobs.where(created_at: after_target_date).count).to eq(3)
- end
- end
-end
diff --git a/spec/migrations/20210922021816_drop_int4_columns_for_ci_job_artifacts_spec.rb b/spec/migrations/20210922021816_drop_int4_columns_for_ci_job_artifacts_spec.rb
deleted file mode 100644
index c463f69c80c..00000000000
--- a/spec/migrations/20210922021816_drop_int4_columns_for_ci_job_artifacts_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropInt4ColumnsForCiJobArtifacts, feature_category: :build_artifacts do
- let(:ci_job_artifacts) { table(:ci_job_artifacts) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(ci_job_artifacts.column_names).to include('id_convert_to_bigint')
- expect(ci_job_artifacts.column_names).to include('job_id_convert_to_bigint')
- }
-
- migration.after -> {
- ci_job_artifacts.reset_column_information
- expect(ci_job_artifacts.column_names).not_to include('id_convert_to_bigint')
- expect(ci_job_artifacts.column_names).not_to include('job_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210922025631_drop_int4_column_for_ci_sources_pipelines_spec.rb b/spec/migrations/20210922025631_drop_int4_column_for_ci_sources_pipelines_spec.rb
deleted file mode 100644
index 6b0c3a6db9a..00000000000
--- a/spec/migrations/20210922025631_drop_int4_column_for_ci_sources_pipelines_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropInt4ColumnForCiSourcesPipelines, feature_category: :pipeline_authoring do
- let(:ci_sources_pipelines) { table(:ci_sources_pipelines) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(ci_sources_pipelines.column_names).to include('source_job_id_convert_to_bigint')
- }
-
- migration.after -> {
- ci_sources_pipelines.reset_column_information
- expect(ci_sources_pipelines.column_names).not_to include('source_job_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb b/spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb
deleted file mode 100644
index 49cf1a01f2a..00000000000
--- a/spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropInt4ColumnForEvents, feature_category: :user_profile do
- let(:events) { table(:events) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(events.column_names).to include('id_convert_to_bigint')
- }
-
- migration.after -> {
- events.reset_column_information
- expect(events.column_names).not_to include('id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20210922091402_drop_int4_column_for_push_event_payloads_spec.rb b/spec/migrations/20210922091402_drop_int4_column_for_push_event_payloads_spec.rb
deleted file mode 100644
index 3e241438339..00000000000
--- a/spec/migrations/20210922091402_drop_int4_column_for_push_event_payloads_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DropInt4ColumnForPushEventPayloads, feature_category: :user_profile do
- let(:push_event_payloads) { table(:push_event_payloads) }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(push_event_payloads.column_names).to include('event_id_convert_to_bigint')
- }
-
- migration.after -> {
- push_event_payloads.reset_column_information
- expect(push_event_payloads.column_names).not_to include('event_id_convert_to_bigint')
- }
- end
- end
-end
diff --git a/spec/migrations/20211006060436_schedule_populate_topics_total_projects_count_cache_spec.rb b/spec/migrations/20211006060436_schedule_populate_topics_total_projects_count_cache_spec.rb
deleted file mode 100644
index 2f3903a20a9..00000000000
--- a/spec/migrations/20211006060436_schedule_populate_topics_total_projects_count_cache_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe SchedulePopulateTopicsTotalProjectsCountCache, feature_category: :projects do
- let(:topics) { table(:topics) }
- let!(:topic_1) { topics.create!(name: 'Topic1') }
- let!(:topic_2) { topics.create!(name: 'Topic2') }
- let!(:topic_3) { topics.create!(name: 'Topic3') }
-
- describe '#up' do
- before do
- stub_const("#{described_class}::BATCH_SIZE", 2)
- end
-
- it 'schedules BackfillProjectsWithCoverage background jobs', :aggregate_failures do
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, topic_1.id, topic_2.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, topic_3.id, topic_3.id)
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
- end
- end
- end
- end
-end
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
deleted file mode 100644
index a61e450d9ab..00000000000
--- a/spec/migrations/20211012134316_clean_up_migrate_merge_request_diff_commit_users_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration! 'clean_up_migrate_merge_request_diff_commit_users'
-
-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
- Gitlab::Database::BackgroundMigrationJob.create!(
- class_name: 'MigrateMergeRequestDiffCommitUsers',
- status: :pending,
- arguments: [10, 20]
- )
-
- spy = Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers
- migration = described_class.new
-
- allow(Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers)
- .to receive(:new)
- .and_return(spy)
-
- expect(migration).to receive(:say)
- expect(spy).to receive(:perform).with(10, 20)
-
- migration.up
- end
- end
-
- context 'when all jobs are completed' do
- it 'does nothing' do
- Gitlab::Database::BackgroundMigrationJob.create!(
- class_name: 'MigrateMergeRequestDiffCommitUsers',
- status: :succeeded,
- arguments: [10, 20]
- )
-
- migration = described_class.new
-
- expect(migration).not_to receive(:say)
- expect(Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers)
- .not_to receive(:new)
-
- migration.up
- end
- end
- end
-end
diff --git a/spec/migrations/20211018152654_schedule_remove_duplicate_vulnerabilities_findings3_spec.rb b/spec/migrations/20211018152654_schedule_remove_duplicate_vulnerabilities_findings3_spec.rb
deleted file mode 100644
index 3e8176a36a1..00000000000
--- a/spec/migrations/20211018152654_schedule_remove_duplicate_vulnerabilities_findings3_spec.rb
+++ /dev/null
@@ -1,166 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-require_migration!('schedule_remove_duplicate_vulnerabilities_findings3')
-
-RSpec.describe ScheduleRemoveDuplicateVulnerabilitiesFindings3, :migration, feature_category: :vulnerability_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: 14219619, namespace_id: namespace.id) }
- let(:scanners) { table(:vulnerability_scanners) }
- let!(:scanner1) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
- let!(:scanner2) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
- let!(:scanner3) { scanners.create!(project_id: project.id, external_id: 'test 3', name: 'test scanner 3') }
- let!(:unrelated_scanner) { scanners.create!(project_id: project.id, external_id: 'unreleated_scanner', name: 'unrelated scanner') }
- let(:vulnerabilities) { table(:vulnerabilities) }
- let(:vulnerability_findings) { table(:vulnerability_occurrences) }
- let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
- let(:vulnerability_identifier) do
- vulnerability_identifiers.create!(
- id: 1244459,
- project_id: project.id,
- external_type: 'vulnerability-identifier',
- external_id: 'vulnerability-identifier',
- fingerprint: '0a203e8cd5260a1948edbedc76c7cb91ad6a2e45',
- name: 'vulnerability identifier')
- end
-
- let!(:vulnerability_for_first_duplicate) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:first_finding_duplicate) do
- create_finding!(
- id: 5606961,
- uuid: "bd95c085-71aa-51d7-9bb6-08ae669c262e",
- vulnerability_id: vulnerability_for_first_duplicate.id,
- report_type: 0,
- location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: scanner1.id,
- project_id: project.id
- )
- end
-
- let!(:vulnerability_for_second_duplicate) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:second_finding_duplicate) do
- create_finding!(
- id: 8765432,
- uuid: "5b714f58-1176-5b26-8fd5-e11dfcb031b5",
- vulnerability_id: vulnerability_for_second_duplicate.id,
- report_type: 0,
- location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: scanner2.id,
- project_id: project.id
- )
- end
-
- let!(:vulnerability_for_third_duplicate) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:third_finding_duplicate) do
- create_finding!(
- id: 8832995,
- uuid: "cfe435fa-b25b-5199-a56d-7b007cc9e2d4",
- vulnerability_id: vulnerability_for_third_duplicate.id,
- report_type: 0,
- location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: scanner3.id,
- project_id: project.id
- )
- end
-
- let!(:unrelated_finding) do
- create_finding!(
- id: 9999999,
- vulnerability_id: nil,
- report_type: 1,
- location_fingerprint: 'random_location_fingerprint',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: unrelated_scanner.id,
- project_id: project.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 migration' do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(4)
- expect(described_class::MIGRATION).to be_scheduled_migration(first_finding_duplicate.id, first_finding_duplicate.id)
- expect(described_class::MIGRATION).to be_scheduled_migration(second_finding_duplicate.id, second_finding_duplicate.id)
- expect(described_class::MIGRATION).to be_scheduled_migration(third_finding_duplicate.id, third_finding_duplicate.id)
- expect(described_class::MIGRATION).to be_scheduled_migration(unrelated_finding.id, unrelated_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:, id: nil,
- name: "test", severity: 7, confidence: 7, report_type: 0,
- project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
- metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
- vulnerability_findings.create!({
- id: id,
- 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: vulnerability_identifier.id,
- location_fingerprint: location_fingerprint,
- metadata_version: metadata_version,
- raw_metadata: raw_metadata,
- uuid: uuid
- }.compact)
- end
- # rubocop:enable Metrics/ParameterLists
-
- def create_user!(name: "Example User", email: "user@example.com", user_type: nil, created_at: Time.zone.now, confirmed_at: Time.zone.now)
- users.create!(
- name: name,
- email: email,
- username: name,
- projects_limit: 0,
- user_type: user_type,
- confirmed_at: confirmed_at
- )
- end
-end
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
deleted file mode 100644
index 968d9cf176c..00000000000
--- a/spec/migrations/20211028155449_schedule_fix_merge_request_diff_commit_users_migration_spec.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration! 'schedule_fix_merge_request_diff_commit_users_migration'
-
-RSpec.describe ScheduleFixMergeRequestDiffCommitUsersMigration, :migration, feature_category: :code_review_workflow do
- let(:migration) { described_class.new }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
-
- describe '#up' do
- it 'does nothing when there are no projects to correct' do
- migration.up
-
- expect(Gitlab::Database::BackgroundMigrationJob.count).to be_zero
- end
-
- it 'schedules imported projects created after July' do
- project = projects.create!(
- namespace_id: namespace.id,
- import_type: 'gitlab_project',
- created_at: '2021-08-01'
- )
-
- expect(migration)
- .to receive(:migrate_in)
- .with(2.minutes, 'FixMergeRequestDiffCommitUsers', [project.id])
-
- migration.up
-
- expect(Gitlab::Database::BackgroundMigrationJob.count).to eq(1)
-
- job = Gitlab::Database::BackgroundMigrationJob.first
-
- expect(job.class_name).to eq('FixMergeRequestDiffCommitUsers')
- expect(job.arguments).to eq([project.id])
- end
-
- it 'ignores projects imported before July' do
- projects.create!(
- namespace_id: namespace.id,
- import_type: 'gitlab_project',
- created_at: '2020-08-01'
- )
-
- migration.up
-
- expect(Gitlab::Database::BackgroundMigrationJob.count).to be_zero
- end
-
- it 'ignores projects that are not imported' do
- projects.create!(
- namespace_id: namespace.id,
- created_at: '2021-08-01'
- )
-
- migration.up
-
- expect(Gitlab::Database::BackgroundMigrationJob.count).to be_zero
- end
- end
-end
diff --git a/spec/migrations/20211101222614_consume_remaining_user_namespace_jobs_spec.rb b/spec/migrations/20211101222614_consume_remaining_user_namespace_jobs_spec.rb
deleted file mode 100644
index 1688ebf7cb1..00000000000
--- a/spec/migrations/20211101222614_consume_remaining_user_namespace_jobs_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ConsumeRemainingUserNamespaceJobs, feature_category: :subgroups do
- let(:namespaces) { table(:namespaces) }
- let!(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org', type: nil) }
-
- context 'when Namespaces with nil `type` still exist' do
- it 'steals sidekiq jobs from BackfillUserNamespace background migration' do
- expect(Gitlab::BackgroundMigration).to receive(:steal).with('BackfillUserNamespace')
-
- migrate!
- end
-
- it 'migrates namespaces without type' do
- expect { migrate! }.to change { namespaces.where(type: 'User').count }.from(0).to(1)
- end
- end
-end
diff --git a/spec/migrations/20211110143306_add_not_null_constraint_to_security_findings_uuid_spec.rb b/spec/migrations/20211110143306_add_not_null_constraint_to_security_findings_uuid_spec.rb
deleted file mode 100644
index 3b69169b2d6..00000000000
--- a/spec/migrations/20211110143306_add_not_null_constraint_to_security_findings_uuid_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-require_migration!
-
-RSpec.describe AddNotNullConstraintToSecurityFindingsUuid, feature_category: :vulnerability_management do
- let!(:security_findings) { table(:security_findings) }
- let!(:migration) { described_class.new }
-
- before do
- allow(migration).to receive(:transaction_open?).and_return(false)
- allow(migration).to receive(:with_lock_retries).and_yield
- end
-
- it 'adds a check constraint' do
- constraint = security_findings.connection.check_constraints(:security_findings).find { |constraint| constraint.expression == "uuid IS NOT NULL" }
- expect(constraint).to be_nil
-
- migration.up
-
- constraint = security_findings.connection.check_constraints(:security_findings).find { |constraint| constraint.expression == "uuid IS NOT NULL" }
- expect(constraint).to be_a(ActiveRecord::ConnectionAdapters::CheckConstraintDefinition)
- end
-end
diff --git a/spec/migrations/20211110151350_schedule_drop_invalid_security_findings_spec.rb b/spec/migrations/20211110151350_schedule_drop_invalid_security_findings_spec.rb
deleted file mode 100644
index d05828112e6..00000000000
--- a/spec/migrations/20211110151350_schedule_drop_invalid_security_findings_spec.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleDropInvalidSecurityFindings, :migration, :suppress_gitlab_schemas_validate_connection, schema: 20211108211434,
- feature_category: :vulnerability_management do
- let!(:background_migration_jobs) { table(:background_migration_jobs) }
-
- let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user', type: Namespaces::UserNamespace.sti_name) }
- let!(:project) { table(:projects).create!(namespace_id: namespace.id) }
-
- let!(:pipelines) { table(:ci_pipelines) }
- let!(:pipeline) { pipelines.create!(project_id: project.id) }
-
- let!(:ci_builds) { table(:ci_builds) }
- let!(:ci_build) { ci_builds.create! }
-
- let!(:security_scans) { table(:security_scans) }
- let!(:security_scan) do
- security_scans.create!(
- scan_type: 1,
- status: 1,
- build_id: ci_build.id,
- project_id: project.id,
- pipeline_id: pipeline.id
- )
- end
-
- let!(:vulnerability_scanners) { table(:vulnerability_scanners) }
- let!(:vulnerability_scanner) { vulnerability_scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
-
- let!(:security_findings) { table(:security_findings) }
- let!(:security_finding_without_uuid) do
- security_findings.create!(
- severity: 1,
- confidence: 1,
- scan_id: security_scan.id,
- scanner_id: vulnerability_scanner.id,
- uuid: nil
- )
- end
-
- let!(:security_finding_with_uuid) do
- security_findings.create!(
- severity: 1,
- confidence: 1,
- scan_id: security_scan.id,
- scanner_id: vulnerability_scanner.id,
- uuid: 'bd95c085-71aa-51d7-9bb6-08ae669c262e'
- )
- end
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
- stub_const("#{described_class}::SUB_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(1)
- expect(background_migration_jobs.first.arguments).to match_array([security_finding_without_uuid.id, security_finding_without_uuid.id, described_class::SUB_BATCH_SIZE])
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(1)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, security_finding_without_uuid.id, security_finding_without_uuid.id, described_class::SUB_BATCH_SIZE)
- end
-end
diff --git a/spec/migrations/20211116091751_change_namespace_type_default_to_user_spec.rb b/spec/migrations/20211116091751_change_namespace_type_default_to_user_spec.rb
deleted file mode 100644
index deba6f9b87c..00000000000
--- a/spec/migrations/20211116091751_change_namespace_type_default_to_user_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-# With https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73495, we no longer allow
-# a Namespace type to be nil. There is nothing left to test for this migration,
-# but we'll keep this file here as a tombstone.
diff --git a/spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb b/spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb
deleted file mode 100644
index 18513656029..00000000000
--- a/spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb
+++ /dev/null
@@ -1,190 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe ScheduleRemoveOccurrencePipelinesAndDuplicateVulnerabilitiesFindings,
- :suppress_gitlab_schemas_validate_connection, :migration, feature_category: :vulnerability_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: 14219619, namespace_id: namespace.id) }
- let!(:pipelines) { table(:ci_pipelines) }
- let!(:scanners) { table(:vulnerability_scanners) }
- let!(:scanner1) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
- let!(:scanner2) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
- let!(:scanner3) { scanners.create!(project_id: project.id, external_id: 'test 3', name: 'test scanner 3') }
- let!(:unrelated_scanner) { scanners.create!(project_id: project.id, external_id: 'unreleated_scanner', name: 'unrelated scanner') }
- let!(:vulnerabilities) { table(:vulnerabilities) }
- let!(:vulnerability_findings) { table(:vulnerability_occurrences) }
- let!(:vulnerability_finding_pipelines) { table(:vulnerability_occurrence_pipelines) }
- let!(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
- let!(:vulnerability_identifier) do
- vulnerability_identifiers.create!(
- id: 1244459,
- project_id: project.id,
- external_type: 'vulnerability-identifier',
- external_id: 'vulnerability-identifier',
- fingerprint: '0a203e8cd5260a1948edbedc76c7cb91ad6a2e45',
- name: 'vulnerability identifier')
- end
-
- let!(:vulnerability_for_first_duplicate) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:first_finding_duplicate) do
- create_finding!(
- id: 5606961,
- uuid: "bd95c085-71aa-51d7-9bb6-08ae669c262e",
- vulnerability_id: vulnerability_for_first_duplicate.id,
- report_type: 0,
- location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: scanner1.id,
- project_id: project.id
- )
- end
-
- let!(:vulnerability_for_second_duplicate) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:second_finding_duplicate) do
- create_finding!(
- id: 8765432,
- uuid: "5b714f58-1176-5b26-8fd5-e11dfcb031b5",
- vulnerability_id: vulnerability_for_second_duplicate.id,
- report_type: 0,
- location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: scanner2.id,
- project_id: project.id
- )
- end
-
- let!(:vulnerability_for_third_duplicate) do
- create_vulnerability!(
- project_id: project.id,
- author_id: user.id
- )
- end
-
- let!(:third_finding_duplicate) do
- create_finding!(
- id: 8832995,
- uuid: "cfe435fa-b25b-5199-a56d-7b007cc9e2d4",
- vulnerability_id: vulnerability_for_third_duplicate.id,
- report_type: 0,
- location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: scanner3.id,
- project_id: project.id
- )
- end
-
- let!(:unrelated_finding) do
- create_finding!(
- id: 9999999,
- vulnerability_id: nil,
- report_type: 1,
- location_fingerprint: 'random_location_fingerprint',
- primary_identifier_id: vulnerability_identifier.id,
- scanner_id: unrelated_scanner.id,
- project_id: project.id
- )
- end
-
- before do
- stub_const("#{described_class}::BATCH_SIZE", 1)
-
- 4.times do
- create_finding_pipeline!(project_id: project.id, finding_id: first_finding_duplicate.id)
- create_finding_pipeline!(project_id: project.id, finding_id: second_finding_duplicate.id)
- create_finding_pipeline!(project_id: project.id, finding_id: third_finding_duplicate.id)
- create_finding_pipeline!(project_id: project.id, finding_id: unrelated_finding.id)
- end
- 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(4)
- expect(background_migration_jobs.first.arguments).to match_array([first_finding_duplicate.id, first_finding_duplicate.id])
- expect(background_migration_jobs.second.arguments).to match_array([second_finding_duplicate.id, second_finding_duplicate.id])
- expect(background_migration_jobs.third.arguments).to match_array([third_finding_duplicate.id, third_finding_duplicate.id])
- expect(background_migration_jobs.fourth.arguments).to match_array([unrelated_finding.id, unrelated_finding.id])
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(4)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, first_finding_duplicate.id, first_finding_duplicate.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, second_finding_duplicate.id, second_finding_duplicate.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(6.minutes, third_finding_duplicate.id, third_finding_duplicate.id)
- expect(described_class::MIGRATION).to be_scheduled_delayed_migration(8.minutes, unrelated_finding.id, unrelated_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:, id: nil,
- name: "test", severity: 7, confidence: 7, report_type: 0,
- project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
- metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid)
- params = {
- 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: vulnerability_identifier.id,
- location_fingerprint: location_fingerprint,
- metadata_version: metadata_version,
- raw_metadata: raw_metadata,
- uuid: uuid
- }
- params[:id] = id unless id.nil?
- vulnerability_findings.create!(params)
- end
- # rubocop:enable Metrics/ParameterLists
-
- def create_user!(name: "Example User", email: "user@example.com", user_type: nil, created_at: Time.zone.now, confirmed_at: Time.zone.now)
- users.create!(
- name: name,
- email: email,
- username: name,
- projects_limit: 0,
- user_type: user_type,
- confirmed_at: confirmed_at
- )
- end
-
- def create_finding_pipeline!(project_id:, finding_id:)
- pipeline = pipelines.create!(project_id: project_id)
- vulnerability_finding_pipelines.create!(pipeline_id: pipeline.id, occurrence_id: finding_id)
- end
-end
diff --git a/spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb b/spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb
deleted file mode 100644
index bfe2b661a31..00000000000
--- a/spec/migrations/20211117084814_migrate_remaining_u2f_registrations_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe MigrateRemainingU2fRegistrations, :migration, feature_category: :authentication_and_authorization do
- let(:u2f_registrations) { table(:u2f_registrations) }
- let(:webauthn_registrations) { table(:webauthn_registrations) }
- let(:users) { table(:users) }
-
- let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) }
-
- before do
- create_u2f_registration(1, 'reg1')
- create_u2f_registration(2, 'reg2')
- create_u2f_registration(3, '')
- create_u2f_registration(4, nil)
- webauthn_registrations.create!({ name: 'reg1', u2f_registration_id: 1, credential_xid: '', public_key: '', user_id: user.id })
- end
-
- it 'correctly migrates u2f registrations previously not migrated' do
- expect { migrate! }.to change { webauthn_registrations.count }.from(1).to(4)
- end
-
- it 'migrates all valid u2f registrations depite errors' do
- create_u2f_registration(5, 'reg3', 'invalid!')
- create_u2f_registration(6, 'reg4')
-
- expect { migrate! }.to change { webauthn_registrations.count }.from(1).to(5)
- end
-
- def create_u2f_registration(id, name, public_key = nil)
- device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5), { key_handle: SecureRandom.random_bytes(255) })
- public_key ||= Base64.strict_encode64(device.origin_public_key_raw)
- u2f_registrations.create!({ id: id,
- certificate: Base64.strict_encode64(device.cert_raw),
- key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
- public_key: public_key,
- counter: 5,
- name: name,
- user_id: user.id })
- end
-end
diff --git a/spec/migrations/20211126115449_encrypt_static_objects_external_storage_auth_token_spec.rb b/spec/migrations/20211126115449_encrypt_static_objects_external_storage_auth_token_spec.rb
deleted file mode 100644
index 09a8bb44d88..00000000000
--- a/spec/migrations/20211126115449_encrypt_static_objects_external_storage_auth_token_spec.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe EncryptStaticObjectsExternalStorageAuthToken, :migration, feature_category: :source_code_management do
- let(:application_settings) do
- Class.new(ActiveRecord::Base) do
- self.table_name = 'application_settings'
- end
- end
-
- context 'when static_objects_external_storage_auth_token is not set' do
- it 'does nothing' do
- application_settings.create!
-
- reversible_migration do |migration|
- migration.before -> {
- settings = application_settings.first
-
- expect(settings.static_objects_external_storage_auth_token).to be_nil
- expect(settings.static_objects_external_storage_auth_token_encrypted).to be_nil
- }
-
- migration.after -> {
- settings = application_settings.first
-
- expect(settings.static_objects_external_storage_auth_token).to be_nil
- expect(settings.static_objects_external_storage_auth_token_encrypted).to be_nil
- }
- end
- end
- end
-
- context 'when static_objects_external_storage_auth_token is set' do
- it 'encrypts static_objects_external_storage_auth_token' do
- settings = application_settings.create!
- settings.update_column(:static_objects_external_storage_auth_token, 'Test')
-
- reversible_migration do |migration|
- migration.before -> {
- settings = application_settings.first
-
- expect(settings.static_objects_external_storage_auth_token).to eq('Test')
- expect(settings.static_objects_external_storage_auth_token_encrypted).to be_nil
- }
- migration.after -> {
- settings = application_settings.first
-
- expect(settings.static_objects_external_storage_auth_token).to eq('Test')
- expect(settings.static_objects_external_storage_auth_token_encrypted).to be_present
- }
- end
- end
- end
-
- context 'when static_objects_external_storage_auth_token is empty string' do
- it 'does not break' do
- settings = application_settings.create!
- settings.update_column(:static_objects_external_storage_auth_token, '')
-
- reversible_migration do |migration|
- migration.before -> {
- settings = application_settings.first
-
- expect(settings.static_objects_external_storage_auth_token).to eq('')
- expect(settings.static_objects_external_storage_auth_token_encrypted).to be_nil
- }
- migration.after -> {
- settings = application_settings.first
-
- expect(settings.static_objects_external_storage_auth_token).to eq('')
- expect(settings.static_objects_external_storage_auth_token_encrypted).to be_nil
- }
- end
- end
- end
-end
diff --git a/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb b/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb
deleted file mode 100644
index db68e895b61..00000000000
--- a/spec/migrations/20211126204445_add_task_to_work_item_types_spec.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe AddTaskToWorkItemTypes, :migration, feature_category: :team_planning do
- include MigrationHelpers::WorkItemTypesHelper
-
- let!(:work_item_types) { table(:work_item_types) }
-
- let(:base_types) do
- {
- issue: 0,
- incident: 1,
- test_case: 2,
- requirement: 3,
- task: 4
- }
- end
-
- 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
- end
-
- it 'skips creating the record if it already exists' do
- reset_db_state_prior_to_migration
- work_item_types.find_or_create_by!(name: 'Task', namespace_id: nil, base_type: base_types[:task], icon_name: 'issue-type-task')
-
- expect do
- migrate!
- end.to not_change(work_item_types, :count)
- end
-
- it 'adds task to base work item types' do
- reset_db_state_prior_to_migration
-
- expect do
- migrate!
- end.to change(work_item_types, :count).from(4).to(5)
-
- expect(work_item_types.all.pluck(:base_type)).to include(base_types[:task])
- end
-
- def reset_db_state_prior_to_migration
- # Database needs to be in a similar state as when this migration was created
- work_item_types.delete_all
- work_item_types.find_or_create_by!(name: 'Issue', namespace_id: nil, base_type: base_types[:issue], icon_name: 'issue-type-issue')
- work_item_types.find_or_create_by!(name: 'Incident', namespace_id: nil, base_type: base_types[:incident], icon_name: 'issue-type-incident')
- work_item_types.find_or_create_by!(name: 'Test Case', namespace_id: nil, base_type: base_types[:test_case], icon_name: 'issue-type-test-case')
- work_item_types.find_or_create_by!(name: 'Requirement', namespace_id: nil, base_type: base_types[:requirement], icon_name: 'issue-type-requirements')
- end
-end
diff --git a/spec/migrations/20211130165043_backfill_sequence_column_for_sprints_table_spec.rb b/spec/migrations/20211130165043_backfill_sequence_column_for_sprints_table_spec.rb
deleted file mode 100644
index 91646da4791..00000000000
--- a/spec/migrations/20211130165043_backfill_sequence_column_for_sprints_table_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe BackfillSequenceColumnForSprintsTable, :migration, schema: 20211126042235, feature_category: :team_planning do
- let(:migration) { described_class.new }
- let(:namespaces) { table(:namespaces) }
- let(:sprints) { table(:sprints) }
- let(:iterations_cadences) { table(:iterations_cadences) }
-
- let!(:group) { namespaces.create!(name: 'foo', path: 'foo') }
- let!(:cadence_1) { iterations_cadences.create!(group_id: group.id, title: "cadence 1") }
- let!(:cadence_2) { iterations_cadences.create!(group_id: group.id, title: "cadence 2") }
- let!(:iteration_1) { sprints.create!(id: 1, group_id: group.id, iterations_cadence_id: cadence_1.id, start_date: Date.new(2021, 11, 1), due_date: Date.new(2021, 11, 5), iid: 1, title: 'a' ) }
- let!(:iteration_2) { sprints.create!(id: 2, group_id: group.id, iterations_cadence_id: cadence_1.id, start_date: Date.new(2021, 12, 1), due_date: Date.new(2021, 12, 5), iid: 2, title: 'b') }
- let!(:iteration_3) { sprints.create!(id: 3, group_id: group.id, iterations_cadence_id: cadence_2.id, start_date: Date.new(2021, 12, 1), due_date: Date.new(2021, 12, 5), iid: 4, title: 'd') }
- let!(:iteration_4) { sprints.create!(id: 4, group_id: group.id, iterations_cadence_id: nil, start_date: Date.new(2021, 11, 15), due_date: Date.new(2021, 11, 20), iid: 3, title: 'c') }
-
- describe '#up' do
- it "correctly sets the sequence attribute with idempotency" do
- migration.up
-
- expect(iteration_1.reload.sequence).to be 1
- expect(iteration_2.reload.sequence).to be 2
- expect(iteration_3.reload.sequence).to be 1
- expect(iteration_4.reload.sequence).to be nil
-
- iteration_5 = sprints.create!(id: 5, group_id: group.id, iterations_cadence_id: cadence_1.id, start_date: Date.new(2022, 1, 1), due_date: Date.new(2022, 1, 5), iid: 1, title: 'e' )
-
- migration.down
- migration.up
-
- expect(iteration_1.reload.sequence).to be 1
- expect(iteration_2.reload.sequence).to be 2
- expect(iteration_5.reload.sequence).to be 3
- expect(iteration_3.reload.sequence).to be 1
- expect(iteration_4.reload.sequence).to be nil
- end
- end
-end
diff --git a/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
index be89ee9d2aa..9fa2ac2313a 100644
--- a/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
+++ b/spec/migrations/20211207125331_remove_jobs_for_recalculate_vulnerabilities_occurrences_uuid_spec.rb
@@ -21,7 +21,7 @@ def create_background_migration_jobs(ids, status, created_at)
end
RSpec.describe RemoveJobsForRecalculateVulnerabilitiesOccurrencesUuid, :migration,
-feature_category: :vulnerability_management do
+ feature_category: :vulnerability_management do
let!(:background_migration_jobs) { table(:background_migration_jobs) }
context 'when RecalculateVulnerabilitiesOccurrencesUuid jobs are present' do
diff --git a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb
index ee468f40908..b9189cbae7f 100644
--- a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb
+++ b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe DedupRunnerProjects, :migration, :suppress_gitlab_schemas_validate_connection,
-schema: 20220120085655, feature_category: :runner do
+ schema: 20220120085655, feature_category: :runner do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:runners) { table(:ci_runners) }
diff --git a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
index ea88cf1a2ce..3abe173196f 100644
--- a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
+++ b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!('remove_dangling_running_builds')
RSpec.describe RemoveDanglingRunningBuilds, :suppress_gitlab_schemas_validate_connection,
-feature_category: :continuous_integration do
+ feature_category: :continuous_integration do
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
let(:project) { table(:projects).create!(namespace_id: namespace.id) }
let(:runner) { table(:ci_runners).create!(runner_type: 1) }
diff --git a/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb b/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
index 3bdd6e5fab9..98e2ba4816b 100644
--- a/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
+++ b/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
@@ -14,9 +14,7 @@ RSpec.describe RemoveDuplicateProjectTagReleases, feature_category: :release_orc
let(:dup_releases) do
Array.new(4).fill do |i|
- rel = releases.new(project_id: project.id,
- tag: "duplicate tag",
- released_at: (DateTime.now + i.days))
+ rel = releases.new(project_id: project.id, tag: "duplicate tag", released_at: (DateTime.now + i.days))
rel.save!(validate: false)
rel
end
diff --git a/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb b/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
index c0b94313d4d..8df9907643e 100644
--- a/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
+++ b/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
require_migration!
-RSpec.describe RemoveLeftoverExternalPullRequestDeletions, feature_category: :pods do
+RSpec.describe RemoveLeftoverExternalPullRequestDeletions, feature_category: :cell do
let(:deleted_records) { table(:loose_foreign_keys_deleted_records) }
let(:pending_record1) { deleted_records.create!(id: 1, fully_qualified_table_name: 'public.external_pull_requests', primary_key_value: 1, status: 1) }
diff --git a/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb b/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
index f40f9c70833..5d9be79e768 100644
--- a/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
+++ b/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe RemoveDependencyListUsageDataFromRedis, :migration, :clean_gitlab_redis_shared_state,
-feature_category: :dependency_management do
+ feature_category: :dependency_management do
let(:key) { "DEPENDENCY_LIST_USAGE_COUNTER" }
describe "#up" do
diff --git a/spec/migrations/20220324032250_migrate_shimo_confluence_service_category_spec.rb b/spec/migrations/20220324032250_migrate_shimo_confluence_service_category_spec.rb
index 15c16a2b232..6f9e70aa8c8 100644
--- a/spec/migrations/20220324032250_migrate_shimo_confluence_service_category_spec.rb
+++ b/spec/migrations/20220324032250_migrate_shimo_confluence_service_category_spec.rb
@@ -11,8 +11,9 @@ RSpec.describe MigrateShimoConfluenceServiceCategory, :migration, feature_catego
before do
namespace = namespaces.create!(name: 'test', path: 'test')
projects.create!(id: 1, namespace_id: namespace.id, name: 'gitlab', path: 'gitlab')
- integrations.create!(id: 1, active: true, type_new: "Integrations::SlackSlashCommands",
- category: 'chat', project_id: 1)
+ integrations.create!(
+ id: 1, active: true, type_new: "Integrations::SlackSlashCommands", category: 'chat', project_id: 1
+ )
integrations.create!(id: 3, active: true, type_new: "Integrations::Confluence", category: 'common', project_id: 1)
integrations.create!(id: 5, active: true, type_new: "Integrations::Shimo", category: 'common', project_id: 1)
end
diff --git a/spec/migrations/20220329175119_remove_leftover_ci_job_artifact_deletions_spec.rb b/spec/migrations/20220329175119_remove_leftover_ci_job_artifact_deletions_spec.rb
index e9bca42f37f..ca2ee6d8aba 100644
--- a/spec/migrations/20220329175119_remove_leftover_ci_job_artifact_deletions_spec.rb
+++ b/spec/migrations/20220329175119_remove_leftover_ci_job_artifact_deletions_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
require_migration!
-RSpec.describe RemoveLeftoverCiJobArtifactDeletions, feature_category: :pods do
+RSpec.describe RemoveLeftoverCiJobArtifactDeletions, feature_category: :cell do
let(:deleted_records) { table(:loose_foreign_keys_deleted_records) }
target_table_name = Ci::JobArtifact.table_name
diff --git a/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb b/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb
index 3a6a8f5dbe5..16258eeb0fb 100644
--- a/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb
+++ b/spec/migrations/20220505044348_fix_automatic_iterations_cadences_start_date_spec.rb
@@ -28,19 +28,19 @@ RSpec.describe FixAutomaticIterationsCadencesStartDate, feature_category: :team_
before do
sprints.create!(id: 2, start_date: jan2022, due_date: jan2022 + 1.week, iterations_cadence_id: cadence1.id,
- group_id: group1.id, iid: 1)
+ group_id: group1.id, iid: 1)
sprints.create!(id: 1, start_date: dec2022, due_date: dec2022 + 1.week, iterations_cadence_id: cadence1.id,
- group_id: group1.id, iid: 2)
+ group_id: group1.id, iid: 2)
sprints.create!(id: 4, start_date: feb2022, due_date: feb2022 + 1.week, iterations_cadence_id: cadence3.id,
- group_id: group2.id, iid: 1)
+ group_id: group2.id, iid: 1)
sprints.create!(id: 3, start_date: may2022, due_date: may2022 + 1.week, iterations_cadence_id: cadence3.id,
- group_id: group2.id, iid: 2)
+ group_id: group2.id, iid: 2)
sprints.create!(id: 5, start_date: may2022, due_date: may2022 + 1.week, iterations_cadence_id: cadence4.id,
- group_id: group2.id, iid: 4)
+ group_id: group2.id, iid: 4)
sprints.create!(id: 6, start_date: feb2022, due_date: feb2022 + 1.week, iterations_cadence_id: cadence4.id,
- group_id: group2.id, iid: 3)
+ group_id: group2.id, iid: 3)
end
describe '#up' do
diff --git a/spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb b/spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb
index 735232dfac7..b03849b61a2 100644
--- a/spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb
+++ b/spec/migrations/20220513043344_reschedule_expire_o_auth_tokens_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe RescheduleExpireOAuthTokens, feature_category: :authentication_and_authorization do
+RSpec.describe RescheduleExpireOAuthTokens, feature_category: :system_access do
let!(:migration) { described_class::MIGRATION }
describe '#up' do
diff --git a/spec/migrations/20220601152916_add_user_id_and_ip_address_success_index_to_authentication_events_spec.rb b/spec/migrations/20220601152916_add_user_id_and_ip_address_success_index_to_authentication_events_spec.rb
index 1b8ec47f61b..c01d982c34e 100644
--- a/spec/migrations/20220601152916_add_user_id_and_ip_address_success_index_to_authentication_events_spec.rb
+++ b/spec/migrations/20220601152916_add_user_id_and_ip_address_success_index_to_authentication_events_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe AddUserIdAndIpAddressSuccessIndexToAuthenticationEvents,
-feature_category: :authentication_and_authorization do
+ feature_category: :system_access do
let(:db) { described_class.new }
let(:old_index) { described_class::OLD_INDEX_NAME }
let(:new_index) { described_class::NEW_INDEX_NAME }
diff --git a/spec/migrations/20220606082910_add_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb b/spec/migrations/20220606082910_add_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb
index b74e15d804f..4ae40933541 100644
--- a/spec/migrations/20220606082910_add_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb
+++ b/spec/migrations/20220606082910_add_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb
@@ -5,7 +5,7 @@ require "spec_helper"
require_migration!
RSpec.describe AddTmpIndexForPotentiallyMisassociatedVulnerabilityOccurrences,
-feature_category: :vulnerability_management do
+ feature_category: :vulnerability_management do
let(:async_index) { Gitlab::Database::AsyncIndexes::PostgresAsyncIndex }
let(:index_name) { described_class::INDEX_NAME }
diff --git a/spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb b/spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb
index 8d3ef9a46d7..d4a800eb1db 100644
--- a/spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb
+++ b/spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb
@@ -5,7 +5,7 @@ require "spec_helper"
require_migration!
RSpec.describe AddSyncTmpIndexForPotentiallyMisassociatedVulnerabilityOccurrences,
-feature_category: :vulnerability_management do
+ feature_category: :vulnerability_management do
let(:table) { "vulnerability_occurrences" }
let(:index) { described_class::INDEX_NAME }
diff --git a/spec/migrations/20220628012902_finalise_project_namespace_members_spec.rb b/spec/migrations/20220628012902_finalise_project_namespace_members_spec.rb
index 55cabc21997..fb1a4782f3b 100644
--- a/spec/migrations/20220628012902_finalise_project_namespace_members_spec.rb
+++ b/spec/migrations/20220628012902_finalise_project_namespace_members_spec.rb
@@ -12,12 +12,16 @@ RSpec.describe FinaliseProjectNamespaceMembers, :migration, feature_category: :s
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
- expect(runner).to receive(:finalize).with('BackfillProjectMemberNamespaceId', :members, :id, [])
+ expect(runner).to receive(:finalize).with(migration, :members, :id, [])
end
end
end
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -29,7 +33,7 @@ RSpec.describe FinaliseProjectNamespaceMembers, :migration, feature_category: :s
context 'with migration present' do
let!(:project_member_namespace_id_backfill) do
batched_migrations.create!(
- job_class_name: 'BackfillProjectMemberNamespaceId',
+ job_class_name: migration,
table_name: :members,
column_name: :id,
job_arguments: [],
diff --git a/spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb b/spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb
index f8f1565fe4c..a9f0bdc8487 100644
--- a/spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb
+++ b/spec/migrations/20220801155858_schedule_disable_legacy_open_source_licence_for_recent_public_projects_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
require_migration!
-RSpec.describe ScheduleDisableLegacyOpenSourceLicenceForRecentPublicProjects, schema: 20220801155858,
- feature_category: :projects do
+RSpec.describe ScheduleDisableLegacyOpenSourceLicenceForRecentPublicProjects,
+ schema: 20220801155858, feature_category: :projects do
context 'when on gitlab.com' do
let(:background_migration) { described_class::MIGRATION }
let(:migration) { described_class.new }
diff --git a/spec/migrations/20220802204737_remove_deactivated_user_highest_role_stats_spec.rb b/spec/migrations/20220802204737_remove_deactivated_user_highest_role_stats_spec.rb
index 36c65612bb9..b731a8c8c18 100644
--- a/spec/migrations/20220802204737_remove_deactivated_user_highest_role_stats_spec.rb
+++ b/spec/migrations/20220802204737_remove_deactivated_user_highest_role_stats_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe RemoveDeactivatedUserHighestRoleStats, feature_category: :subscription_cost_management do
+RSpec.describe RemoveDeactivatedUserHighestRoleStats, feature_category: :seat_cost_management do
let!(:users) { table(:users) }
let!(:user_highest_roles) { table(:user_highest_roles) }
diff --git a/spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb b/spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb
index 25b2b5c2e18..0807f5d4e38 100644
--- a/spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb
+++ b/spec/migrations/20220816163444_update_start_date_for_iterations_cadences_spec.rb
@@ -31,31 +31,31 @@ RSpec.describe UpdateStartDateForIterationsCadences, :freeze_time, feature_categ
before do
# Past iteratioin
sprints.create!(id: 1, iid: 1, **cadence_params(auto_cadence1),
- start_date: Date.current - 1.week, due_date: Date.current - 1.day)
+ start_date: Date.current - 1.week, due_date: Date.current - 1.day)
# Current iteraition
sprints.create!(id: 3, iid: 5, **cadence_params(auto_cadence1),
- start_date: Date.current, due_date: Date.current + 1.week)
+ start_date: Date.current, due_date: Date.current + 1.week)
# First upcoming iteration
sprints.create!(id: 4, iid: 8, **cadence_params(auto_cadence1),
- start_date: first_upcoming_start_date, due_date: first_upcoming_start_date + 1.week)
+ start_date: first_upcoming_start_date, due_date: first_upcoming_start_date + 1.week)
# Second upcoming iteration
sprints.create!(id: 5, iid: 9, **cadence_params(auto_cadence1),
- start_date: first_upcoming_start_date + 2.weeks, due_date: first_upcoming_start_date + 3.weeks)
+ start_date: first_upcoming_start_date + 2.weeks, due_date: first_upcoming_start_date + 3.weeks)
sprints.create!(id: 6, iid: 1, **cadence_params(manual_cadence2),
- start_date: Date.current, due_date: Date.current + 1.week)
+ start_date: Date.current, due_date: Date.current + 1.week)
sprints.create!(id: 7, iid: 5, **cadence_params(manual_cadence2),
- start_date: Date.current + 2.weeks, due_date: Date.current + 3.weeks)
+ start_date: Date.current + 2.weeks, due_date: Date.current + 3.weeks)
end
describe '#up' do
it "updates the start date of an automatic cadence to the start date of its first upcoming sprint record." do
expect { migration.up }
- .to change { auto_cadence1.reload.start_date }.to(first_upcoming_start_date)
- .and not_change { auto_cadence2.reload.start_date } # the cadence doesn't have any upcoming iteration.
- .and not_change { auto_cadence3.reload.start_date } # the cadence is empty; it has no iterations.
- .and not_change { manual_cadence1.reload.start_date } # manual cadence don't need to be touched.
- .and not_change { manual_cadence2.reload.start_date } # manual cadence don't need to be touched.
+ .to change { auto_cadence1.reload.start_date }.to(first_upcoming_start_date)
+ .and not_change { auto_cadence2.reload.start_date } # the cadence doesn't have any upcoming iteration.
+ .and not_change { auto_cadence3.reload.start_date } # the cadence is empty; it has no iterations.
+ .and not_change { manual_cadence1.reload.start_date } # manual cadence don't need to be touched.
+ .and not_change { manual_cadence2.reload.start_date } # manual cadence don't need to be touched.
end
end
@@ -64,10 +64,10 @@ RSpec.describe UpdateStartDateForIterationsCadences, :freeze_time, feature_categ
migration.up
expect { migration.down }
- .to change { auto_cadence1.reload.start_date }.to(original_cadence_start_date)
- .and not_change { auto_cadence2.reload.start_date } # the cadence is empty; it has no iterations.
- .and not_change { manual_cadence1.reload.start_date } # manual cadence don't need to be touched.
- .and not_change { manual_cadence2.reload.start_date } # manual cadence don't need to be touched.
+ .to change { auto_cadence1.reload.start_date }.to(original_cadence_start_date)
+ .and not_change { auto_cadence2.reload.start_date } # the cadence is empty; it has no iterations.
+ .and not_change { manual_cadence1.reload.start_date } # manual cadence don't need to be touched.
+ .and not_change { manual_cadence2.reload.start_date } # manual cadence don't need to be touched.
end
end
end
diff --git a/spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb b/spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb
index 5a61f49485c..1d18862c8ee 100644
--- a/spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb
+++ b/spec/migrations/20220819153725_add_vulnerability_advisory_foreign_key_to_sbom_vulnerable_component_versions_spec.rb
@@ -5,7 +5,7 @@ require "spec_helper"
require_migration!
RSpec.describe AddVulnerabilityAdvisoryForeignKeyToSbomVulnerableComponentVersions,
-feature_category: :dependency_management do
+ feature_category: :dependency_management do
let(:table) { described_class::SOURCE_TABLE }
let(:column) { described_class::COLUMN }
let(:foreign_key) { -> { described_class.new.foreign_keys_for(table, column).first } }
diff --git a/spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb b/spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb
index 999c833f9e3..a280795380d 100644
--- a/spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb
+++ b/spec/migrations/20220819162852_add_sbom_component_version_foreign_key_to_sbom_vulnerable_component_versions_spec.rb
@@ -5,7 +5,7 @@ require "spec_helper"
require_migration!
RSpec.describe AddSbomComponentVersionForeignKeyToSbomVulnerableComponentVersions,
-feature_category: :dependency_management do
+ feature_category: :dependency_management do
let(:table) { described_class::SOURCE_TABLE }
let(:column) { described_class::COLUMN }
let(:foreign_key) { -> { described_class.new.foreign_keys_for(table, column).first } }
diff --git a/spec/migrations/20220921144258_remove_orphan_group_token_users_spec.rb b/spec/migrations/20220921144258_remove_orphan_group_token_users_spec.rb
index 19cf3b2fb69..5cfcb2eb3dd 100644
--- a/spec/migrations/20220921144258_remove_orphan_group_token_users_spec.rb
+++ b/spec/migrations/20220921144258_remove_orphan_group_token_users_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
require_migration!
RSpec.describe RemoveOrphanGroupTokenUsers, :migration, :sidekiq_inline,
-feature_category: :authentication_and_authorization do
+ feature_category: :system_access do
subject(:migration) { described_class.new }
let(:users) { table(:users) }
@@ -18,12 +18,14 @@ feature_category: :authentication_and_authorization do
let!(:valid_used_bot) do
create_bot(username: 'used_bot', email: 'used_bot@bot.com').tap do |bot|
group = namespaces.create!(type: 'Group', path: 'used_bot_group', name: 'used_bot_group')
- members.create!(user_id: bot.id,
- source_id: group.id,
- member_namespace_id: group.id,
- source_type: 'Group',
- access_level: 10,
- notification_level: 0)
+ members.create!(
+ user_id: bot.id,
+ source_id: group.id,
+ member_namespace_id: group.id,
+ source_type: 'Group',
+ access_level: 10,
+ notification_level: 0
+ )
end
end
diff --git a/spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb b/spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb
index 5c1b5c8f2a7..085e9726663 100644
--- a/spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb
+++ b/spec/migrations/20220928225711_schedule_update_ci_pipeline_artifacts_locked_status_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
require_migration!
-RSpec.describe ScheduleUpdateCiPipelineArtifactsLockedStatus, migration: :gitlab_ci,
- feature_category: :build_artifacts do
+RSpec.describe ScheduleUpdateCiPipelineArtifactsLockedStatus,
+ migration: :gitlab_ci, feature_category: :build_artifacts do
let!(:migration) { described_class::MIGRATION }
describe '#up' do
diff --git a/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb b/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
index 4ff16111417..632b23a8384 100644
--- a/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
+++ b/spec/migrations/20221002234454_finalize_group_member_namespace_id_migration_spec.rb
@@ -12,12 +12,16 @@ RSpec.describe FinalizeGroupMemberNamespaceIdMigration, :migration, feature_cate
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
- expect(runner).to receive(:finalize).with('BackfillMemberNamespaceForGroupMembers', :members, :id, [])
+ expect(runner).to receive(:finalize).with(migration, :members, :id, [])
end
end
end
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -29,7 +33,7 @@ RSpec.describe FinalizeGroupMemberNamespaceIdMigration, :migration, feature_cate
context 'with migration present' do
let!(:group_member_namespace_id_backfill) do
batched_migrations.create!(
- job_class_name: 'BackfillMemberNamespaceForGroupMembers',
+ job_class_name: migration,
table_name: :members,
column_name: :id,
job_arguments: [],
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 6284608becb..d591b370d65 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
@@ -28,10 +28,12 @@ RSpec.describe AddObjectiveAndKeyresultToWorkItemTypes, :migration, feature_cate
it 'skips creating both objective & keyresult type record if it already exists' do
reset_db_state_prior_to_migration
- work_item_types.find_or_create_by!(name: 'Key Result', namespace_id: nil, base_type: base_types[:key_result],
- icon_name: 'issue-type-keyresult')
- work_item_types.find_or_create_by!(name: 'Objective', namespace_id: nil, base_type: base_types[:objective],
- icon_name: 'issue-type-objective')
+ work_item_types.find_or_create_by!(
+ name: 'Key Result', namespace_id: nil, base_type: base_types[:key_result], icon_name: 'issue-type-keyresult'
+ )
+ work_item_types.find_or_create_by!(
+ name: 'Objective', namespace_id: nil, base_type: base_types[:objective], icon_name: 'issue-type-objective'
+ )
expect do
migrate!
@@ -52,15 +54,20 @@ RSpec.describe AddObjectiveAndKeyresultToWorkItemTypes, :migration, feature_cate
def reset_db_state_prior_to_migration
# Database needs to be in a similar state as when this migration was created
work_item_types.delete_all
- work_item_types.find_or_create_by!(name: 'Issue', namespace_id: nil, base_type: base_types[:issue],
- icon_name: 'issue-type-issue')
- work_item_types.find_or_create_by!(name: 'Incident', namespace_id: nil, base_type: base_types[:incident],
- icon_name: 'issue-type-incident')
- work_item_types.find_or_create_by!(name: 'Test Case', namespace_id: nil, base_type: base_types[:test_case],
- icon_name: 'issue-type-test-case')
- work_item_types.find_or_create_by!(name: 'Requirement', namespace_id: nil, base_type: base_types[:requirement],
- icon_name: 'issue-type-requirements')
- work_item_types.find_or_create_by!(name: 'Task', namespace_id: nil, base_type: base_types[:task],
- icon_name: 'issue-type-task')
+ work_item_types.find_or_create_by!(
+ name: 'Issue', namespace_id: nil, base_type: base_types[:issue], icon_name: 'issue-type-issue'
+ )
+ work_item_types.find_or_create_by!(
+ name: 'Incident', namespace_id: nil, base_type: base_types[:incident], icon_name: 'issue-type-incident'
+ )
+ work_item_types.find_or_create_by!(
+ name: 'Test Case', namespace_id: nil, base_type: base_types[:test_case], icon_name: 'issue-type-test-case'
+ )
+ work_item_types.find_or_create_by!(
+ name: 'Requirement', namespace_id: nil, base_type: base_types[:requirement], icon_name: 'issue-type-requirements'
+ )
+ work_item_types.find_or_create_by!(
+ name: 'Task', namespace_id: nil, base_type: base_types[:task], icon_name: 'issue-type-task'
+ )
end
end
diff --git a/spec/migrations/20221018193635_ensure_task_note_renaming_background_migration_finished_spec.rb b/spec/migrations/20221018193635_ensure_task_note_renaming_background_migration_finished_spec.rb
index 8b599881359..da1df92691e 100644
--- a/spec/migrations/20221018193635_ensure_task_note_renaming_background_migration_finished_spec.rb
+++ b/spec/migrations/20221018193635_ensure_task_note_renaming_background_migration_finished_spec.rb
@@ -25,6 +25,10 @@ RSpec.describe EnsureTaskNoteRenamingBackgroundMigrationFinished, :migration, fe
end
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -36,7 +40,7 @@ RSpec.describe EnsureTaskNoteRenamingBackgroundMigrationFinished, :migration, fe
context 'with migration present' do
let!(:task_renaming_migration) do
batched_migrations.create!(
- job_class_name: 'RenameTaskSystemNoteToChecklistItem',
+ job_class_name: migration,
table_name: :system_note_metadata,
column_name: :id,
job_arguments: [],
diff --git a/spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb b/spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb
index 37bff128edd..da2f4364e5c 100644
--- a/spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb
+++ b/spec/migrations/20221102231130_finalize_backfill_user_details_fields_spec.rb
@@ -26,6 +26,10 @@ RSpec.describe FinalizeBackfillUserDetailsFields, :migration, feature_category:
end
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
diff --git a/spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb b/spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb
index d86720365c4..9658b5a699a 100644
--- a/spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb
+++ b/spec/migrations/20221104115712_backfill_project_statistics_storage_size_without_uploads_size_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe BackfillProjectStatisticsStorageSizeWithoutUploadsSize,
- feature_category: :subscription_cost_management do
+ feature_category: :consumables_cost_management do
let!(:batched_migration) { described_class::MIGRATION_CLASS }
it 'does not schedule background jobs when Gitlab.org_or_com? is false' do
diff --git a/spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb b/spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb
index e9250625832..d560da40c21 100644
--- a/spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb
+++ b/spec/migrations/20221115173607_ensure_work_item_type_backfill_migration_finished_spec.rb
@@ -13,6 +13,10 @@ RSpec.describe EnsureWorkItemTypeBackfillMigrationFinished, :migration, feature_
describe '#up', :redis do
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration_class).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
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
index da6532a822a..e5890ffce17 100644
--- 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
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe CleanupOAuthAccessTokensWithNullExpiresIn, feature_category: :authentication_and_authorization do
+RSpec.describe CleanupOAuthAccessTokensWithNullExpiresIn, feature_category: :system_access do
let(:batched_migration) { described_class::MIGRATION }
it 'schedules background jobs for each batch of oauth_access_tokens' do
diff --git a/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb b/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb
index d7aa53ec35b..7cc0bd96a0d 100644
--- a/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb
+++ b/spec/migrations/20221215151822_schedule_backfill_releases_author_id_spec.rb
@@ -10,21 +10,27 @@ RSpec.describe ScheduleBackfillReleasesAuthorId, feature_category: :release_orch
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)
+ 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)
+ 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
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
index 6f9cfe4764a..440a932c76b 100644
--- 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
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe RemoveTempIndexForProjectStatisticsUploadSizeMigration,
-feature_category: :subscription_cost_management do
+ feature_category: :consumables_cost_management do
let(:table_name) { 'project_statistics' }
let(:index_name) { described_class::INDEX_NAME }
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
index aa82ca2661b..70c9c1333b8 100644
--- 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
@@ -5,7 +5,7 @@ require 'spec_helper'
require_migration!
RSpec.describe SyncNewAmountUsedWithAmountUsedOnCiNamespaceMonthlyUsagesTable, migration: :gitlab_ci,
-feature_category: :continuous_integration do
+ feature_category: :continuous_integration do
let(:namespace_usages) { table(:ci_namespace_monthly_usages) }
let(:migration) { described_class.new }
diff --git a/spec/migrations/20230118144623_schedule_migration_for_remediation_spec.rb b/spec/migrations/20230118144623_schedule_migration_for_remediation_spec.rb
new file mode 100644
index 00000000000..f6d0f32b87c
--- /dev/null
+++ b/spec/migrations/20230118144623_schedule_migration_for_remediation_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleMigrationForRemediation, :migration, feature_category: :vulnerability_management do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules a batched background migration' do
+ migrate!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ 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/20230125195503_queue_backfill_compliance_violations_spec.rb b/spec/migrations/20230125195503_queue_backfill_compliance_violations_spec.rb
new file mode 100644
index 00000000000..a70f9820855
--- /dev/null
+++ b/spec/migrations/20230125195503_queue_backfill_compliance_violations_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillComplianceViolations, feature_category: :compliance_management do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of merge_request_compliance_violations' do
+ migrate!
+
+ expect(migration).to(
+ have_scheduled_batched_migration(
+ table_name: :merge_requests_compliance_violations,
+ column_name: :id,
+ interval: described_class::INTERVAL,
+ batch_size: described_class::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/backfill_user_namespace_spec.rb b/spec/migrations/20230130182412_schedule_create_vulnerability_links_migration_spec.rb
index a58030803b1..58e27379ef7 100644
--- a/spec/migrations/backfill_user_namespace_spec.rb
+++ b/spec/migrations/20230130182412_schedule_create_vulnerability_links_migration_spec.rb
@@ -3,17 +3,18 @@
require 'spec_helper'
require_migration!
-RSpec.describe BackfillUserNamespace, feature_category: :subgroups do
- let!(:migration) { described_class::MIGRATION }
+RSpec.describe ScheduleCreateVulnerabilityLinksMigration, feature_category: :vulnerability_management do
+ let(:migration) { described_class::MIGRATION }
describe '#up' do
- it 'schedules background jobs for each batch of namespaces' do
+ it 'schedules background jobs for each batch of Vulnerabilities::Feedback' do
migrate!
expect(migration).to have_scheduled_batched_migration(
- table_name: :namespaces,
+ table_name: :vulnerability_feedback,
column_name: :id,
- interval: described_class::INTERVAL
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE
)
end
end
diff --git a/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb b/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb
index 3fc9c7d8af7..e7a78f11f16 100644
--- a/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb
+++ b/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb
@@ -18,6 +18,10 @@ RSpec.describe FinalizeBackfillEnvironmentTierMigration, :migration, feature_cat
end
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -29,7 +33,7 @@ RSpec.describe FinalizeBackfillEnvironmentTierMigration, :migration, feature_cat
context 'with migration present' do
let!(:group_member_namespace_id_backfill) do
batched_migrations.create!(
- job_class_name: 'BackfillEnvironmentTiers',
+ job_class_name: migration,
table_name: :environments,
column_name: :id,
job_arguments: [],
diff --git a/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb b/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb
index a8896e7d3cf..597cd7c1581 100644
--- a/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb
+++ b/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb
@@ -9,14 +9,6 @@ RSpec.describe EncryptCiTriggerToken, migration: :gitlab_ci, feature_category: :
let!(:migration) { described_class::MIGRATION }
describe '#up' do
- shared_examples 'finalizes the migration' do
- it 'finalizes the migration' do
- allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
- expect(runner).to receive(:finalize).with('EncryptCiTriggerToken', :ci_triggers, :id, [])
- end
- end
- end
-
context 'with migration present' do
let!(:ci_trigger_token_encryption_migration) do
batched_migrations.create!(
@@ -51,25 +43,6 @@ RSpec.describe EncryptCiTriggerToken, migration: :gitlab_ci, feature_category: :
)
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
- ci_trigger_token_encryption_migration.update!(status: status)
- end
-
- it_behaves_like 'finalizes the migration'
- end
- end
end
end
diff --git a/spec/migrations/20230202211434_migrate_redis_slot_keys_spec.rb b/spec/migrations/20230202211434_migrate_redis_slot_keys_spec.rb
new file mode 100644
index 00000000000..ca2c50241bf
--- /dev/null
+++ b/spec/migrations/20230202211434_migrate_redis_slot_keys_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe MigrateRedisSlotKeys, :migration, feature_category: :service_ping do
+ let(:date) { Date.yesterday.strftime('%G-%j') }
+ let(:week) { Date.yesterday.strftime('%G-%V') }
+
+ before do
+ allow(described_class::BackupHLLRedisCounter).to receive(:known_events).and_return([{
+ redis_slot: 'analytics',
+ aggregation: 'daily',
+ name: 'users_viewing_analytics_group_devops_adoption'
+ }, {
+ aggregation: 'weekly',
+ name: 'wiki_action'
+ }])
+ end
+
+ describe "#up" do
+ it 'rename keys', :aggregate_failures do
+ expiry_daily = described_class::BackupHLLRedisCounter::DEFAULT_DAILY_KEY_EXPIRY_LENGTH
+ expiry_weekly = described_class::BackupHLLRedisCounter::DEFAULT_WEEKLY_KEY_EXPIRY_LENGTH
+
+ default_slot = described_class::BackupHLLRedisCounter::REDIS_SLOT
+
+ old_slot_a = "#{date}-users_viewing_{analytics}_group_devops_adoption"
+ old_slot_b = "{wiki_action}-#{week}"
+
+ new_slot_a = "#{date}-{#{default_slot}}_users_viewing_analytics_group_devops_adoption"
+ new_slot_b = "{#{default_slot}}_wiki_action-#{week}"
+
+ Gitlab::Redis::HLL.add(key: old_slot_a, value: 1, expiry: expiry_daily)
+ Gitlab::Redis::HLL.add(key: old_slot_b, value: 1, expiry: expiry_weekly)
+
+ # check that we merge values during migration
+ # i.e. we dont drop keys created after code deploy but before the migration
+ Gitlab::Redis::HLL.add(key: new_slot_a, value: 2, expiry: expiry_daily)
+ Gitlab::Redis::HLL.add(key: new_slot_b, value: 2, expiry: expiry_weekly)
+
+ migrate!
+
+ expect(Gitlab::Redis::HLL.count(keys: new_slot_a)).to eq(2)
+ expect(Gitlab::Redis::HLL.count(keys: new_slot_b)).to eq(2)
+ expect(with_redis { |r| r.ttl(new_slot_a) }).to be_within(600).of(expiry_daily)
+ expect(with_redis { |r| r.ttl(new_slot_b) }).to be_within(600).of(expiry_weekly)
+ end
+ end
+
+ def with_redis(&block)
+ Gitlab::Redis::SharedState.with(&block)
+ end
+end
diff --git a/spec/migrations/20230208125736_schedule_migration_for_links_spec.rb b/spec/migrations/20230208125736_schedule_migration_for_links_spec.rb
new file mode 100644
index 00000000000..035f13b8309
--- /dev/null
+++ b/spec/migrations/20230208125736_schedule_migration_for_links_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleMigrationForLinks, :migration, feature_category: :vulnerability_management do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules a batched background migration' do
+ migrate!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ 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/20230209222452_schedule_remove_project_group_link_with_missing_groups_spec.rb b/spec/migrations/20230209222452_schedule_remove_project_group_link_with_missing_groups_spec.rb
new file mode 100644
index 00000000000..13ae12b2774
--- /dev/null
+++ b/spec/migrations/20230209222452_schedule_remove_project_group_link_with_missing_groups_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleRemoveProjectGroupLinkWithMissingGroups, feature_category: :subgroups do
+ let!(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background migration' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :project_group_links,
+ 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 'removes scheduled background migrations' do
+ migrate!
+ schema_migrate_down!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/20230214181633_finalize_ci_build_needs_big_int_conversion_spec.rb b/spec/migrations/20230214181633_finalize_ci_build_needs_big_int_conversion_spec.rb
new file mode 100644
index 00000000000..638fe2a12d5
--- /dev/null
+++ b/spec/migrations/20230214181633_finalize_ci_build_needs_big_int_conversion_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FinalizeCiBuildNeedsBigIntConversion, migration: :gitlab_ci, feature_category: :continuous_integration do
+ describe '#up' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:dot_com, :dev_or_test, :jh, :expectation) do
+ true | true | true | :not_to
+ true | false | true | :not_to
+ false | true | true | :not_to
+ false | false | true | :not_to
+ true | true | false | :to
+ true | false | false | :to
+ false | true | false | :to
+ false | false | false | :not_to
+ end
+
+ with_them do
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ allow(Gitlab).to receive(:com?).and_return(dot_com)
+ allow(Gitlab).to receive(:dev_or_test_env?).and_return(dev_or_test)
+ allow(Gitlab).to receive(:jh?).and_return(jh)
+
+ migration_arguments = {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'ci_build_needs',
+ column_name: 'id',
+ job_arguments: [['id'], ['id_convert_to_bigint']]
+ }
+
+ expect(described_class).send(
+ expectation,
+ ensure_batched_background_migration_is_finished_for(migration_arguments)
+ )
+
+ migrate!
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230220102212_swap_columns_ci_build_needs_big_int_conversion_spec.rb b/spec/migrations/20230220102212_swap_columns_ci_build_needs_big_int_conversion_spec.rb
new file mode 100644
index 00000000000..1c21047c0c3
--- /dev/null
+++ b/spec/migrations/20230220102212_swap_columns_ci_build_needs_big_int_conversion_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapColumnsCiBuildNeedsBigIntConversion, feature_category: :continuous_integration do
+ describe '#up' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:dot_com, :dev_or_test, :jh, :swap) do
+ true | true | true | false
+ true | false | true | false
+ false | true | true | false
+ false | false | true | false
+ true | true | false | true
+ true | false | false | true
+ false | true | false | true
+ false | false | false | false
+ end
+
+ with_them do
+ before do
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE ci_build_needs ALTER COLUMN id TYPE integer')
+ connection.execute('ALTER TABLE ci_build_needs ALTER COLUMN id_convert_to_bigint TYPE bigint')
+ end
+
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow(Gitlab).to receive(:com?).and_return(dot_com)
+ allow(Gitlab).to receive(:dev_or_test_env?).and_return(dev_or_test)
+ allow(Gitlab).to receive(:jh?).and_return(jh)
+
+ ci_build_needs = table(:ci_build_needs)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ ci_build_needs.reset_column_information
+
+ expect(ci_build_needs.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(ci_build_needs.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ ci_build_needs.reset_column_information
+
+ if swap
+ expect(ci_build_needs.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(ci_build_needs.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('integer')
+ else
+ expect(ci_build_needs.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(ci_build_needs.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('bigint')
+ end
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230221093533_add_tmp_partial_index_on_vulnerability_report_types_spec.rb b/spec/migrations/20230221093533_add_tmp_partial_index_on_vulnerability_report_types_spec.rb
new file mode 100644
index 00000000000..cbf6b2882c4
--- /dev/null
+++ b/spec/migrations/20230221093533_add_tmp_partial_index_on_vulnerability_report_types_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+require_migration!
+
+RSpec.describe AddTmpPartialIndexOnVulnerabilityReportTypes, feature_category: :vulnerability_management do
+ let(:async_index) { Gitlab::Database::AsyncIndexes::PostgresAsyncIndex }
+ let(:index_name) { described_class::INDEX_NAME }
+
+ it "schedules the index" do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(async_index.where(name: index_name).count).to be(0)
+ end
+
+ migration.after -> do
+ expect(async_index.where(name: index_name).count).to be(1)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230221214519_remove_incorrectly_onboarded_namespaces_from_onboarding_progress_spec.rb b/spec/migrations/20230221214519_remove_incorrectly_onboarded_namespaces_from_onboarding_progress_spec.rb
new file mode 100644
index 00000000000..be49a3e919d
--- /dev/null
+++ b/spec/migrations/20230221214519_remove_incorrectly_onboarded_namespaces_from_onboarding_progress_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveIncorrectlyOnboardedNamespacesFromOnboardingProgress, feature_category: :onboarding do
+ let(:onboarding_progresses) { table(:onboarding_progresses) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ # namespace to keep with name Learn Gitlab
+ let(:namespace1) { namespaces.create!(name: 'namespace1', type: 'Group', path: 'namespace1') }
+ let!(:onboard_keep_1) { onboarding_progresses.create!(namespace_id: namespace1.id) }
+ let!(:proj1) do
+ proj_namespace = namespaces.create!(name: 'proj1', path: 'proj1', type: 'Project', parent_id: namespace1.id)
+ projects.create!(name: 'project', namespace_id: namespace1.id, project_namespace_id: proj_namespace.id)
+ end
+
+ let!(:learn_gitlab) do
+ proj_namespace = namespaces.create!(name: 'projlg1', path: 'projlg1', type: 'Project', parent_id: namespace1.id)
+ projects.create!(name: 'Learn GitLab', namespace_id: namespace1.id, project_namespace_id: proj_namespace.id)
+ end
+
+ # namespace to keep with name Learn GitLab - Ultimate trial
+ let(:namespace2) { namespaces.create!(name: 'namespace2', type: 'Group', path: 'namespace2') }
+ let!(:onboard_keep_2) { onboarding_progresses.create!(namespace_id: namespace2.id) }
+ let!(:proj2) do
+ proj_namespace = namespaces.create!(name: 'proj2', path: 'proj2', type: 'Project', parent_id: namespace2.id)
+ projects.create!(name: 'project', namespace_id: namespace2.id, project_namespace_id: proj_namespace.id)
+ end
+
+ let!(:learn_gitlab2) do
+ proj_namespace = namespaces.create!(name: 'projlg2', path: 'projlg2', type: 'Project', parent_id: namespace2.id)
+ projects.create!(
+ name: 'Learn GitLab - Ultimate trial',
+ namespace_id: namespace2.id,
+ project_namespace_id: proj_namespace.id
+ )
+ end
+
+ # namespace to remove without learn gitlab project
+ let(:namespace3) { namespaces.create!(name: 'namespace3', type: 'Group', path: 'namespace3') }
+ let!(:onboarding_to_delete) { onboarding_progresses.create!(namespace_id: namespace3.id) }
+ let!(:proj3) do
+ proj_namespace = namespaces.create!(name: 'proj3', path: 'proj3', type: 'Project', parent_id: namespace3.id)
+ projects.create!(name: 'project', namespace_id: namespace3.id, project_namespace_id: proj_namespace.id)
+ end
+
+ # namespace to remove without any projects
+ let(:namespace4) { namespaces.create!(name: 'namespace4', type: 'Group', path: 'namespace4') }
+ let!(:onboarding_to_delete_without_project) { onboarding_progresses.create!(namespace_id: namespace4.id) }
+
+ describe '#up' do
+ it 'deletes the onboarding for namespaces without learn gitlab' do
+ expect { migrate! }.to change { onboarding_progresses.count }.by(-2)
+ expect(onboarding_progresses.all).to contain_exactly(onboard_keep_1, onboard_keep_2)
+ end
+ end
+end
diff --git a/spec/migrations/20230223065753_finalize_nullify_creator_id_of_orphaned_projects_spec.rb b/spec/migrations/20230223065753_finalize_nullify_creator_id_of_orphaned_projects_spec.rb
new file mode 100644
index 00000000000..e4adf3ca540
--- /dev/null
+++ b/spec/migrations/20230223065753_finalize_nullify_creator_id_of_orphaned_projects_spec.rb
@@ -0,0 +1,97 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe FinalizeNullifyCreatorIdOfOrphanedProjects, :migration, feature_category: :projects do
+ let(:batched_migrations) { table(:batched_background_migrations) }
+ let(:batch_failed_status) { 2 }
+ let(:batch_finalized_status) { 3 }
+
+ let!(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ shared_examples 'finalizes the migration' do
+ it 'finalizes the migration' do
+ expect do
+ migrate!
+
+ migration_record.reload
+ failed_job.reload
+ end.to change { migration_record.status }.from(migration_record.status).to(3).and(
+ change { failed_job.status }.from(batch_failed_status).to(batch_finalized_status)
+ )
+ end
+ end
+
+ context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
+ it 'warns migration not found' do
+ expect(Gitlab::AppLogger)
+ .to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
+
+ migrate!
+ end
+ end
+
+ context 'with migration present' do
+ let!(:migration_record) do
+ batched_migrations.create!(
+ job_class_name: migration,
+ table_name: :projects,
+ column_name: :id,
+ job_arguments: [],
+ interval: 2.minutes,
+ min_value: 1,
+ max_value: 2,
+ batch_size: 1000,
+ sub_batch_size: 500,
+ max_batch_size: 5000,
+ 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', :redis do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:status, :description) do
+ 0 | 'paused'
+ 1 | 'active'
+ 4 | 'failed'
+ 5 | 'finalizing'
+ end
+
+ with_them do
+ let!(:failed_job) do
+ table(:batched_background_migration_jobs).create!(
+ batched_background_migration_id: migration_record.id,
+ status: batch_failed_status,
+ min_value: 1,
+ max_value: 10,
+ attempts: 2,
+ batch_size: 100,
+ sub_batch_size: 10
+ )
+ end
+
+ before do
+ migration_record.update!(status: status)
+ end
+
+ it_behaves_like 'finalizes the migration'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230224085743_update_issues_internal_id_scope_spec.rb b/spec/migrations/20230224085743_update_issues_internal_id_scope_spec.rb
new file mode 100644
index 00000000000..7c7b58c7f0e
--- /dev/null
+++ b/spec/migrations/20230224085743_update_issues_internal_id_scope_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe UpdateIssuesInternalIdScope, feature_category: :team_planning do
+ describe '#up' do
+ it 'schedules background migration' do
+ migrate!
+
+ expect(described_class::MIGRATION).to have_scheduled_batched_migration(
+ table_name: :internal_ids,
+ column_name: :id,
+ interval: described_class::INTERVAL)
+ end
+ end
+
+ describe '#down' do
+ it 'does not schedule background migration' do
+ schema_migrate_down!
+
+ expect(described_class::MIGRATION).not_to have_scheduled_batched_migration(
+ table_name: :internal_ids,
+ column_name: :id,
+ interval: described_class::INTERVAL)
+ end
+ end
+end
diff --git a/spec/migrations/20230224144233_migrate_evidences_from_raw_metadata_spec.rb b/spec/migrations/20230224144233_migrate_evidences_from_raw_metadata_spec.rb
new file mode 100644
index 00000000000..6610f70be2b
--- /dev/null
+++ b/spec/migrations/20230224144233_migrate_evidences_from_raw_metadata_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe MigrateEvidencesFromRawMetadata, :migration, feature_category: :vulnerability_management do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules a batched background migration' do
+ migrate!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ 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/20230228142350_add_notifications_work_item_widget_spec.rb b/spec/migrations/20230228142350_add_notifications_work_item_widget_spec.rb
new file mode 100644
index 00000000000..7161ca35edd
--- /dev/null
+++ b/spec/migrations/20230228142350_add_notifications_work_item_widget_spec.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddNotificationsWorkItemWidget, :migration, feature_category: :team_planning do
+ it_behaves_like 'migration that adds widget to work items definitions', widget_name: 'Notifications'
+end
diff --git a/spec/migrations/20230302185739_queue_fix_vulnerability_reads_has_issues_spec.rb b/spec/migrations/20230302185739_queue_fix_vulnerability_reads_has_issues_spec.rb
new file mode 100644
index 00000000000..54b1e231db2
--- /dev/null
+++ b/spec/migrations/20230302185739_queue_fix_vulnerability_reads_has_issues_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueFixVulnerabilityReadsHasIssues, feature_category: :vulnerability_management do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :vulnerability_issue_links,
+ column_name: :vulnerability_id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE,
+ max_batch_size: described_class::MAX_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230302811133_re_migrate_redis_slot_keys_spec.rb b/spec/migrations/20230302811133_re_migrate_redis_slot_keys_spec.rb
new file mode 100644
index 00000000000..4c6d4907c29
--- /dev/null
+++ b/spec/migrations/20230302811133_re_migrate_redis_slot_keys_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ReMigrateRedisSlotKeys, :migration, feature_category: :service_ping do
+ let(:date) { Date.yesterday.strftime('%G-%j') }
+ let(:week) { Date.yesterday.strftime('%G-%V') }
+ let(:known_events) do
+ [
+ {
+ redis_slot: 'analytics',
+ aggregation: 'daily',
+ name: 'users_viewing_analytics_group_devops_adoption'
+ }, {
+ aggregation: 'weekly',
+ name: 'wiki_action'
+ }, {
+ aggregation: 'weekly',
+ name: 'non_existing_event'
+ }, {
+ aggregation: 'weekly',
+ name: 'event_without_expiry'
+ }
+ ]
+ end
+
+ describe "#up" do
+ it 'rename keys', :aggregate_failures do
+ allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:known_events)
+ .and_return(known_events)
+
+ expiry_daily = Gitlab::UsageDataCounters::HLLRedisCounter::DEFAULT_DAILY_KEY_EXPIRY_LENGTH
+ expiry_weekly = Gitlab::UsageDataCounters::HLLRedisCounter::DEFAULT_WEEKLY_KEY_EXPIRY_LENGTH
+
+ default_slot = Gitlab::UsageDataCounters::HLLRedisCounter::REDIS_SLOT
+
+ old_slot_a = "#{date}-users_viewing_{analytics}_group_devops_adoption"
+ old_slot_b = "{wiki_action}-#{week}"
+ old_slot_without_expiry = "{event_without_expiry}-#{week}"
+
+ new_slot_a = "#{date}-{#{default_slot}}_users_viewing_analytics_group_devops_adoption"
+ new_slot_b = "{#{default_slot}}_wiki_action-#{week}"
+ new_slot_without_expiry = "{#{default_slot}}_event_without_expiry-#{week}"
+
+ Gitlab::Redis::HLL.add(key: old_slot_a, value: 1, expiry: expiry_daily)
+ Gitlab::Redis::HLL.add(key: old_slot_b, value: 1, expiry: expiry_weekly)
+ Gitlab::Redis::HLL.add(key: old_slot_a, value: 2, expiry: expiry_daily)
+ Gitlab::Redis::HLL.add(key: old_slot_b, value: 2, expiry: expiry_weekly)
+ Gitlab::Redis::HLL.add(key: old_slot_b, value: 2, expiry: expiry_weekly)
+ Gitlab::Redis::SharedState.with { |redis| redis.pfadd(old_slot_without_expiry, 1) }
+
+ # check that we merge values during migration
+ # i.e. we dont drop keys created after code deploy but before the migration
+ Gitlab::Redis::HLL.add(key: new_slot_a, value: 3, expiry: expiry_daily)
+ Gitlab::Redis::HLL.add(key: new_slot_b, value: 3, expiry: expiry_weekly)
+ Gitlab::Redis::HLL.add(key: new_slot_without_expiry, value: 2, expiry: expiry_weekly)
+
+ migrate!
+
+ expect(Gitlab::Redis::HLL.count(keys: new_slot_a)).to eq(3)
+ expect(Gitlab::Redis::HLL.count(keys: new_slot_b)).to eq(3)
+ expect(Gitlab::Redis::HLL.count(keys: new_slot_without_expiry)).to eq(2)
+ expect(with_redis { |r| r.ttl(new_slot_a) }).to be_within(600).of(expiry_daily)
+ expect(with_redis { |r| r.ttl(new_slot_b) }).to be_within(600).of(expiry_weekly)
+ expect(with_redis { |r| r.ttl(new_slot_without_expiry) }).to be_within(600).of(expiry_weekly)
+ end
+
+ it 'runs without errors' do
+ expect { migrate! }.not_to raise_error
+ end
+ end
+
+ def with_redis(&block)
+ Gitlab::Redis::SharedState.with(&block)
+ end
+end
diff --git a/spec/migrations/20230303105806_queue_delete_orphaned_packages_dependencies_spec.rb b/spec/migrations/20230303105806_queue_delete_orphaned_packages_dependencies_spec.rb
new file mode 100644
index 00000000000..7fe90a08763
--- /dev/null
+++ b/spec/migrations/20230303105806_queue_delete_orphaned_packages_dependencies_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueDeleteOrphanedPackagesDependencies, feature_category: :package_registry do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :packages_dependencies,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230309071242_delete_security_policy_bot_users_spec.rb b/spec/migrations/20230309071242_delete_security_policy_bot_users_spec.rb
new file mode 100644
index 00000000000..4dd44cad158
--- /dev/null
+++ b/spec/migrations/20230309071242_delete_security_policy_bot_users_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DeleteSecurityPolicyBotUsers, feature_category: :security_policy_management do
+ let(:users) { table(:users) }
+
+ before do
+ users.create!(user_type: 10, projects_limit: 0, email: 'security_policy_bot@example.com')
+ users.create!(user_type: 1, projects_limit: 0, email: 'support_bot@example.com')
+ users.create!(projects_limit: 0, email: 'human@example.com')
+ end
+
+ describe '#up' do
+ it 'deletes security_policy_bot users' do
+ expect { migrate! }.to change { users.count }.by(-1)
+
+ expect(users.where(user_type: 10).count).to eq(0)
+ expect(users.where(user_type: 1).count).to eq(1)
+ expect(users.where(user_type: nil).count).to eq(1)
+ end
+ end
+end
diff --git a/spec/migrations/20230313142631_backfill_ml_candidates_package_id_spec.rb b/spec/migrations/20230313142631_backfill_ml_candidates_package_id_spec.rb
new file mode 100644
index 00000000000..57ddb0504ec
--- /dev/null
+++ b/spec/migrations/20230313142631_backfill_ml_candidates_package_id_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe BackfillMlCandidatesPackageId, feature_category: :mlops do
+ let(:migration) { described_class.new }
+
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:ml_experiments) { table(:ml_experiments) }
+ let(:ml_candidates) { table(:ml_candidates) }
+ let(:packages_packages) { table(:packages_packages) }
+
+ let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
+ let(:project) { projects.create!(project_namespace_id: namespace.id, namespace_id: namespace.id) }
+ let(:experiment) { ml_experiments.create!(project_id: project.id, iid: 1, name: 'experiment') }
+ let!(:candidate1) { ml_candidates.create!(experiment_id: experiment.id, iid: SecureRandom.uuid) }
+ let!(:candidate2) { ml_candidates.create!(experiment_id: experiment.id, iid: SecureRandom.uuid) }
+ let!(:package1) do
+ packages_packages.create!(
+ project_id: project.id,
+ name: "ml_candidate_#{candidate1.id}",
+ version: "-",
+ package_type: 7
+ )
+ end
+
+ let!(:package2) do
+ packages_packages.create!(
+ project_id: project.id,
+ name: "ml_candidate_1000",
+ version: "-",
+ package_type: 7)
+ end
+
+ let!(:package3) do
+ packages_packages.create!(
+ project_id: project.id,
+ name: "ml_candidate_abcde",
+ version: "-",
+ package_type: 7
+ )
+ end
+
+ describe '#up' do
+ it 'sets the correct package_ids with idempotency', :aggregate_failures do
+ migration.up
+
+ expect(candidate1.reload.package_id).to be(package1.id)
+ expect(candidate2.reload.package_id).to be(nil)
+
+ migration.down
+ migration.up
+
+ expect(candidate1.reload.package_id).to be(package1.id)
+ expect(candidate2.reload.package_id).to be(nil)
+ end
+ end
+end
diff --git a/spec/migrations/20230313150531_reschedule_migration_for_remediation_spec.rb b/spec/migrations/20230313150531_reschedule_migration_for_remediation_spec.rb
new file mode 100644
index 00000000000..00f0836285b
--- /dev/null
+++ b/spec/migrations/20230313150531_reschedule_migration_for_remediation_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RescheduleMigrationForRemediation, :migration, feature_category: :vulnerability_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: :vulnerability_occurrences,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ end
+ end
+
+ 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/20230314144640_reschedule_migration_for_links_spec.rb b/spec/migrations/20230314144640_reschedule_migration_for_links_spec.rb
new file mode 100644
index 00000000000..b28b1ea0730
--- /dev/null
+++ b/spec/migrations/20230314144640_reschedule_migration_for_links_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RescheduleMigrationForLinks, :migration, feature_category: :vulnerability_management do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules a batched background migration' do
+ migrate!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ 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/20230317004428_migrate_daily_redis_hll_events_to_weekly_aggregation_spec.rb b/spec/migrations/20230317004428_migrate_daily_redis_hll_events_to_weekly_aggregation_spec.rb
new file mode 100644
index 00000000000..86787273fbc
--- /dev/null
+++ b/spec/migrations/20230317004428_migrate_daily_redis_hll_events_to_weekly_aggregation_spec.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe MigrateDailyRedisHllEventsToWeeklyAggregation, :migration, :clean_gitlab_redis_cache, feature_category: :service_ping do
+ it 'calls HLLRedisCounter.known_events to get list of events' do
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:known_events).and_call_original.at_least(1).time
+
+ migrate!
+ end
+
+ describe '#redis_key' do
+ let(:date) { Date.today }
+
+ context 'with daily aggregation' do
+ let(:date_formatted) { date.strftime('%G-%j') }
+ let(:event) { { aggregation: 'daily', name: 'wiki_action' } }
+
+ it 'returns correct key' do
+ existing_key = "#{date_formatted}-{hll_counters}_wiki_action"
+
+ expect(described_class.new.redis_key(event, date, event[:aggregation])).to eq(existing_key)
+ end
+ end
+
+ context 'with weekly aggregation' do
+ let(:event) { { aggregation: 'weekly', name: 'wiki_action' } }
+
+ it 'returns correct key' do
+ existing_key = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, event, date)
+
+ expect(described_class.new.redis_key(event, date, event[:aggregation])).to eq(existing_key)
+ end
+ end
+ end
+
+ context 'with weekly events' do
+ let(:events) { [{ aggregation: 'weekly', name: 'wiki_action' }] }
+
+ before do
+ allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:known_events).and_return(events)
+ end
+
+ it 'does not migrate weekly events' do
+ Gitlab::Redis::SharedState.with do |redis|
+ expect(redis).not_to receive(:pfmerge)
+ expect(redis).not_to receive(:expire)
+ end
+
+ migrate!
+ end
+ end
+
+ context 'with daily events' do
+ let(:daily_expiry) { Gitlab::UsageDataCounters::HLLRedisCounter::DEFAULT_DAILY_KEY_EXPIRY_LENGTH }
+ let(:weekly_expiry) { Gitlab::UsageDataCounters::HLLRedisCounter::DEFAULT_WEEKLY_KEY_EXPIRY_LENGTH }
+
+ it 'doesnt override events from migrated keys (code deployed before migration)' do
+ events = [{ aggregation: 'daily', name: 'users_viewing_analytics' },
+ { aggregation: 'weekly', name: 'users_viewing_analytics' }]
+ allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:known_events).and_return(events)
+
+ day = (Date.today - 1.week).beginning_of_week
+ daily_event = events.first
+ key_daily1 = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, daily_event, day)
+ Gitlab::Redis::HLL.add(key: key_daily1, value: 1, expiry: daily_expiry)
+ key_daily2 = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, daily_event, day + 2.days)
+ Gitlab::Redis::HLL.add(key: key_daily2, value: 2, expiry: daily_expiry)
+ key_daily3 = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, daily_event, day + 5.days)
+ Gitlab::Redis::HLL.add(key: key_daily3, value: 3, expiry: daily_expiry)
+
+ # the same event but with weekly aggregation and pre-Redis migration
+ weekly_event = events.second
+ key_weekly = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, weekly_event, day + 5.days)
+ Gitlab::Redis::HLL.add(key: key_weekly, value: 3, expiry: weekly_expiry)
+
+ migrate!
+
+ expect(Gitlab::Redis::HLL.count(keys: key_weekly)).to eq(3)
+ end
+
+ it 'migrates with correct parameters', :aggregate_failures do
+ events = [{ aggregation: 'daily', name: 'users_viewing_analytics_group_devops_adoption' }]
+ allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:known_events).and_return(events)
+
+ event = events.first.dup.tap { |e| e[:aggregation] = 'weekly' }
+ # For every day in the last 30 days, add a value to the daily key with daily expiry (including today)
+ 31.times do |i|
+ key = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, event, Date.today - i.days)
+ Gitlab::Redis::HLL.add(key: key, value: i, expiry: daily_expiry)
+ end
+
+ migrate!
+
+ new_key = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, event, Date.today)
+ # for the current week we should have value eq to the day of the week (ie. 1 for Monday, 2 for Tuesday, etc.)
+ first_week_days = Date.today.cwday
+ expect(Gitlab::Redis::HLL.count(keys: new_key)).to eq(first_week_days)
+ expect(with_redis { |r| r.ttl(new_key) }).to be_within(600).of(weekly_expiry)
+
+ full_weeks = (31 - first_week_days) / 7
+ # for the next full weeks we should have value eq to 7 (ie. 7 days in a week)
+ (1..full_weeks).each do |i|
+ new_key = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, event, Date.today - i.weeks)
+ expect(Gitlab::Redis::HLL.count(keys: new_key)).to eq(7)
+ expect(with_redis { |r| r.ttl(new_key) }).to be_within(600).of(weekly_expiry)
+ end
+
+ # for the last week we should have value eq to amount of rest of the days affected
+ last_week_days = 31 - ((full_weeks * 7) + first_week_days)
+ unless last_week_days.zero?
+ last_week = full_weeks + 1
+ new_key = Gitlab::UsageDataCounters::HLLRedisCounter.send(:redis_key, event, Date.today - last_week.weeks)
+ expect(Gitlab::Redis::HLL.count(keys: new_key)).to eq(last_week_days)
+ expect(with_redis { |r| r.ttl(new_key) }).to be_within(600).of(weekly_expiry)
+ end
+ end
+ end
+
+ def with_redis(&block)
+ Gitlab::Redis::SharedState.with(&block)
+ end
+end
diff --git a/spec/migrations/20230317162059_add_current_user_todos_work_item_widget_spec.rb b/spec/migrations/20230317162059_add_current_user_todos_work_item_widget_spec.rb
new file mode 100644
index 00000000000..1df80a519f2
--- /dev/null
+++ b/spec/migrations/20230317162059_add_current_user_todos_work_item_widget_spec.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddCurrentUserTodosWorkItemWidget, :migration, feature_category: :team_planning do
+ it_behaves_like 'migration that adds widget to work items definitions', widget_name: 'Current user todos'
+end
diff --git a/spec/migrations/20230321153035_add_package_id_created_at_desc_index_to_package_files_spec.rb b/spec/migrations/20230321153035_add_package_id_created_at_desc_index_to_package_files_spec.rb
new file mode 100644
index 00000000000..68f3b1f23a9
--- /dev/null
+++ b/spec/migrations/20230321153035_add_package_id_created_at_desc_index_to_package_files_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddPackageIdCreatedAtDescIndexToPackageFiles, feature_category: :package_registry do
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(ActiveRecord::Base.connection.indexes('packages_package_files').map(&:name))
+ .not_to include('index_packages_package_files_on_package_id_and_created_at_desc')
+ }
+
+ migration.after -> {
+ expect(ActiveRecord::Base.connection.indexes('packages_package_files').map(&:name))
+ .to include('index_packages_package_files_on_package_id_and_created_at_desc')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230321163947_backfill_ml_candidates_project_id_spec.rb b/spec/migrations/20230321163947_backfill_ml_candidates_project_id_spec.rb
new file mode 100644
index 00000000000..da76794a74c
--- /dev/null
+++ b/spec/migrations/20230321163947_backfill_ml_candidates_project_id_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe BackfillMlCandidatesProjectId, feature_category: :mlops do
+ let(:migration) { described_class.new }
+
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:ml_experiments) { table(:ml_experiments) }
+ let(:ml_candidates) { table(:ml_candidates) }
+
+ let(:namespace1) { namespaces.create!(name: 'foo', path: 'foo') }
+ let(:namespace2) { namespaces.create!(name: 'bar', path: 'bar') }
+ let(:project1) { projects.create!(project_namespace_id: namespace1.id, namespace_id: namespace1.id) }
+ let(:project2) { projects.create!(project_namespace_id: namespace2.id, namespace_id: namespace2.id) }
+ let(:experiment1) { ml_experiments.create!(project_id: project1.id, iid: 1, name: 'experiment') }
+ let(:experiment2) { ml_experiments.create!(project_id: project2.id, iid: 1, name: 'experiment') }
+ let!(:candidate1) do
+ ml_candidates.create!(experiment_id: experiment1.id, project_id: nil, eid: SecureRandom.uuid)
+ end
+
+ let!(:candidate2) do
+ ml_candidates.create!(experiment_id: experiment2.id, project_id: nil, eid: SecureRandom.uuid)
+ end
+
+ let!(:candidate3) do
+ ml_candidates.create!(experiment_id: experiment1.id, project_id: project1.id, eid: SecureRandom.uuid)
+ end
+
+ describe '#up' do
+ it 'sets the correct project_id with idempotency', :aggregate_failures do
+ migration.up
+
+ expect(candidate1.reload.project_id).to be(project1.id)
+ expect(candidate2.reload.project_id).to be(project2.id)
+ # in case we have candidates added between the column addition and the migration
+ expect(candidate3.reload.project_id).to be(project1.id)
+
+ migration.down
+ migration.up
+
+ expect(candidate1.reload.project_id).to be(project1.id)
+ expect(candidate2.reload.project_id).to be(project2.id)
+ expect(candidate3.reload.project_id).to be(project1.id)
+ end
+ end
+end
diff --git a/spec/migrations/20230321170823_backfill_ml_candidates_internal_id_spec.rb b/spec/migrations/20230321170823_backfill_ml_candidates_internal_id_spec.rb
new file mode 100644
index 00000000000..c8f7b19490a
--- /dev/null
+++ b/spec/migrations/20230321170823_backfill_ml_candidates_internal_id_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe BackfillMlCandidatesInternalId, feature_category: :mlops do
+ let(:migration) { described_class.new }
+
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:ml_experiments) { table(:ml_experiments) }
+ let(:ml_candidates) { table(:ml_candidates) }
+
+ let(:namespace1) { namespaces.create!(name: 'foo', path: 'foo') }
+ let(:namespace2) { namespaces.create!(name: 'bar', path: 'bar') }
+ let(:project1) { projects.create!(project_namespace_id: namespace1.id, namespace_id: namespace1.id) }
+ let(:project2) { projects.create!(project_namespace_id: namespace2.id, namespace_id: namespace2.id) }
+ let(:experiment1) { ml_experiments.create!(project_id: project1.id, iid: 1, name: 'experiment1') }
+ let(:experiment2) { ml_experiments.create!(project_id: project1.id, iid: 2, name: 'experiment2') }
+ let(:experiment3) { ml_experiments.create!(project_id: project2.id, iid: 1, name: 'experiment3') }
+
+ let!(:candidate1) do
+ ml_candidates.create!(experiment_id: experiment1.id, project_id: project1.id, eid: SecureRandom.uuid)
+ end
+
+ let!(:candidate2) do
+ ml_candidates.create!(experiment_id: experiment2.id, project_id: project1.id, eid: SecureRandom.uuid)
+ end
+
+ let!(:candidate3) do
+ ml_candidates.create!(experiment_id: experiment1.id, project_id: project1.id, eid: SecureRandom.uuid)
+ end
+
+ let!(:candidate4) do
+ ml_candidates.create!(experiment_id: experiment1.id, project_id: project1.id, internal_id: 1,
+ eid: SecureRandom.uuid)
+ end
+
+ let!(:candidate5) do
+ ml_candidates.create!(experiment_id: experiment3.id, project_id: project2.id, eid: SecureRandom.uuid)
+ end
+
+ describe '#up' do
+ it 'sets the correct project_id with idempotency', :aggregate_failures do
+ migration.up
+
+ expect(candidate4.reload.internal_id).to be(1) # candidate 4 already has an internal_id
+ expect(candidate1.reload.internal_id).to be(2)
+ expect(candidate2.reload.internal_id).to be(3)
+ expect(candidate3.reload.internal_id).to be(4)
+ expect(candidate5.reload.internal_id).to be(1) # candidate 5 is a different project
+
+ migration.down
+ migration.up
+
+ expect(candidate4.reload.internal_id).to be(1)
+ expect(candidate1.reload.internal_id).to be(2)
+ expect(candidate2.reload.internal_id).to be(3)
+ expect(candidate3.reload.internal_id).to be(4)
+ expect(candidate5.reload.internal_id).to be(1)
+ end
+ end
+end
diff --git a/spec/migrations/20230322085041_remove_user_namespace_records_from_vsa_aggregation_spec.rb b/spec/migrations/20230322085041_remove_user_namespace_records_from_vsa_aggregation_spec.rb
new file mode 100644
index 00000000000..e5f64ef2e70
--- /dev/null
+++ b/spec/migrations/20230322085041_remove_user_namespace_records_from_vsa_aggregation_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveUserNamespaceRecordsFromVsaAggregation,
+ migration: :gitlab_main,
+ feature_category: :value_stream_management do
+ let(:migration) { described_class::MIGRATION }
+ let!(:namespaces) { table(:namespaces) }
+ let!(:aggregations) { table(:analytics_cycle_analytics_aggregations) }
+
+ let!(:group) { namespaces.create!(name: 'aaa', path: 'aaa', type: 'Group') }
+ let!(:user_namespace) { namespaces.create!(name: 'ccc', path: 'ccc', type: 'User') }
+ let!(:project_namespace) { namespaces.create!(name: 'bbb', path: 'bbb', type: 'Project') }
+
+ let!(:group_aggregation) { aggregations.create!(group_id: group.id) }
+ let!(:user_namespace_aggregation) { aggregations.create!(group_id: user_namespace.id) }
+ let!(:project_namespace_aggregation) { aggregations.create!(group_id: project_namespace.id) }
+
+ describe '#up' do
+ it 'deletes the non-group namespace aggregation records' do
+ stub_const('RemoveUserNamespaceRecordsFromVsaAggregation::BATCH_SIZE', 1)
+
+ expect { migrate! }.to change {
+ aggregations.order(:group_id)
+ }.from([group_aggregation, user_namespace_aggregation,
+ project_namespace_aggregation]).to([group_aggregation])
+ end
+ end
+
+ describe '#down' do
+ it 'does nothing' do
+ migrate!
+
+ expect { schema_migrate_down! }.not_to change {
+ aggregations.order(:group_id).pluck(:group_id)
+ }.from([group_aggregation.id])
+ end
+ end
+end
diff --git a/spec/migrations/20230322145403_add_project_id_foreign_key_to_packages_npm_metadata_caches_spec.rb b/spec/migrations/20230322145403_add_project_id_foreign_key_to_packages_npm_metadata_caches_spec.rb
new file mode 100644
index 00000000000..647c583aa39
--- /dev/null
+++ b/spec/migrations/20230322145403_add_project_id_foreign_key_to_packages_npm_metadata_caches_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddProjectIdForeignKeyToPackagesNpmMetadataCaches,
+ feature_category: :package_registry do
+ let(:table) { described_class::SOURCE_TABLE }
+ let(:column) { described_class::COLUMN }
+ let(:foreign_key) { -> { described_class.new.foreign_keys_for(table, column).first } }
+
+ it 'creates and drops the foreign key' do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(foreign_key.call).to be(nil)
+ end
+
+ migration.after -> do
+ expect(foreign_key.call).to have_attributes(column: column.to_s)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230323101138_add_award_emoji_work_item_widget_spec.rb b/spec/migrations/20230323101138_add_award_emoji_work_item_widget_spec.rb
new file mode 100644
index 00000000000..16a205c5da5
--- /dev/null
+++ b/spec/migrations/20230323101138_add_award_emoji_work_item_widget_spec.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddAwardEmojiWorkItemWidget, :migration, feature_category: :team_planning do
+ it_behaves_like 'migration that adds widget to work items definitions', widget_name: 'Award emoji'
+end
diff --git a/spec/migrations/20230327103401_queue_migrate_human_user_type_spec.rb b/spec/migrations/20230327103401_queue_migrate_human_user_type_spec.rb
new file mode 100644
index 00000000000..e5852c93471
--- /dev/null
+++ b/spec/migrations/20230327103401_queue_migrate_human_user_type_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueMigrateHumanUserType, feature_category: :user_management do
+ let(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :users,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230327123333_backfill_product_analytics_data_collector_host_spec.rb b/spec/migrations/20230327123333_backfill_product_analytics_data_collector_host_spec.rb
new file mode 100644
index 00000000000..253512c9194
--- /dev/null
+++ b/spec/migrations/20230327123333_backfill_product_analytics_data_collector_host_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+require_migration!
+
+RSpec.describe BackfillProductAnalyticsDataCollectorHost, feature_category: :product_analytics do
+ let!(:application_settings) { table(:application_settings) }
+
+ describe '#up' do
+ before do
+ create_application_settings!(id: 1, jitsu_host: "https://configurator.testing.my-product-analytics.com",
+ product_analytics_data_collector_host: nil)
+ create_application_settings!(id: 2, jitsu_host: "https://config-urator_1.testing.my-product-analytics.com",
+ product_analytics_data_collector_host: nil)
+ create_application_settings!(id: 3, jitsu_host: "https://configurator.testing.my-product-analytics.com",
+ product_analytics_data_collector_host: "https://existingcollector.my-product-analytics.com")
+ create_application_settings!(id: 4, jitsu_host: nil, product_analytics_data_collector_host: nil)
+ migrate!
+ end
+
+ describe 'when jitsu host is present' do
+ it 'backfills missing product_analytics_data_collector_host' do
+ expect(application_settings.find(1).product_analytics_data_collector_host).to eq("https://collector.testing.my-product-analytics.com")
+ expect(application_settings.find(2).product_analytics_data_collector_host).to eq("https://collector.testing.my-product-analytics.com")
+ end
+
+ it 'does not modify existing product_analytics_data_collector_host' do
+ expect(application_settings.find(3).product_analytics_data_collector_host).to eq("https://existingcollector.my-product-analytics.com")
+ end
+ end
+
+ describe 'when jitsu host is not present' do
+ it 'does not backfill product_analytics_data_collector_host' do
+ expect(application_settings.find(4).product_analytics_data_collector_host).to be_nil
+ end
+ end
+ end
+
+ def create_application_settings!(id:, jitsu_host:, product_analytics_data_collector_host:)
+ params = {
+ id: id,
+ jitsu_host: jitsu_host,
+ product_analytics_data_collector_host: product_analytics_data_collector_host
+ }
+ application_settings.create!(params)
+ end
+end
diff --git a/spec/migrations/20230328030101_add_secureflag_training_provider_spec.rb b/spec/migrations/20230328030101_add_secureflag_training_provider_spec.rb
new file mode 100644
index 00000000000..774ea89937a
--- /dev/null
+++ b/spec/migrations/20230328030101_add_secureflag_training_provider_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddSecureflagTrainingProvider, :migration, feature_category: :vulnerability_management do
+ include MigrationHelpers::WorkItemTypesHelper
+
+ let!(:security_training_providers) { table(:security_training_providers) }
+
+ it 'adds additional provider' do
+ # Need to delete all as security training providers are seeded before entire test suite
+ security_training_providers.delete_all
+
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(security_training_providers.count).to eq(0)
+ }
+
+ migration.after -> {
+ expect(security_training_providers.count).to eq(1)
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230328100534_truncate_error_tracking_tables_spec.rb b/spec/migrations/20230328100534_truncate_error_tracking_tables_spec.rb
new file mode 100644
index 00000000000..efbbe22fd1b
--- /dev/null
+++ b/spec/migrations/20230328100534_truncate_error_tracking_tables_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe TruncateErrorTrackingTables, :migration, feature_category: :redis do
+ let(:migration) { described_class.new }
+
+ context 'when on GitLab.com' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ context 'when using Main db' do
+ it 'truncates the table' do
+ expect(described_class.connection).to receive(:execute).with('TRUNCATE table error_tracking_errors CASCADE')
+
+ migration.up
+ end
+ end
+
+ context 'when uses CI db', migration: :gitlab_ci do
+ before do
+ skip_if_multiple_databases_not_setup(:ci)
+ end
+
+ it 'does not truncate the table' do
+ expect(described_class.connection).not_to receive(:execute).with('TRUNCATE table error_tracking_errors CASCADE')
+
+ migration.up
+ end
+ end
+ end
+
+ context 'when on self-managed' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(false)
+ end
+
+ context 'when using Main db' do
+ it 'does not truncate the table' do
+ expect(described_class.connection).not_to receive(:execute).with('TRUNCATE table error_tracking_errors CASCADE')
+
+ migration.up
+ end
+ end
+
+ context 'when uses CI db', migration: :gitlab_ci do
+ it 'does not truncate the table' do
+ expect(described_class.connection).not_to receive(:execute).with('TRUNCATE table error_tracking_errors CASCADE')
+
+ migration.up
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230329100222_drop_software_licenses_temp_index_spec.rb b/spec/migrations/20230329100222_drop_software_licenses_temp_index_spec.rb
new file mode 100644
index 00000000000..d4d276980f8
--- /dev/null
+++ b/spec/migrations/20230329100222_drop_software_licenses_temp_index_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DropSoftwareLicensesTempIndex, feature_category: :security_policy_management do
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(ActiveRecord::Base.connection.indexes('software_licenses').map(&:name))
+ .to include(described_class::INDEX_NAME)
+ }
+
+ migration.after -> {
+ expect(ActiveRecord::Base.connection.indexes('software_licenses').map(&:name))
+ .not_to include(described_class::INDEX_NAME)
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230330103104_reschedule_migrate_evidences_spec.rb b/spec/migrations/20230330103104_reschedule_migrate_evidences_spec.rb
new file mode 100644
index 00000000000..8dc8cd68acb
--- /dev/null
+++ b/spec/migrations/20230330103104_reschedule_migrate_evidences_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RescheduleMigrateEvidences, :migration, feature_category: :vulnerability_management do
+ let(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'does not schedule a batched background migration' do
+ migrate!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ 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/20230403085957_add_tmp_partial_index_on_vulnerability_report_types2_spec.rb b/spec/migrations/20230403085957_add_tmp_partial_index_on_vulnerability_report_types2_spec.rb
new file mode 100644
index 00000000000..5203e772d15
--- /dev/null
+++ b/spec/migrations/20230403085957_add_tmp_partial_index_on_vulnerability_report_types2_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+require_migration!
+
+RSpec.describe AddTmpPartialIndexOnVulnerabilityReportTypes2, feature_category: :vulnerability_management do
+ let(:async_index) { Gitlab::Database::AsyncIndexes::PostgresAsyncIndex }
+ let(:index_name) { described_class::INDEX_NAME }
+
+ before do
+ allow_any_instance_of(ActiveRecord::ConnectionAdapters::SchemaStatements) # rubocop:disable RSpec/AnyInstanceOf
+ .to receive(:index_exists?)
+ .with("vulnerability_occurrences", :id, hash_including(name: index_name))
+ .and_return(index_exists)
+ end
+
+ context "with index absent" do
+ let(:index_exists) { false }
+
+ it "schedules the index" do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(async_index.where(name: index_name).count).to be(0)
+ end
+
+ migration.after -> do
+ expect(async_index.where(name: index_name).count).to be(1)
+ end
+ end
+ end
+ end
+
+ context "with index present" do
+ let(:index_exists) { true }
+
+ it "does not schedule the index" do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(async_index.where(name: index_name).count).to be(0)
+ end
+
+ migration.after -> do
+ expect(async_index.where(name: index_name).count).to be(0)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230405200858_requeue_backfill_project_wiki_repositories_spec.rb b/spec/migrations/20230405200858_requeue_backfill_project_wiki_repositories_spec.rb
new file mode 100644
index 00000000000..cf42818152f
--- /dev/null
+++ b/spec/migrations/20230405200858_requeue_backfill_project_wiki_repositories_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RequeueBackfillProjectWikiRepositories, feature_category: :geo_replication do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :projects,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230406121544_queue_backfill_design_management_repositories_spec.rb b/spec/migrations/20230406121544_queue_backfill_design_management_repositories_spec.rb
new file mode 100644
index 00000000000..39ef769fd11
--- /dev/null
+++ b/spec/migrations/20230406121544_queue_backfill_design_management_repositories_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillDesignManagementRepositories, feature_category: :geo_replication do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :projects,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230411153310_cleanup_bigint_conversion_for_sent_notifications_spec.rb b/spec/migrations/20230411153310_cleanup_bigint_conversion_for_sent_notifications_spec.rb
new file mode 100644
index 00000000000..5780aa365da
--- /dev/null
+++ b/spec/migrations/20230411153310_cleanup_bigint_conversion_for_sent_notifications_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('cleanup_bigint_conversion_for_sent_notifications')
+
+RSpec.describe CleanupBigintConversionForSentNotifications, feature_category: :database do
+ let(:sent_notifications) { table(:sent_notifications) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(sent_notifications.column_names).to include('id_convert_to_bigint')
+ }
+
+ migration.after -> {
+ sent_notifications.reset_column_information
+ expect(sent_notifications.column_names).not_to include('id_convert_to_bigint')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230412141541_reschedule_links_avoiding_duplication_spec.rb b/spec/migrations/20230412141541_reschedule_links_avoiding_duplication_spec.rb
new file mode 100644
index 00000000000..06eccf03ca4
--- /dev/null
+++ b/spec/migrations/20230412141541_reschedule_links_avoiding_duplication_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RescheduleLinksAvoidingDuplication, :migration, feature_category: :vulnerability_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: :vulnerability_occurrences,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ end
+ end
+
+ 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/20230412185837_queue_populate_vulnerability_dismissal_fields_spec.rb b/spec/migrations/20230412185837_queue_populate_vulnerability_dismissal_fields_spec.rb
new file mode 100644
index 00000000000..d39936abb90
--- /dev/null
+++ b/spec/migrations/20230412185837_queue_populate_vulnerability_dismissal_fields_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueuePopulateVulnerabilityDismissalFields, feature_category: :vulnerability_management do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ 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: :vulnerabilities,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+ end
+
+ describe '#down' do
+ it 'deletes all batched migration records' do
+ migrate!
+ schema_migrate_down!
+
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/20230412214119_finalize_encrypt_ci_trigger_token_spec.rb b/spec/migrations/20230412214119_finalize_encrypt_ci_trigger_token_spec.rb
new file mode 100644
index 00000000000..c30cafc915d
--- /dev/null
+++ b/spec/migrations/20230412214119_finalize_encrypt_ci_trigger_token_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe FinalizeEncryptCiTriggerToken, migration: :gitlab_ci, feature_category: :continuous_integration do
+ let(:batched_migrations) { table(:batched_background_migrations) }
+ let(:batch_failed_status) { 2 }
+ let(:batch_finalized_status) { 3 }
+
+ let!(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
+ it 'warns migration not found' do
+ expect(Gitlab::AppLogger)
+ .to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
+
+ migrate!
+ end
+ end
+
+ context 'with migration present' do
+ let!(:migration_record) do
+ batched_migrations.create!(
+ job_class_name: migration,
+ table_name: :ci_triggers,
+ column_name: :id,
+ job_arguments: [],
+ interval: 2.minutes,
+ min_value: 1,
+ max_value: 2,
+ batch_size: 1000,
+ sub_batch_size: 100,
+ max_batch_size: 2000,
+ gitlab_schema: :gitlab_ci,
+ status: batch_finalized_status
+ )
+ 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', :redis do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:status, :description) do
+ 0 | 'paused'
+ 1 | 'active'
+ 4 | 'failed'
+ 5 | 'finalizing'
+ end
+
+ with_them do
+ let!(:failed_job) do
+ table(:batched_background_migration_jobs).create!(
+ batched_background_migration_id: migration_record.id,
+ status: batch_failed_status,
+ min_value: 1,
+ max_value: 10,
+ attempts: 2,
+ batch_size: 100,
+ sub_batch_size: 10
+ )
+ end
+
+ before do
+ migration_record.update!(status: status)
+ end
+
+ it 'finalizes the migration' do
+ expect do
+ migrate!
+
+ migration_record.reload
+ failed_job.reload
+ end.to(
+ change { migration_record.status }.from(status).to(batch_finalized_status)
+ .and(
+ change { failed_job.status }.from(batch_failed_status).to(batch_finalized_status)
+ )
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230418215853_add_assignee_widget_to_incidents_spec.rb b/spec/migrations/20230418215853_add_assignee_widget_to_incidents_spec.rb
new file mode 100644
index 00000000000..d809d0e6a54
--- /dev/null
+++ b/spec/migrations/20230418215853_add_assignee_widget_to_incidents_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddAssigneeWidgetToIncidents, :migration, feature_category: :team_planning do
+ let(:migration) { described_class.new }
+ let(:work_item_definitions) { table(:work_item_widget_definitions) }
+ let(:work_item_types) { table(:work_item_types) }
+
+ let(:widget_name) { 'Assignees' }
+ let(:work_item_type) { 'Incident' }
+
+ describe '#up' do
+ it 'creates widget definition' do
+ type = work_item_types.find_by_name_and_namespace_id(work_item_type, nil)
+ work_item_definitions.where(work_item_type_id: type, name: widget_name).delete_all if type
+
+ expect { migrate! }.to change { work_item_definitions.count }.by(1)
+
+ type = work_item_types.find_by_name_and_namespace_id(work_item_type, nil)
+
+ expect(work_item_definitions.where(work_item_type_id: type, name: widget_name).count).to eq 1
+ end
+
+ it 'logs a warning if the type is missing' do
+ allow(described_class::WorkItemType).to receive(:find_by_name_and_namespace_id).and_call_original
+ allow(described_class::WorkItemType).to receive(:find_by_name_and_namespace_id)
+ .with(work_item_type, nil).and_return(nil)
+
+ expect(Gitlab::AppLogger).to receive(:warn).with(AddAssigneeWidgetToIncidents::FAILURE_MSG)
+ migrate!
+ end
+ end
+
+ describe '#down' do
+ it 'removes definitions for widget' do
+ migrate!
+
+ expect { migration.down }.to change { work_item_definitions.count }.by(-1)
+
+ type = work_item_types.find_by_name_and_namespace_id(work_item_type, nil)
+
+ expect(work_item_definitions.where(work_item_type_id: type, name: widget_name).count).to eq 0
+ end
+ end
+end
diff --git a/spec/migrations/20230419105225_remove_phabricator_from_application_settings_spec.rb b/spec/migrations/20230419105225_remove_phabricator_from_application_settings_spec.rb
new file mode 100644
index 00000000000..df84c8efd05
--- /dev/null
+++ b/spec/migrations/20230419105225_remove_phabricator_from_application_settings_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemovePhabricatorFromApplicationSettings, feature_category: :importers do
+ let(:settings) { table(:application_settings) }
+ let(:import_sources_with_phabricator) { %w[phabricator github git bitbucket bitbucket_server] }
+ let(:import_sources_without_phabricator) { %w[github git bitbucket bitbucket_server] }
+
+ describe "#up" do
+ it 'removes phabricator and preserves existing valid import sources' do
+ record = settings.create!(import_sources: import_sources_with_phabricator)
+
+ migrate!
+
+ expect(record.reload.import_sources).to start_with('---')
+
+ expect(ApplicationSetting.last.import_sources).to eq(import_sources_without_phabricator)
+ end
+ end
+end
diff --git a/spec/migrations/20230426102200_fix_import_sources_on_application_settings_after_phabricator_removal_spec.rb b/spec/migrations/20230426102200_fix_import_sources_on_application_settings_after_phabricator_removal_spec.rb
new file mode 100644
index 00000000000..aa5ec462871
--- /dev/null
+++ b/spec/migrations/20230426102200_fix_import_sources_on_application_settings_after_phabricator_removal_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FixImportSourcesOnApplicationSettingsAfterPhabricatorRemoval, feature_category: :importers do
+ let(:settings) { table(:application_settings) }
+ let(:import_sources) { %w[github git bitbucket bitbucket_server] }
+
+ describe "#up" do
+ shared_examples 'fixes import_sources on application_settings' do
+ it 'ensures YAML is stored' do
+ record = settings.create!(import_sources: data)
+
+ migrate!
+
+ expect(record.reload.import_sources).to start_with('---')
+ expect(ApplicationSetting.last.import_sources).to eq(import_sources)
+ end
+ end
+
+ context 'when import_sources is a String' do
+ let(:data) { import_sources.to_s }
+
+ it_behaves_like 'fixes import_sources on application_settings'
+ end
+
+ context 'when import_sources is already YAML' do
+ let(:data) { import_sources.to_yaml }
+
+ it_behaves_like 'fixes import_sources on application_settings'
+ end
+ end
+end
diff --git a/spec/migrations/20230428085332_remove_shimo_zentao_integration_records_spec.rb b/spec/migrations/20230428085332_remove_shimo_zentao_integration_records_spec.rb
new file mode 100644
index 00000000000..1d2fbb6b95d
--- /dev/null
+++ b/spec/migrations/20230428085332_remove_shimo_zentao_integration_records_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveShimoZentaoIntegrationRecords, feature_category: :integrations do
+ let(:integrations) { table(:integrations) }
+ let(:zentao_tracker_data) { table(:zentao_tracker_data) }
+
+ before do
+ integrations.create!(id: 1, type_new: 'Integrations::MockMonitoring')
+ integrations.create!(id: 2, type_new: 'Integrations::Redmine')
+ integrations.create!(id: 3, type_new: 'Integrations::Confluence')
+
+ integrations.create!(id: 4, type_new: 'Integrations::Shimo')
+ integrations.create!(id: 5, type_new: 'Integrations::Zentao')
+ integrations.create!(id: 6, type_new: 'Integrations::Zentao')
+ zentao_tracker_data.create!(id: 1, integration_id: 5)
+ zentao_tracker_data.create!(id: 2, integration_id: 6)
+ end
+
+ context 'with CE/EE env' do
+ it 'destroys all shimo and zentao integrations' do
+ migrate!
+
+ expect(integrations.count).to eq(3) # keep other integrations
+ expect(integrations.where(type_new: described_class::TYPES).count).to eq(0)
+ expect(zentao_tracker_data.count).to eq(0)
+ end
+ end
+
+ context 'with JiHu env' do
+ before do
+ allow(Gitlab).to receive(:jh?).and_return(true)
+ end
+
+ it 'keeps shimo and zentao integrations' do
+ migrate!
+
+ expect(integrations.count).to eq(6)
+ expect(integrations.where(type_new: described_class::TYPES).count).to eq(3)
+ expect(zentao_tracker_data.count).to eq(2)
+ end
+ end
+end
diff --git a/spec/migrations/20230502102832_schedule_index_to_members_on_source_and_type_and_access_level_spec.rb b/spec/migrations/20230502102832_schedule_index_to_members_on_source_and_type_and_access_level_spec.rb
new file mode 100644
index 00000000000..34d69642802
--- /dev/null
+++ b/spec/migrations/20230502102832_schedule_index_to_members_on_source_and_type_and_access_level_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+require_migration!
+
+RSpec.describe ScheduleIndexToMembersOnSourceAndTypeAndAccessLevel, feature_category: :security_policy_management do
+ let(:async_index) { Gitlab::Database::AsyncIndexes::PostgresAsyncIndex }
+ let(:index_name) { described_class::INDEX_NAME }
+
+ it "schedules the index" do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(async_index.where(name: index_name).count).to be(0)
+ end
+
+ migration.after -> do
+ expect(async_index.where(name: index_name).count).to be(1)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230502120021_schedule_index_to_project_authorizations_on_project_user_access_level_spec.rb b/spec/migrations/20230502120021_schedule_index_to_project_authorizations_on_project_user_access_level_spec.rb
new file mode 100644
index 00000000000..9759fa7862d
--- /dev/null
+++ b/spec/migrations/20230502120021_schedule_index_to_project_authorizations_on_project_user_access_level_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+require_migration!
+
+RSpec.describe ScheduleIndexToProjectAuthorizationsOnProjectUserAccessLevel, feature_category: :security_policy_management do
+ let(:async_index) { Gitlab::Database::AsyncIndexes::PostgresAsyncIndex }
+ let(:index_name) { described_class::INDEX_NAME }
+
+ it "schedules the index" do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(async_index.where(name: index_name).count).to be(0)
+ end
+
+ migration.after -> do
+ expect(async_index.where(name: index_name).count).to be(1)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230504084524_remove_gitlab_import_source_spec.rb b/spec/migrations/20230504084524_remove_gitlab_import_source_spec.rb
new file mode 100644
index 00000000000..b2442359e87
--- /dev/null
+++ b/spec/migrations/20230504084524_remove_gitlab_import_source_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveGitlabImportSource, feature_category: :importers do
+ let(:settings) { table(:application_settings) }
+ let(:import_sources_with_gitlab) { %w[github git gitlab bitbucket bitbucket_server] }
+ let(:import_sources_without_gitlab) { %w[github git bitbucket bitbucket_server] }
+
+ describe "#up" do
+ it 'removes gitlab and preserves existing valid import sources' do
+ record = settings.create!(import_sources: import_sources_with_gitlab)
+
+ migrate!
+
+ expect(record.reload.import_sources).to start_with('---')
+
+ expect(ApplicationSetting.last.import_sources).to eq(import_sources_without_gitlab)
+ end
+ end
+end
diff --git a/spec/migrations/20230508150219_reschedule_evidences_handling_unicode_spec.rb b/spec/migrations/20230508150219_reschedule_evidences_handling_unicode_spec.rb
new file mode 100644
index 00000000000..9ba44984372
--- /dev/null
+++ b/spec/migrations/20230508150219_reschedule_evidences_handling_unicode_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RescheduleEvidencesHandlingUnicode, :migration, feature_category: :vulnerability_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: :vulnerability_occurrences,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ end
+ end
+
+ 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/20230508175057_backfill_corrected_secure_files_expirations_spec.rb b/spec/migrations/20230508175057_backfill_corrected_secure_files_expirations_spec.rb
new file mode 100644
index 00000000000..570be0e02c7
--- /dev/null
+++ b/spec/migrations/20230508175057_backfill_corrected_secure_files_expirations_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe BackfillCorrectedSecureFilesExpirations, migration: :gitlab_ci, feature_category: :mobile_devops do
+ let(:migration) { described_class.new }
+ let(:ci_secure_files) { table(:ci_secure_files) }
+
+ let!(:file1) { ci_secure_files.create!(project_id: 1, name: "file.cer", file: "foo", checksum: 'bar') }
+ let!(:file2) { ci_secure_files.create!(project_id: 1, name: "file.p12", file: "foo", checksum: 'bar') }
+ let!(:file3) { ci_secure_files.create!(project_id: 1, name: "file.jks", file: "foo", checksum: 'bar') }
+
+ describe '#up' do
+ it 'enqueues the ParseSecureFileMetadataWorker job for relevant file types', :aggregate_failures do
+ expect(::Ci::ParseSecureFileMetadataWorker).to receive(:perform_async).with(file1.id)
+ expect(::Ci::ParseSecureFileMetadataWorker).to receive(:perform_async).with(file2.id)
+ expect(::Ci::ParseSecureFileMetadataWorker).not_to receive(:perform_async).with(file3.id)
+
+ migration.up
+ end
+ end
+end
diff --git a/spec/migrations/20230509131736_add_default_organization_spec.rb b/spec/migrations/20230509131736_add_default_organization_spec.rb
new file mode 100644
index 00000000000..539216c57ee
--- /dev/null
+++ b/spec/migrations/20230509131736_add_default_organization_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddDefaultOrganization, feature_category: :cell do
+ let(:organization) { table(:organizations) }
+
+ it "correctly migrates up and down" do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(organization.where(id: 1, name: 'Default')).to be_empty
+ }
+ migration.after -> {
+ expect(organization.where(id: 1, name: 'Default')).not_to be_empty
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20230510062502_queue_cleanup_personal_access_tokens_with_nil_expires_at_spec.rb b/spec/migrations/20230510062502_queue_cleanup_personal_access_tokens_with_nil_expires_at_spec.rb
new file mode 100644
index 00000000000..45ef85a49cf
--- /dev/null
+++ b/spec/migrations/20230510062502_queue_cleanup_personal_access_tokens_with_nil_expires_at_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueCleanupPersonalAccessTokensWithNilExpiresAt, feature_category: :system_access do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :personal_access_tokens,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/add_open_source_plan_spec.rb b/spec/migrations/add_open_source_plan_spec.rb
deleted file mode 100644
index f5d68f455e6..00000000000
--- a/spec/migrations/add_open_source_plan_spec.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe AddOpenSourcePlan, :migration, feature_category: :purchase do
- describe '#up' do
- before do
- allow(Gitlab).to receive(:com?).and_return true
- end
-
- it 'creates 1 entry within the plans table' do
- expect { migrate! }.to change { AddOpenSourcePlan::Plan.count }.by 1
- expect(AddOpenSourcePlan::Plan.last.name).to eql('opensource')
- end
-
- it 'creates 1 entry for plan limits' do
- expect { migrate! }.to change { AddOpenSourcePlan::PlanLimits.count }.by 1
- end
-
- context 'when the plan limits for gold and silver exists' do
- before do
- table(:plans).create!(id: 1, name: 'ultimate', title: 'Ultimate')
- table(:plan_limits).create!(id: 1, plan_id: 1, storage_size_limit: 2000)
- end
-
- it 'duplicates the gold and silvers plan limits entries' do
- migrate!
-
- opensource_limits = AddOpenSourcePlan::Plan.find_by(name: 'opensource').limits
- expect(opensource_limits.storage_size_limit).to be 2000
- 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 { AddOpenSourcePlan::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 opensource entry' do
- migrate!
-
- expect { described_class.new.down }.to change { AddOpenSourcePlan::Plan.count }.by(-1)
- expect(AddOpenSourcePlan::Plan.find_by(name: 'opensource')).to be_nil
-
- other_plan = AddOpenSourcePlan::Plan.find_by(name: 'other')
- expect(other_plan).to be_persisted
- expect(AddOpenSourcePlan::PlanLimits.count).to eq(1)
- expect(AddOpenSourcePlan::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: 'opensource', title: 'Open Source Program')
- table(:plan_limits).create!(id: 1, plan_id: 1)
- end
-
- it 'does not delete plans and plan limits and returns' do
- migrate!
-
- expect { described_class.new.down }.not_to change { AddOpenSourcePlan::Plan.count }
- expect(AddOpenSourcePlan::PlanLimits.count).to eq(2)
- end
- end
- end
-end
diff --git a/spec/migrations/backfill_current_value_with_progress_work_item_progresses_spec.rb b/spec/migrations/backfill_current_value_with_progress_work_item_progresses_spec.rb
new file mode 100644
index 00000000000..632925b23b2
--- /dev/null
+++ b/spec/migrations/backfill_current_value_with_progress_work_item_progresses_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillCurrentValueWithProgressWorkItemProgresses, :migration, feature_category: :team_planning do
+ let(:namespaces) { table(:namespaces) }
+ let(:users) { table(:users) }
+ let(:projects) { table(:projects) }
+ let(:issues) { table(:issues) }
+ let(:progresses) { table(:work_item_progresses) }
+ let(:issue_base_type_enum_value) { 5 }
+ let(:issue_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_base_type_enum_value) }
+
+ let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
+ let(:user) { users.create!(name: 'test', email: 'test@example.com', projects_limit: 5) }
+ let(:project) do
+ projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id, name: 'Alpha Gamma',
+ path: 'alpha-gamma')
+ end
+
+ let(:work_item1) do
+ issues.create!(
+ id: 1, project_id: project.id, namespace_id: project.project_namespace_id,
+ title: 'issue1', author_id: user.id, work_item_type_id: issue_type.id
+ )
+ end
+
+ let(:work_item2) do
+ issues.create!(
+ id: 2, project_id: project.id, namespace_id: project.project_namespace_id,
+ title: 'issue2', author_id: user.id, work_item_type_id: issue_type.id
+ )
+ end
+
+ let(:progress1) { progresses.create!(issue_id: work_item1.id, progress: 10) }
+ let(:progress2) { progresses.create!(issue_id: work_item2.id, progress: 60) }
+
+ describe '#up' do
+ it 'back fills current_value from progress columns' do
+ expect { migrate! }
+ .to change { progress1.reload.current_value }.from(0).to(10)
+ .and change { progress2.reload.current_value }.from(0).to(60)
+ .and not_change(progress1, :progress)
+ .and not_change(progress2, :progress)
+ end
+ end
+end
diff --git a/spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb b/spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb
index 5029a861d31..83b47da3065 100644
--- a/spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb
+++ b/spec/migrations/backfill_integrations_enable_ssl_verification_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe BackfillIntegrationsEnableSslVerification, feature_category: :authentication_and_authorization do
+RSpec.describe BackfillIntegrationsEnableSslVerification, feature_category: :system_access do
let!(:migration) { described_class::MIGRATION }
let!(:integrations) { described_class::Integration }
diff --git a/spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb b/spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb
index e85489198ee..71ffdd66d62 100644
--- a/spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb
+++ b/spec/migrations/bulk_insert_cluster_enabled_grants_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require_migration!
-RSpec.describe BulkInsertClusterEnabledGrants, :migration, feature_category: :kubernetes_management do
+RSpec.describe BulkInsertClusterEnabledGrants, :migration, feature_category: :deployment_management do
let(:migration) { described_class.new }
let(:cluster_enabled_grants) { table(:cluster_enabled_grants) }
diff --git a/spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb b/spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb
index 7aaa90ee985..01c85f85e0b 100644
--- a/spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb
+++ b/spec/migrations/cleanup_backfill_integrations_enable_ssl_verification_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe CleanupBackfillIntegrationsEnableSslVerification, :migration,
-feature_category: :authentication_and_authorization do
+ feature_category: :system_access do
let(:job_class_name) { 'BackfillIntegrationsEnableSslVerification' }
before do
diff --git a/spec/migrations/cleanup_vulnerability_state_transitions_with_same_from_state_to_state_spec.rb b/spec/migrations/cleanup_vulnerability_state_transitions_with_same_from_state_to_state_spec.rb
index b808f03428d..b270f2b100f 100644
--- a/spec/migrations/cleanup_vulnerability_state_transitions_with_same_from_state_to_state_spec.rb
+++ b/spec/migrations/cleanup_vulnerability_state_transitions_with_same_from_state_to_state_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe CleanupVulnerabilityStateTransitionsWithSameFromStateToState, :migration,
-feature_category: :vulnerability_management do
+ feature_category: :vulnerability_management do
let!(:namespace) { table(:namespaces).create!(name: 'namespace', type: 'Group', path: 'namespace') }
let!(:user) { table(:users).create!(email: 'author@example.com', username: 'author', projects_limit: 10) }
let!(:project) do
diff --git a/spec/migrations/delete_migrate_shared_vulnerability_scanners_spec.rb b/spec/migrations/delete_migrate_shared_vulnerability_scanners_spec.rb
index 562b1e25db4..8a0c0250cdf 100644
--- a/spec/migrations/delete_migrate_shared_vulnerability_scanners_spec.rb
+++ b/spec/migrations/delete_migrate_shared_vulnerability_scanners_spec.rb
@@ -9,37 +9,41 @@ RSpec.describe DeleteMigrateSharedVulnerabilityScanners, :migration, feature_cat
let(:batched_background_migration_jobs) { table(:batched_background_migration_jobs) }
let(:migration) do
- batched_background_migrations.create!(created_at: Time.zone.now,
- updated_at: Time.zone.now,
- min_value: 1,
- max_value: 1,
- batch_size: described_class::BATCH_SIZE,
- sub_batch_size: 100,
- interval: 300,
- status: 3,
- job_class_name: described_class::MIGRATION,
- batch_class_name: "PrimaryKeyBatchingStrategy",
- table_name: described_class::TABLE_NAME,
- column_name: described_class::BATCH_COLUMN,
- job_arguments: [],
- pause_ms: 100,
- max_batch_size: 1000,
- gitlab_schema: "gitlab_main")
+ batched_background_migrations.create!(
+ created_at: Time.zone.now,
+ updated_at: Time.zone.now,
+ min_value: 1,
+ max_value: 1,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: 100,
+ interval: 300,
+ status: 3,
+ job_class_name: described_class::MIGRATION,
+ batch_class_name: "PrimaryKeyBatchingStrategy",
+ table_name: described_class::TABLE_NAME,
+ column_name: described_class::BATCH_COLUMN,
+ job_arguments: [],
+ pause_ms: 100,
+ max_batch_size: 1000,
+ gitlab_schema: "gitlab_main"
+ )
end
let(:jobs) do
Array.new(10) do
- batched_background_migration_jobs.create!(batched_background_migration_id: migration.id,
- created_at: Time.zone.now,
- updated_at: Time.zone.now,
- min_value: 1,
- max_value: 1,
- batch_size: 1,
- sub_batch_size: 1,
- status: 0,
- attempts: 0,
- metrics: {},
- pause_ms: 100)
+ batched_background_migration_jobs.create!(
+ batched_background_migration_id: migration.id,
+ created_at: Time.zone.now,
+ updated_at: Time.zone.now,
+ min_value: 1,
+ max_value: 1,
+ batch_size: 1,
+ sub_batch_size: 1,
+ status: 0,
+ attempts: 0,
+ metrics: {},
+ pause_ms: 100
+ )
end
end
diff --git a/spec/migrations/disable_job_token_scope_when_unused_spec.rb b/spec/migrations/disable_job_token_scope_when_unused_spec.rb
deleted file mode 100644
index fddf3594e2b..00000000000
--- a/spec/migrations/disable_job_token_scope_when_unused_spec.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe DisableJobTokenScopeWhenUnused, feature_category: :continuous_integration do
- it 'is a no-op' do
- migrate!
- end
-end
diff --git a/spec/migrations/drop_packages_events_table_spec.rb b/spec/migrations/drop_packages_events_table_spec.rb
new file mode 100644
index 00000000000..539a3b88196
--- /dev/null
+++ b/spec/migrations/drop_packages_events_table_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+require_migration!
+
+RSpec.describe DropPackagesEventsTable, feature_category: :package_registry do
+ let(:table) { described_class::SOURCE_TABLE }
+ let(:column) { described_class::COLUMN }
+
+ subject { described_class.new }
+
+ it 'drops and creates the packages_events table' do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(subject.table_exists?(:packages_events)).to eq(true)
+ end
+
+ migration.after -> do
+ expect(subject.table_exists?(:packages_events)).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/ensure_award_emoji_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_award_emoji_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..826320ec6c2
--- /dev/null
+++ b/spec/migrations/ensure_award_emoji_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureAwardEmojiBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'award_emoji',
+ column_name: 'id',
+ job_arguments: [['awardable_id'], ['awardable_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_commit_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_commit_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..89e14650034
--- /dev/null
+++ b/spec/migrations/ensure_commit_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureCommitUserMentionsNoteIdBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'commit_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_design_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_design_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..ac763af1a70
--- /dev/null
+++ b/spec/migrations/ensure_design_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureDesignUserMentionsNoteIdBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'design_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_epic_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_epic_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..a6b2f751b3b
--- /dev/null
+++ b/spec/migrations/ensure_epic_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureEpicUserMentionsBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'epic_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_issue_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_issue_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..602dd87c593
--- /dev/null
+++ b/spec/migrations/ensure_issue_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureIssueUserMentionsBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'issue_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..118e0058922
--- /dev/null
+++ b/spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureMergeRequestMetricsIdBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'merge_request_metrics',
+ column_name: 'id',
+ job_arguments: [['id'], ['id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_self_hosts_spec.rb b/spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_self_hosts_spec.rb
new file mode 100644
index 00000000000..b946f816f3b
--- /dev/null
+++ b/spec/migrations/ensure_merge_request_metrics_id_bigint_backfill_is_finished_for_self_hosts_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureMergeRequestMetricsIdBigintBackfillIsFinishedForSelfHosts, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'merge_request_metrics',
+ column_name: 'id',
+ job_arguments: [['id'], ['id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..af9fc3f3b07
--- /dev/null
+++ b/spec/migrations/ensure_mr_user_mentions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureMrUserMentionsNoteIdBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'merge_request_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_note_diff_files_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_note_diff_files_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..acafc211e8c
--- /dev/null
+++ b/spec/migrations/ensure_note_diff_files_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureNoteDiffFilesBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'note_diff_files',
+ column_name: 'id',
+ job_arguments: [['diff_note_id'], ['diff_note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_notes_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_notes_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..2832be38f9d
--- /dev/null
+++ b/spec/migrations/ensure_notes_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureNotesBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'notes',
+ column_name: 'id',
+ job_arguments: [['id'], ['id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_snippet_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_snippet_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..b942a9a67a3
--- /dev/null
+++ b/spec/migrations/ensure_snippet_user_mentions_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureSnippetUserMentionsBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'snippet_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_suggestions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_suggestions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..f8dd700b160
--- /dev/null
+++ b/spec/migrations/ensure_suggestions_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureSuggestionsNoteIdBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'suggestions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_system_note_metadata_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_system_note_metadata_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..11e087b63e2
--- /dev/null
+++ b/spec/migrations/ensure_system_note_metadata_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureSystemNoteMetadataBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'system_note_metadata',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_timelogs_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_timelogs_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..9f733f1e1f4
--- /dev/null
+++ b/spec/migrations/ensure_timelogs_note_id_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureTimelogsNoteIdBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'timelogs',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_todos_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb b/spec/migrations/ensure_todos_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..2b9d319be08
--- /dev/null
+++ b/spec/migrations/ensure_todos_bigint_backfill_is_finished_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureTodosBigintBackfillIsFinishedForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'todos',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/ensure_unique_debian_packages_spec.rb b/spec/migrations/ensure_unique_debian_packages_spec.rb
new file mode 100644
index 00000000000..eaa87ebd45e
--- /dev/null
+++ b/spec/migrations/ensure_unique_debian_packages_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+require_migration! 'add_unique_packages_index_when_debian'
+require_migration! 'add_tmp_unique_packages_index_when_debian'
+
+RSpec.describe EnsureUniqueDebianPackages, feature_category: :package_registry do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:packages) { table(:packages_packages) }
+
+ let!(:group) { namespaces.create!(name: 'group', path: 'group_path') }
+ let!(:project_namespace1) { namespaces.create!(name: 'name1', path: 'path1') }
+ let!(:project_namespace2) { namespaces.create!(name: 'name2', path: 'path2') }
+
+ let!(:project1) { projects.create!(namespace_id: group.id, project_namespace_id: project_namespace1.id) }
+ let!(:project2) { projects.create!(namespace_id: group.id, project_namespace_id: project_namespace2.id) }
+
+ let!(:debian_package1_1) do
+ packages.create!(project_id: project1.id, package_type: 9, name: FFaker::Lorem.word, version: 'v1.0')
+ end
+
+ let(:debian_package1_2) do
+ packages.create!(project_id: project1.id, package_type: 9, name: debian_package1_1.name,
+ version: debian_package1_1.version)
+ end
+
+ let!(:pypi_package1_3) do
+ packages.create!(project_id: project1.id, package_type: 5, name: debian_package1_1.name,
+ version: debian_package1_1.version)
+ end
+
+ let!(:debian_package2_1) do
+ packages.create!(project_id: project2.id, package_type: 9, name: debian_package1_1.name,
+ version: debian_package1_1.version)
+ end
+
+ before do
+ # Remove unique indices
+ AddUniquePackagesIndexWhenDebian.new.down
+ AddTmpUniquePackagesIndexWhenDebian.new.down
+ # Then create the duplicate packages
+ debian_package1_2
+ end
+
+ it 'marks as pending destruction the duplicated packages', :aggregate_failures do
+ expect { migrate! }
+ .to change { packages.where(status: 0).count }.from(4).to(3)
+ .and not_change { packages.where(status: 1).count }
+ .and not_change { packages.where(status: 2).count }
+ .and not_change { packages.where(status: 3).count }
+ .and change { packages.where(status: 4).count }.from(0).to(1)
+ end
+end
diff --git a/spec/migrations/ensure_vum_bigint_backfill_is_finished_for_gl_dot_com_spec.rb b/spec/migrations/ensure_vum_bigint_backfill_is_finished_for_gl_dot_com_spec.rb
new file mode 100644
index 00000000000..d582a8a9460
--- /dev/null
+++ b/spec/migrations/ensure_vum_bigint_backfill_is_finished_for_gl_dot_com_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe EnsureVumBigintBackfillIsFinishedForGlDotCom, feature_category: :database do
+ describe '#up' do
+ let(:migration_arguments) do
+ {
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: 'vulnerability_user_mentions',
+ column_name: 'id',
+ job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
+ }
+ end
+
+ it 'ensures the migration is completed for GitLab.com, dev, or test' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ expect(instance).to receive(:ensure_batched_background_migration_is_finished).with(migration_arguments)
+ end
+
+ migrate!
+ end
+
+ it 'skips the check for other instances' do
+ expect_next_instance_of(described_class) do |instance|
+ expect(instance).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ expect(instance).not_to receive(:ensure_batched_background_migration_is_finished)
+ end
+
+ migrate!
+ end
+ end
+end
diff --git a/spec/migrations/finalize_invalid_member_cleanup_spec.rb b/spec/migrations/finalize_invalid_member_cleanup_spec.rb
index 29d03f8983c..c039edcc319 100644
--- a/spec/migrations/finalize_invalid_member_cleanup_spec.rb
+++ b/spec/migrations/finalize_invalid_member_cleanup_spec.rb
@@ -18,6 +18,10 @@ RSpec.describe FinalizeInvalidMemberCleanup, :migration, feature_category: :subg
end
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
diff --git a/spec/migrations/finalize_issues_iid_scoping_to_namespace_spec.rb b/spec/migrations/finalize_issues_iid_scoping_to_namespace_spec.rb
new file mode 100644
index 00000000000..1834e8c6e0e
--- /dev/null
+++ b/spec/migrations/finalize_issues_iid_scoping_to_namespace_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe FinalizeIssuesIidScopingToNamespace, :migration, feature_category: :team_planning do
+ let(:batched_migrations) { table(:batched_background_migrations) }
+
+ let!(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ shared_examples 'finalizes the migration' do
+ it 'finalizes the migration' do
+ allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
+ expect(runner).to receive(:finalize).with('"IssuesInternalIdScopeUpdater"', :internal_ids, :id, [nil, "up"])
+ end
+ end
+ end
+
+ context 'when migration is missing' do
+ it 'warns migration not found' do
+ expect(Gitlab::AppLogger)
+ .to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
+
+ migrate!
+ end
+ end
+
+ context 'with migration present' do
+ let!(:migration) do
+ batched_migrations.create!(
+ job_class_name: 'IssuesInternalIdScopeUpdater',
+ table_name: :internal_ids,
+ column_name: :id,
+ job_arguments: [nil, 'up'],
+ 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
+ migration.update!(status: status)
+ end
+
+ it_behaves_like 'finalizes the migration'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb b/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb
index d0c25fb3dd6..0800a049767 100644
--- a/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb
+++ b/spec/migrations/finalize_issues_namespace_id_backfilling_spec.rb
@@ -12,12 +12,16 @@ RSpec.describe FinalizeIssuesNamespaceIdBackfilling, :migration, feature_categor
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
- expect(runner).to receive(:finalize).with('BackfillProjectNamespaceOnIssues', :projects, :id, [])
+ expect(runner).to receive(:finalize).with(migration, :projects, :id, [])
end
end
end
context 'when routes backfilling migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -29,7 +33,7 @@ RSpec.describe FinalizeIssuesNamespaceIdBackfilling, :migration, feature_categor
context 'with backfilling migration present' do
let!(:project_namespace_backfill) do
batched_migrations.create!(
- job_class_name: 'BackfillProjectNamespaceOnIssues',
+ job_class_name: migration,
table_name: :routes,
column_name: :id,
job_arguments: [],
diff --git a/spec/migrations/finalize_orphaned_routes_cleanup_spec.rb b/spec/migrations/finalize_orphaned_routes_cleanup_spec.rb
index 78546806039..215fdbb05ad 100644
--- a/spec/migrations/finalize_orphaned_routes_cleanup_spec.rb
+++ b/spec/migrations/finalize_orphaned_routes_cleanup_spec.rb
@@ -12,12 +12,16 @@ RSpec.describe FinalizeOrphanedRoutesCleanup, :migration, feature_category: :pro
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
- expect(runner).to receive(:finalize).with('CleanupOrphanedRoutes', :projects, :id, [])
+ expect(runner).to receive(:finalize).with(migration, :projects, :id, [])
end
end
end
context 'when migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -29,7 +33,7 @@ RSpec.describe FinalizeOrphanedRoutesCleanup, :migration, feature_category: :pro
context 'with migration present' do
let!(:project_namespace_backfill) do
batched_migrations.create!(
- job_class_name: 'CleanupOrphanedRoutes',
+ job_class_name: migration,
table_name: :routes,
column_name: :id,
job_arguments: [],
diff --git a/spec/migrations/finalize_project_namespaces_backfill_spec.rb b/spec/migrations/finalize_project_namespaces_backfill_spec.rb
index 6cc3a694de8..880bb6661a4 100644
--- a/spec/migrations/finalize_project_namespaces_backfill_spec.rb
+++ b/spec/migrations/finalize_project_namespaces_backfill_spec.rb
@@ -12,12 +12,16 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration, feature_category:
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
- expect(runner).to receive(:finalize).with('"ProjectNamespaces::BackfillProjectNamespaces"', :projects, :id, [nil, "up"])
+ expect(runner).to receive(:finalize).with(migration, :projects, :id, [nil, "up"])
end
end
end
context 'when project namespace backfilling migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -29,7 +33,7 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration, feature_category:
context 'with backfilling migration present' do
let!(:project_namespace_backfill) do
batched_migrations.create!(
- job_class_name: 'ProjectNamespaces::BackfillProjectNamespaces',
+ job_class_name: migration,
table_name: :projects,
column_name: :id,
job_arguments: [nil, 'up'],
diff --git a/spec/migrations/finalize_routes_backfilling_for_projects_spec.rb b/spec/migrations/finalize_routes_backfilling_for_projects_spec.rb
index b79fdc98425..7618957d2f7 100644
--- a/spec/migrations/finalize_routes_backfilling_for_projects_spec.rb
+++ b/spec/migrations/finalize_routes_backfilling_for_projects_spec.rb
@@ -12,12 +12,16 @@ RSpec.describe FinalizeRoutesBackfillingForProjects, :migration, feature_categor
shared_examples 'finalizes the migration' do
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
- expect(runner).to receive(:finalize).with('BackfillNamespaceIdForProjectRoute', :projects, :id, [])
+ expect(runner).to receive(:finalize).with(migration, :projects, :id, [])
end
end
end
context 'when routes backfilling migration is missing' do
+ before do
+ batched_migrations.where(job_class_name: migration).delete_all
+ end
+
it 'warns migration not found' do
expect(Gitlab::AppLogger)
.to receive(:warn).with(/Could not find batched background migration for the given configuration:/)
@@ -29,7 +33,7 @@ RSpec.describe FinalizeRoutesBackfillingForProjects, :migration, feature_categor
context 'with backfilling migration present' do
let!(:project_namespace_backfill) do
batched_migrations.create!(
- job_class_name: 'BackfillNamespaceIdForProjectRoute',
+ job_class_name: migration,
table_name: :routes,
column_name: :id,
job_arguments: [],
diff --git a/spec/migrations/finalize_traversal_ids_background_migrations_spec.rb b/spec/migrations/finalize_traversal_ids_background_migrations_spec.rb
deleted file mode 100644
index 0cebe7b9f91..00000000000
--- a/spec/migrations/finalize_traversal_ids_background_migrations_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!('finalize_traversal_ids_background_migrations')
-
-RSpec.describe FinalizeTraversalIdsBackgroundMigrations, :migration, feature_category: :database do
- shared_context 'incomplete background migration' do
- before do
- # Jobs enqueued in Sidekiq.
- Sidekiq::Testing.disable! do
- BackgroundMigrationWorker.perform_in(10, job_class_name, [1, 2, 100])
- BackgroundMigrationWorker.perform_in(20, job_class_name, [3, 4, 100])
- end
-
- # Jobs tracked in the database.
- # table(:background_migration_jobs).create!(
- Gitlab::Database::BackgroundMigrationJob.create!(
- class_name: job_class_name,
- arguments: [5, 6, 100],
- status: Gitlab::Database::BackgroundMigrationJob.statuses['pending']
- )
- # table(:background_migration_jobs).create!(
- Gitlab::Database::BackgroundMigrationJob.create!(
- class_name: job_class_name,
- arguments: [7, 8, 100],
- status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded']
- )
- end
- end
-
- context 'BackfillNamespaceTraversalIdsRoots background migration' do
- let(:job_class_name) { 'BackfillNamespaceTraversalIdsRoots' }
-
- include_context 'incomplete background migration'
-
- before do
- migrate!
- end
-
- it_behaves_like(
- 'finalized tracked background migration',
- Gitlab::BackgroundMigration::BackfillNamespaceTraversalIdsRoots
- )
- end
-
- context 'BackfillNamespaceTraversalIdsChildren background migration' do
- let(:job_class_name) { 'BackfillNamespaceTraversalIdsChildren' }
-
- include_context 'incomplete background migration'
-
- before do
- migrate!
- end
-
- it_behaves_like(
- 'finalized tracked background migration',
- Gitlab::BackgroundMigration::BackfillNamespaceTraversalIdsChildren
- )
- end
-end
diff --git a/spec/migrations/insert_daily_invites_trial_plan_limits_spec.rb b/spec/migrations/insert_daily_invites_trial_plan_limits_spec.rb
new file mode 100644
index 00000000000..ea1476b94a9
--- /dev/null
+++ b/spec/migrations/insert_daily_invites_trial_plan_limits_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe InsertDailyInvitesTrialPlanLimits, feature_category: :subgroups do
+ let(:plans) { table(:plans) }
+ let(:plan_limits) { table(:plan_limits) }
+ let!(:premium_trial_plan) { plans.create!(name: 'premium_trial') }
+ let!(:ultimate_trial_plan) { plans.create!(name: 'ultimate_trial') }
+
+ context 'when on gitlab.com' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ trial_plan_ids = [premium_trial_plan.id, ultimate_trial_plan.id]
+ expect(plan_limits.where(plan_id: trial_plan_ids).where.not(daily_invites: 0)).to be_empty
+ }
+
+ migration.after -> {
+ expect(plan_limits.pluck(:plan_id, :daily_invites))
+ .to contain_exactly([premium_trial_plan.id, 50], [ultimate_trial_plan.id, 50])
+ }
+ end
+ end
+ end
+
+ context 'when on self-managed' do
+ before do
+ allow(Gitlab).to receive(:com?).and_return(false)
+ end
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ trial_plan_ids = [premium_trial_plan.id, ultimate_trial_plan.id]
+
+ migration.before -> {
+ expect(plan_limits.where(plan_id: trial_plan_ids).where.not(daily_invites: 0)).to be_empty
+ }
+
+ migration.after -> {
+ expect(plan_limits.where(plan_id: trial_plan_ids).where.not(daily_invites: 0)).to be_empty
+ }
+ end
+ end
+ 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
deleted file mode 100644
index 8209f317550..00000000000
--- a/spec/migrations/queue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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/queue_backfill_prepared_at_data_spec.rb b/spec/migrations/queue_backfill_prepared_at_data_spec.rb
new file mode 100644
index 00000000000..ac3ea2f59c5
--- /dev/null
+++ b/spec/migrations/queue_backfill_prepared_at_data_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillPreparedAtData, feature_category: :code_review_workflow do
+ let!(:batched_migration) { described_class::MIGRATION }
+
+ it 'schedules a new batched migration' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(batched_migration).not_to have_scheduled_batched_migration
+ }
+
+ migration.after -> {
+ expect(batched_migration).to have_scheduled_batched_migration(
+ table_name: :merge_requests,
+ column_name: :id,
+ interval: described_class::DELAY_INTERVAL
+ )
+ }
+ end
+ end
+end
diff --git a/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_features_spec.rb b/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_features_spec.rb
deleted file mode 100644
index 80ecc23dfbe..00000000000
--- a/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_features_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe RecreateIndexSecurityCiBuildsOnNameAndIdParserFeatures, :migration, feature_category: :database do
- let(:db) { described_class.new }
- let(:pg_class) { table(:pg_class) }
- let(:pg_index) { table(:pg_index) }
- let(:async_indexes) { table(:postgres_async_indexes) }
-
- it "recreates index" do
- reversible_migration do |migration|
- migration.before -> {
- expect(async_indexes.where(name: described_class::OLD_INDEX_NAME).exists?).to be false
- expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::OLD_INDEX_NAME)).to be true
- expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::NEW_INDEX_NAME)).to be false
- }
-
- migration.after -> {
- expect(async_indexes.where(name: described_class::OLD_INDEX_NAME).exists?).to be true
- expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::OLD_INDEX_NAME)).to be false
- expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::NEW_INDEX_NAME)).to be true
- }
- end
- end
-end
diff --git a/spec/migrations/remove_invalid_deploy_access_level_spec.rb b/spec/migrations/remove_invalid_deploy_access_level_spec.rb
deleted file mode 100644
index cc0f5679dda..00000000000
--- a/spec/migrations/remove_invalid_deploy_access_level_spec.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe RemoveInvalidDeployAccessLevel, :migration, feature_category: :continuous_integration do
- let(:users) { table(:users) }
- let(:groups) { table(:namespaces) }
- let(:protected_environments) { table(:protected_environments) }
- let(:deploy_access_levels) { table(:protected_environment_deploy_access_levels) }
-
- let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) }
- let(:group) { groups.create!(name: 'test-group', path: 'test-group') }
- let(:pe) do
- protected_environments.create!(name: 'test-pe', group_id: group.id)
- end
-
- let!(:invalid_access_level) do
- deploy_access_levels.create!(
- access_level: 40,
- user_id: user.id,
- group_id: group.id,
- protected_environment_id: pe.id)
- end
-
- let!(:group_access_level) do
- deploy_access_levels.create!(
- group_id: group.id,
- protected_environment_id: pe.id)
- end
-
- let!(:user_access_level) do
- deploy_access_levels.create!(
- user_id: user.id,
- protected_environment_id: pe.id)
- end
-
- it 'removes invalid access_level entries' do
- expect { migrate! }.to change {
- deploy_access_levels.where(
- protected_environment_id: pe.id,
- access_level: nil).count
- }.from(2).to(3)
-
- expect(invalid_access_level.reload.access_level).to be_nil
- end
-end
diff --git a/spec/migrations/remove_packages_events_package_id_fk_spec.rb b/spec/migrations/remove_packages_events_package_id_fk_spec.rb
new file mode 100644
index 00000000000..13e73de88bd
--- /dev/null
+++ b/spec/migrations/remove_packages_events_package_id_fk_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+require_migration!
+
+RSpec.describe RemovePackagesEventsPackageIdFk, feature_category: :package_registry do
+ let(:table) { described_class::SOURCE_TABLE }
+ let(:column) { described_class::COLUMN }
+ let(:foreign_key) { -> { described_class.new.foreign_keys_for(table, column).first } }
+
+ it 'drops and creates the foreign key' do
+ reversible_migration do |migration|
+ migration.before -> do
+ expect(foreign_key.call).to have_attributes(column: column.to_s)
+ end
+
+ migration.after -> do
+ expect(foreign_key.call).to be(nil)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/remove_saml_provider_and_identities_non_root_group_spec.rb b/spec/migrations/remove_saml_provider_and_identities_non_root_group_spec.rb
new file mode 100644
index 00000000000..07873d0ce79
--- /dev/null
+++ b/spec/migrations/remove_saml_provider_and_identities_non_root_group_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveSamlProviderAndIdentitiesNonRootGroup, feature_category: :system_access do
+ let(:namespaces) { table(:namespaces) }
+ let(:saml_providers) { table(:saml_providers) }
+ let(:identities) { table(:identities) }
+ let(:root_group) do
+ namespaces.create!(name: 'root_group', path: 'foo', parent_id: nil, type: 'Group')
+ end
+
+ let(:non_root_group) do
+ namespaces.create!(name: 'non_root_group', path: 'non_root', parent_id: root_group.id, type: 'Group')
+ end
+
+ it 'removes saml_providers that belong to non-root group and related identities' do
+ provider_root_group = saml_providers.create!(
+ group_id: root_group.id,
+ sso_url: 'https://saml.example.com/adfs/ls',
+ certificate_fingerprint: '55:44:33:22:11:aa:bb:cc:dd:ee:ff:11:22:33:44:55:66:77:88:99',
+ default_membership_role: ::Gitlab::Access::GUEST,
+ enabled: true
+ )
+
+ identity_root_group = identities.create!(
+ saml_provider_id: provider_root_group.id,
+ extern_uid: "12345"
+ )
+
+ provider_non_root_group = saml_providers.create!(
+ group_id: non_root_group.id,
+ sso_url: 'https://saml.example.com/adfs/ls',
+ certificate_fingerprint: '55:44:33:22:11:aa:bb:cc:dd:ee:ff:11:22:33:44:55:66:77:88:99',
+ default_membership_role: ::Gitlab::Access::GUEST,
+ enabled: true
+ )
+
+ identity_non_root_group = identities.create!(
+ saml_provider_id: provider_non_root_group.id,
+ extern_uid: "12345"
+ )
+
+ expect { migrate! }.to change { saml_providers.count }.from(2).to(1)
+
+ expect(identities.find_by_id(identity_non_root_group.id)).to be_nil
+ expect(saml_providers.find_by_id(provider_non_root_group.id)).to be_nil
+
+ expect(identities.find_by_id(identity_root_group.id)).not_to be_nil
+ expect(saml_providers.find_by_id(provider_root_group.id)).not_to be_nil
+ end
+end
diff --git a/spec/migrations/remove_schedule_and_status_from_pending_alert_escalations_spec.rb b/spec/migrations/remove_schedule_and_status_from_pending_alert_escalations_spec.rb
deleted file mode 100644
index 86e161cea43..00000000000
--- a/spec/migrations/remove_schedule_and_status_from_pending_alert_escalations_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe RemoveScheduleAndStatusFromPendingAlertEscalations, feature_category: :incident_management do
- let(:escalations) { table(:incident_management_pending_alert_escalations) }
- let(:schedule_index) { 'index_incident_management_pending_alert_escalations_on_schedule' }
- let(:schedule_foreign_key) { 'fk_rails_fcbfd9338b' }
-
- it 'correctly migrates up and down' do
- reversible_migration do |migration|
- migration.before -> {
- expect(escalations.column_names).to include('schedule_id', 'status')
- expect(escalations_indexes).to include(schedule_index)
- expect(escalations_constraints).to include(schedule_foreign_key)
- }
-
- migration.after -> {
- escalations.reset_column_information
- expect(escalations.column_names).not_to include('schedule_id', 'status')
- expect(escalations_indexes).not_to include(schedule_index)
- expect(escalations_constraints).not_to include(schedule_foreign_key)
- }
- end
- end
-
- private
-
- def escalations_indexes
- ActiveRecord::Base.connection.indexes(:incident_management_pending_alert_escalations).collect(&:name)
- end
-
- def escalations_constraints
- ActiveRecord::Base.connection.foreign_keys(:incident_management_pending_alert_escalations).collect(&:name)
- end
-end
diff --git a/spec/migrations/remove_scim_token_and_scim_identity_non_root_group_spec.rb b/spec/migrations/remove_scim_token_and_scim_identity_non_root_group_spec.rb
new file mode 100644
index 00000000000..31915365c91
--- /dev/null
+++ b/spec/migrations/remove_scim_token_and_scim_identity_non_root_group_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveScimTokenAndScimIdentityNonRootGroup, feature_category: :system_access do
+ let(:namespaces) { table(:namespaces) }
+ let(:scim_oauth_access_tokens) { table(:scim_oauth_access_tokens) }
+ let(:scim_identities) { table(:scim_identities) }
+ let(:users) { table(:users) }
+ let(:root_group) do
+ namespaces.create!(name: 'root_group', path: 'foo', parent_id: nil, type: 'Group')
+ end
+
+ let(:non_root_group) do
+ namespaces.create!(name: 'non_root_group', path: 'non_root', parent_id: root_group.id, type: 'Group')
+ end
+
+ let(:root_group_user) do
+ users.create!(name: 'Example User', email: 'user@example.com', projects_limit: 0)
+ end
+
+ let(:non_root_group_user) do
+ users.create!(username: 'user2', email: 'user2@example.com', projects_limit: 10)
+ end
+
+ it 'removes scim_oauth_access_tokens that belong to non-root group and related scim_identities' do
+ scim_oauth_access_token_root_group = scim_oauth_access_tokens.create!(
+ group_id: root_group.id,
+ token_encrypted: Gitlab::CryptoHelper.aes256_gcm_encrypt(SecureRandom.hex(50))
+ )
+ scim_oauth_access_token_non_root_group = scim_oauth_access_tokens.create!(
+ group_id: non_root_group.id,
+ token_encrypted: Gitlab::CryptoHelper.aes256_gcm_encrypt(SecureRandom.hex(50))
+ )
+
+ scim_identity_root_group = scim_identities.create!(
+ group_id: root_group.id,
+ extern_uid: "12345",
+ user_id: root_group_user.id,
+ active: true
+ )
+
+ scim_identity_non_root_group = scim_identities.create!(
+ group_id: non_root_group.id,
+ extern_uid: "12345",
+ user_id: non_root_group_user.id,
+ active: true
+ )
+
+ expect { migrate! }.to change { scim_oauth_access_tokens.count }.from(2).to(1)
+ expect(scim_oauth_access_tokens.find_by_id(scim_oauth_access_token_non_root_group.id)).to be_nil
+ expect(scim_identities.find_by_id(scim_identity_non_root_group.id)).to be_nil
+
+ expect(scim_oauth_access_tokens.find_by_id(scim_oauth_access_token_root_group.id)).not_to be_nil
+ expect(scim_identities.find_by_id(scim_identity_root_group.id)).not_to be_nil
+ end
+end
diff --git a/spec/migrations/requeue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb b/spec/migrations/requeue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb
new file mode 100644
index 00000000000..b9af6d98beb
--- /dev/null
+++ b/spec/migrations/requeue_backfill_admin_mode_scope_for_personal_access_tokens_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RequeueBackfillAdminModeScopeForPersonalAccessTokens, feature_category: :system_access 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/rerun_remove_invalid_deploy_access_level_spec.rb b/spec/migrations/rerun_remove_invalid_deploy_access_level_spec.rb
new file mode 100644
index 00000000000..72663e63996
--- /dev/null
+++ b/spec/migrations/rerun_remove_invalid_deploy_access_level_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RerunRemoveInvalidDeployAccessLevel, :migration, feature_category: :continuous_integration do
+ let(:users) { table(:users) }
+ let(:groups) { table(:namespaces) }
+ let(:protected_environments) { table(:protected_environments) }
+ let(:deploy_access_levels) { table(:protected_environment_deploy_access_levels) }
+
+ let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) }
+ let(:group) { groups.create!(name: 'test-group', path: 'test-group') }
+ let(:pe) do
+ protected_environments.create!(name: 'test-pe', group_id: group.id)
+ end
+
+ let!(:invalid_access_level) do
+ deploy_access_levels.create!(
+ access_level: 40,
+ user_id: user.id,
+ group_id: group.id,
+ protected_environment_id: pe.id)
+ end
+
+ let!(:access_level) do
+ deploy_access_levels.create!(
+ access_level: 40,
+ user_id: nil,
+ group_id: nil,
+ protected_environment_id: pe.id)
+ end
+
+ let!(:group_access_level) do
+ deploy_access_levels.create!(
+ group_id: group.id,
+ protected_environment_id: pe.id)
+ end
+
+ let!(:user_access_level) do
+ deploy_access_levels.create!(
+ user_id: user.id,
+ protected_environment_id: pe.id)
+ end
+
+ let!(:user_and_group_access_level) do
+ deploy_access_levels.create!(
+ user_id: user.id,
+ group_id: group.id,
+ protected_environment_id: pe.id)
+ end
+
+ it 'fixes invalid access_level entries and does not affect others' do
+ expect { migrate! }.to change {
+ deploy_access_levels.where(protected_environment_id: pe.id)
+ .where("num_nonnulls(user_id, group_id, access_level) = 1").count
+ }.from(3).to(5)
+
+ invalid_access_level.reload
+ access_level.reload
+ group_access_level.reload
+ user_access_level.reload
+ user_and_group_access_level.reload
+
+ expect(invalid_access_level.access_level).to be_nil
+ expect(invalid_access_level.user_id).to eq(user.id)
+ expect(invalid_access_level.group_id).to be_nil
+
+ expect(access_level.access_level).to eq(40)
+ expect(access_level.user_id).to be_nil
+ expect(access_level.group_id).to be_nil
+
+ expect(group_access_level.access_level).to be_nil
+ expect(group_access_level.user_id).to be_nil
+ expect(group_access_level.group_id).to eq(group.id)
+
+ expect(user_access_level.access_level).to be_nil
+ expect(user_access_level.user_id).to eq(user.id)
+ expect(user_access_level.group_id).to be_nil
+
+ expect(user_and_group_access_level.access_level).to be_nil
+ expect(user_and_group_access_level.user_id).to eq(user.id)
+ expect(user_and_group_access_level.group_id).to be_nil
+ end
+end
diff --git a/spec/migrations/reschedule_incident_work_item_type_id_backfill_spec.rb b/spec/migrations/reschedule_incident_work_item_type_id_backfill_spec.rb
new file mode 100644
index 00000000000..cb8773e9a9f
--- /dev/null
+++ b/spec/migrations/reschedule_incident_work_item_type_id_backfill_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RescheduleIncidentWorkItemTypeIdBackfill, :migration, feature_category: :team_planning do
+ include MigrationHelpers::WorkItemTypesHelper
+
+ let!(:migration) { described_class::MIGRATION }
+ let!(:interval) { 2.minutes }
+ let!(:incident_type_enum) { 1 }
+ let!(:issue_type_enum) { 0 }
+ let!(:incident_work_item_type) do
+ table(:work_item_types).find_by!(namespace_id: nil, base_type: incident_type_enum)
+ end
+
+ let!(:issue_work_item_type) do
+ table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_type_enum)
+ end
+
+ describe '#up' do
+ let!(:existing_incident_migration) { create_backfill_migration(incident_type_enum, incident_work_item_type.id) }
+ let!(:existing_issue_migration) { create_backfill_migration(issue_type_enum, issue_work_item_type.id) }
+
+ it 'correctly reschedules background migration only for incidents' do
+ migrate!
+
+ migration_ids = table(:batched_background_migrations).pluck(:id)
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :issues,
+ column_name: :id,
+ job_arguments: [incident_type_enum, incident_work_item_type.id],
+ interval: interval,
+ batch_size: described_class::BATCH_SIZE,
+ max_batch_size: described_class::MAX_BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE
+ )
+ expect(migration_ids.count).to eq(2)
+ expect(migration_ids).not_to include(existing_incident_migration.id)
+ expect(migration_ids).to include(existing_issue_migration.id)
+ end
+
+ it "doesn't fail if work item types don't exist on the DB" do
+ table(:work_item_types).delete_all
+
+ migrate!
+
+ # Since migration specs run outside of a transaction, we need to make
+ # sure we recreate default types since this spec deletes them all
+ reset_work_item_types
+ end
+ end
+
+ def create_backfill_migration(base_type, type_id)
+ table(:batched_background_migrations).create!(
+ job_class_name: migration,
+ table_name: :issues,
+ column_name: :id,
+ job_arguments: [base_type, type_id],
+ interval: 2.minutes,
+ min_value: 1,
+ max_value: 2,
+ batch_size: 1000,
+ sub_batch_size: 200,
+ gitlab_schema: :gitlab_main,
+ status: 3
+ )
+ 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 a3bec40c3f0..abcdde7f075 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
@@ -5,7 +5,7 @@ require 'spec_helper'
require_migration!
RSpec.describe ScheduleBackfillDraftStatusOnMergeRequestsCorrectedRegex,
- :sidekiq, feature_category: :code_review_workflow do
+ :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_fixing_security_scan_statuses_spec.rb b/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb
index c4c7819bda7..56d30e71676 100644
--- a/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb
+++ b/spec/migrations/schedule_fixing_security_scan_statuses_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
require_migration!
-RSpec.describe ScheduleFixingSecurityScanStatuses, :suppress_gitlab_schemas_validate_connection,
- feature_category: :vulnerability_management do
+RSpec.describe ScheduleFixingSecurityScanStatuses,
+ :suppress_gitlab_schemas_validate_connection, feature_category: :vulnerability_management do
let!(:namespaces) { table(:namespaces) }
let!(:projects) { table(:projects) }
let!(:pipelines) { table(:ci_pipelines) }
diff --git a/spec/migrations/schedule_migrate_shared_vulnerability_identifiers_spec.rb b/spec/migrations/schedule_migrate_shared_vulnerability_identifiers_spec.rb
new file mode 100644
index 00000000000..c1802a1a339
--- /dev/null
+++ b/spec/migrations/schedule_migrate_shared_vulnerability_identifiers_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+require_migration!
+
+RSpec.describe ScheduleMigrateSharedVulnerabilityIdentifiers, :migration, feature_category: :vulnerability_management do
+ describe "#up" do
+ before do
+ migrate!
+ end
+
+ it "schedules" do
+ Gitlab::Database::BackgroundMigration::BatchedMigration.find_by!(
+ job_class_name: described_class::MIGRATION,
+ table_name: described_class::TABLE_NAME,
+ column_name: described_class::BATCH_COLUMN,
+ batch_size: described_class::BATCH_SIZE,
+ sub_batch_size: described_class::SUB_BATCH_SIZE)
+ end
+ end
+
+ describe '#down' do
+ before do
+ schema_migrate_down!
+ end
+
+ it "deletes" do
+ expect(described_class::MIGRATION).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/schedule_purging_stale_security_scans_spec.rb b/spec/migrations/schedule_purging_stale_security_scans_spec.rb
index b39baa145ff..906dc90bcc4 100644
--- a/spec/migrations/schedule_purging_stale_security_scans_spec.rb
+++ b/spec/migrations/schedule_purging_stale_security_scans_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe SchedulePurgingStaleSecurityScans, :suppress_gitlab_schemas_validate_connection,
-feature_category: :vulnerability_management do
+ feature_category: :vulnerability_management do
let!(:namespaces) { table(:namespaces) }
let!(:projects) { table(:projects) }
let!(:pipelines) { table(:ci_pipelines) }
diff --git a/spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb b/spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb
deleted file mode 100644
index 8903a32285e..00000000000
--- a/spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe ScheduleRecalculateVulnerabilityFindingSignaturesForFindings, :migration,
-feature_category: :vulnerability_management do
- before do
- allow(Gitlab).to receive(:ee?).and_return(ee?)
- stub_const("#{described_class.name}::BATCH_SIZE", 2)
- end
-
- context 'when the Gitlab instance is FOSS' do
- let(:ee?) { false }
-
- it 'does not run the migration' do
- expect { migrate! }.not_to change { BackgroundMigrationWorker.jobs.size }
- end
- end
-
- context 'when the Gitlab instance is EE' do
- let(:ee?) { true }
-
- let!(:namespaces) { table(:namespaces) }
- let!(:projects) { table(:projects) }
- let!(:findings) { table(:vulnerability_occurrences) }
- let!(:scanners) { table(:vulnerability_scanners) }
- let!(:identifiers) { table(:vulnerability_identifiers) }
- let!(:vulnerability_finding_signatures) { table(:vulnerability_finding_signatures) }
-
- let!(:namespace) { namespaces.create!(name: 'test', path: 'test') }
- let!(:project) { projects.create!(namespace_id: namespace.id, name: 'gitlab', path: 'gitlab') }
-
- let!(:scanner) do
- scanners.create!(project_id: project.id, external_id: 'trivy', name: 'Security Scanner')
- end
-
- let!(:identifier) do
- identifiers.create!(project_id: project.id,
- fingerprint: 'd432c2ad2953e8bd587a3a43b3ce309b5b0154c123',
- external_type: 'SECURITY_ID',
- external_id: 'SECURITY_0',
- name: 'SECURITY_IDENTIFIER 0')
- end
-
- let!(:finding1) { findings.create!(finding_params) }
- let!(:signature1) { vulnerability_finding_signatures.create!(finding_id: finding1.id, algorithm_type: 0, signature_sha: ::Digest::SHA1.digest(SecureRandom.hex(50))) }
-
- let!(:finding2) { findings.create!(finding_params) }
- let!(:signature2) { vulnerability_finding_signatures.create!(finding_id: finding2.id, algorithm_type: 0, signature_sha: ::Digest::SHA1.digest(SecureRandom.hex(50))) }
-
- let!(:finding3) { findings.create!(finding_params) }
- let!(:signature3) { vulnerability_finding_signatures.create!(finding_id: finding3.id, algorithm_type: 0, signature_sha: ::Digest::SHA1.digest(SecureRandom.hex(50))) }
-
- # this migration is now a no-op
- it 'does not schedule the background jobs', :aggregate_failure do
- Sidekiq::Testing.fake! do
- freeze_time do
- migrate!
-
- expect(BackgroundMigrationWorker.jobs.size).to eq(0)
- expect(described_class::MIGRATION)
- .not_to be_scheduled_migration_with_multiple_args(signature1.id, signature2.id)
- expect(described_class::MIGRATION)
- .not_to be_scheduled_migration_with_multiple_args(signature3.id, signature3.id)
- end
- end
- end
-
- def finding_params
- uuid = SecureRandom.uuid
-
- {
- severity: 0,
- confidence: 5,
- report_type: 2,
- project_id: project.id,
- scanner_id: scanner.id,
- primary_identifier_id: identifier.id,
- location: nil,
- project_fingerprint: SecureRandom.hex(20),
- location_fingerprint: Digest::SHA1.hexdigest(SecureRandom.hex(10)),
- uuid: uuid,
- name: "Vulnerability Finding #{uuid}",
- metadata_version: '1.3',
- raw_metadata: '{}'
- }
- end
- end
-end
diff --git a/spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb b/spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb
index 8e00fbe4b89..02ecbe90ee0 100644
--- a/spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb
+++ b/spec/migrations/set_email_confirmation_setting_before_removing_send_user_confirmation_email_column_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe SetEmailConfirmationSettingBeforeRemovingSendUserConfirmationEmailColumn,
- feature_category: :user_profile do
+ feature_category: :user_profile do
let(:migration) { described_class.new }
let(:application_settings_table) { table(:application_settings) }
diff --git a/spec/migrations/set_email_confirmation_setting_from_soft_email_confirmation_ff_spec.rb b/spec/migrations/set_email_confirmation_setting_from_soft_email_confirmation_ff_spec.rb
new file mode 100644
index 00000000000..202baebf1da
--- /dev/null
+++ b/spec/migrations/set_email_confirmation_setting_from_soft_email_confirmation_ff_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SetEmailConfirmationSettingFromSoftEmailConfirmationFf, feature_category: :feature_flags do
+ let(:migration) { described_class.new }
+ let(:application_settings_table) { table(:application_settings) }
+ let(:feature_gates_table) { table(:feature_gates) }
+
+ describe '#up' do
+ context 'when feature gate for `soft_email_confirmation` does not exist' do
+ it 'does not update `email_confirmation_setting`' do
+ application_settings_table.create!(email_confirmation_setting: 0)
+
+ migration.up
+
+ expect(application_settings_table.last.email_confirmation_setting).to eq 0
+ end
+ end
+
+ context 'when feature gate for `soft_email_confirmation` does exist' do
+ context 'when feature gate value is `false`' do
+ before do
+ feature_gates_table.create!(feature_key: 'soft_email_confirmation', key: 'boolean', value: 'false')
+ end
+
+ it 'does not update `email_confirmation_setting`' do
+ application_settings_table.create!(email_confirmation_setting: 0)
+
+ migration.up
+
+ expect(application_settings_table.last.email_confirmation_setting).to eq 0
+ end
+ end
+
+ context 'when feature gate value is `true`' do
+ before do
+ feature_gates_table.create!(feature_key: 'soft_email_confirmation', key: 'boolean', value: 'true')
+ end
+
+ it "updates `email_confirmation_setting` to '1' (soft)" do
+ application_settings_table.create!(email_confirmation_setting: 0)
+
+ migration.up
+
+ expect(application_settings_table.last.email_confirmation_setting).to eq 1
+ end
+ end
+ end
+ end
+
+ describe '#down' do
+ it "updates 'email_confirmation_setting' to default value: '0' (off)" do
+ application_settings_table.create!(email_confirmation_setting: 1)
+
+ migration.down
+
+ expect(application_settings_table.last.email_confirmation_setting).to eq 0
+ 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
deleted file mode 100644
index ffd25152a45..00000000000
--- a/spec/migrations/slice_merge_request_diff_commit_migrations_spec.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_migration!
-
-RSpec.describe SliceMergeRequestDiffCommitMigrations, :migration, feature_category: :code_review_workflow do
- let(:migration) { described_class.new }
-
- describe '#up' do
- context 'when there are no jobs to process' do
- it 'does nothing' do
- expect(migration).not_to receive(:migrate_in)
- expect(Gitlab::Database::BackgroundMigrationJob).not_to receive(:create!)
-
- migration.up
- end
- end
-
- context 'when there are pending jobs' do
- let!(:job1) do
- Gitlab::Database::BackgroundMigrationJob.create!(
- class_name: described_class::MIGRATION_CLASS,
- arguments: [1, 10_001]
- )
- end
-
- let!(:job2) do
- Gitlab::Database::BackgroundMigrationJob.create!(
- class_name: described_class::MIGRATION_CLASS,
- arguments: [10_001, 20_001]
- )
- end
-
- it 'marks the old jobs as finished' do
- migration.up
-
- job1.reload
- job2.reload
-
- expect(job1).to be_succeeded
- expect(job2).to be_succeeded
- end
-
- it 'the jobs are slices into smaller ranges' do
- migration.up
-
- new_jobs = Gitlab::Database::BackgroundMigrationJob
- .for_migration_class(described_class::MIGRATION_CLASS)
- .pending
- .to_a
-
- expect(new_jobs.map(&:arguments)).to eq(
- [
- [1, 5_001],
- [5_001, 10_001],
- [10_001, 15_001],
- [15_001, 20_001]
- ])
- end
-
- it 'schedules a background migration for the first job' do
- expect(migration)
- .to receive(:migrate_in)
- .with(1.hour, described_class::STEAL_MIGRATION_CLASS, [1, 5_001])
-
- migration.up
- end
- end
- end
-end
diff --git a/spec/migrations/start_backfill_ci_queuing_tables_spec.rb b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb
index c308a16d5b8..0a189b58c94 100644
--- a/spec/migrations/start_backfill_ci_queuing_tables_spec.rb
+++ b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe StartBackfillCiQueuingTables, :suppress_gitlab_schemas_validate_connection,
-feature_category: :continuous_integration do
+ feature_category: :continuous_integration do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:builds) { table(:ci_builds) }
diff --git a/spec/migrations/swap_award_emoji_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_award_emoji_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..c133deaf250
--- /dev/null
+++ b/spec/migrations/swap_award_emoji_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapAwardEmojiNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE award_emoji ALTER COLUMN awardable_id TYPE integer')
+ connection.execute('ALTER TABLE award_emoji ALTER COLUMN awardable_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ award_emoji = table(:award_emoji)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('integer')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('bigint')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }.sql_type)
+ .to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ award_emoji = table(:award_emoji)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('integer')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ award_emoji.reset_column_information
+
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id' }.sql_type).to eq('integer')
+ expect(award_emoji.columns.find { |c| c.name == 'awardable_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_commit_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_commit_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..d219d544033
--- /dev/null
+++ b/spec/migrations/swap_commit_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapCommitUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE commit_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE commit_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:commit_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:commit_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_design_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_design_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..c7cbf7bfe2a
--- /dev/null
+++ b/spec/migrations/swap_design_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapDesignUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE design_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE design_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:design_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:design_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_epic_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_epic_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..41cc75672e1
--- /dev/null
+++ b/spec/migrations/swap_epic_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapEpicUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE epic_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE epic_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:epic_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:epic_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_2_spec.rb b/spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_2_spec.rb
new file mode 100644
index 00000000000..2c561730d95
--- /dev/null
+++ b/spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_2_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+# rubocop: disable RSpec/FilePath
+RSpec.describe SwapIssueUserMentionsNoteIdToBigintForGitlabDotCom2, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:issue_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:issue_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op if columns are already swapped' do
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE integer')
+
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ migrate!
+
+ user_mentions = table(:issue_user_mentions)
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
+# rubocop: enable RSpec/FilePath
diff --git a/spec/migrations/swap_merge_request_metrics_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_merge_request_metrics_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..b819495aa89
--- /dev/null
+++ b/spec/migrations/swap_merge_request_metrics_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapMergeRequestMetricsIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE merge_request_metrics ALTER COLUMN id TYPE integer')
+ connection.execute('ALTER TABLE merge_request_metrics ALTER COLUMN id_convert_to_bigint TYPE bigint')
+ end
+
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ merge_request_metrics = table(:merge_request_metrics)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(merge_request_metrics.columns.find do |c|
+ c.name == 'id_convert_to_bigint'
+ end.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(merge_request_metrics.columns.find do |c|
+ c.name == 'id_convert_to_bigint'
+ end.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ merge_request_metrics = table(:merge_request_metrics)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(merge_request_metrics.columns.find do |c|
+ c.name == 'id_convert_to_bigint'
+ end.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(merge_request_metrics.columns.find do |c|
+ c.name == 'id_convert_to_bigint'
+ end.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/swap_merge_request_metrics_id_to_bigint_for_self_hosts_spec.rb b/spec/migrations/swap_merge_request_metrics_id_to_bigint_for_self_hosts_spec.rb
new file mode 100644
index 00000000000..a2d9887a6c0
--- /dev/null
+++ b/spec/migrations/swap_merge_request_metrics_id_to_bigint_for_self_hosts_spec.rb
@@ -0,0 +1,155 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapMergeRequestMetricsIdToBigintForSelfHosts, feature_category: :database do
+ after do
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE merge_request_metrics DROP COLUMN IF EXISTS id_convert_to_bigint')
+ end
+
+ describe '#up' do
+ context 'when is GitLab.com, dev, or test' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE merge_request_metrics ALTER COLUMN id TYPE bigint')
+ connection.execute('ALTER TABLE merge_request_metrics DROP COLUMN IF EXISTS id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ merge_request_metrics = table(:merge_request_metrics)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be nil
+ }
+
+ migration.after -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be nil
+ }
+ end
+ end
+ end
+ end
+
+ context 'when is a self-host customer with the swapped already completed' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE merge_request_metrics ALTER COLUMN id TYPE bigint')
+ connection.execute('ALTER TABLE merge_request_metrics ADD COLUMN IF NOT EXISTS id_convert_to_bigint integer')
+ end
+
+ it 'does not swap the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ merge_request_metrics = table(:merge_request_metrics)
+
+ migrate!
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(merge_request_metrics.columns.find do |c|
+ c.name == 'id_convert_to_bigint'
+ end.sql_type).to eq('integer')
+ end
+ end
+
+ context 'when is a self-host customer with the `id_convert_to_bigint` column already dropped ' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE merge_request_metrics ALTER COLUMN id TYPE bigint')
+ connection.execute('ALTER TABLE merge_request_metrics DROP COLUMN IF EXISTS id_convert_to_bigint')
+ end
+
+ it 'does not swap the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ merge_request_metrics = table(:merge_request_metrics)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be nil
+ }
+
+ migration.after -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id_convert_to_bigint' }).to be nil
+ }
+ end
+ end
+ end
+ end
+
+ context 'when is a self-host customer' do
+ before do
+ # As we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE merge_request_metrics ALTER COLUMN id TYPE integer')
+ connection.execute('ALTER TABLE merge_request_metrics ADD COLUMN IF NOT EXISTS id_convert_to_bigint bigint')
+ connection.execute('ALTER TABLE merge_request_metrics ALTER COLUMN id_convert_to_bigint TYPE bigint')
+ connection.execute('DROP INDEX IF EXISTS index_merge_request_metrics_on_id_convert_to_bigint')
+ connection.execute('DROP INDEX IF EXISTS tmp_index_mr_metrics_on_target_project_id_merged_at_nulls_last')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_c7107f30d69d() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."id_convert_to_bigint" := NEW."id"; RETURN NEW; END; $$;')
+ end
+
+ it 'swaps the columns' do
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+ # rubocop: enable RSpec/AnyInstanceOf
+
+ merge_request_metrics = table(:merge_request_metrics)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(merge_request_metrics.columns.find do |c|
+ c.name == 'id_convert_to_bigint'
+ end.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ merge_request_metrics.reset_column_information
+
+ expect(merge_request_metrics.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(merge_request_metrics.columns.find do |c|
+ c.name == 'id_convert_to_bigint'
+ end.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_spec.rb b/spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_spec.rb
new file mode 100644
index 00000000000..15b21d34714
--- /dev/null
+++ b/spec/migrations/swap_merge_request_user_mentions_note_id_to_bigint_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapMergeRequestUserMentionsNoteIdToBigint, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE merge_request_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE merge_request_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:merge_request_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:merge_request_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_note_diff_files_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_note_diff_files_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..b0147f3ef58
--- /dev/null
+++ b/spec/migrations/swap_note_diff_files_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapNoteDiffFilesNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE note_diff_files ALTER COLUMN diff_note_id TYPE integer')
+ connection.execute('ALTER TABLE note_diff_files ALTER COLUMN diff_note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ ndf = table(:note_diff_files)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ ndf.reset_column_information
+
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('integer')
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ ndf.reset_column_information
+
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('bigint')
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ ndf = table(:note_diff_files)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ ndf.reset_column_information
+
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('integer')
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ ndf.reset_column_information
+
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id' }.sql_type).to eq('integer')
+ expect(ndf.columns.find { |c| c.name == 'diff_note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_sent_notifications_id_columns_spec.rb b/spec/migrations/swap_sent_notifications_id_columns_spec.rb
new file mode 100644
index 00000000000..2f681a2a587
--- /dev/null
+++ b/spec/migrations/swap_sent_notifications_id_columns_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapSentNotificationsIdColumns, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE sent_notifications ALTER COLUMN id TYPE integer')
+ connection.execute('ALTER TABLE sent_notifications ALTER COLUMN id_convert_to_bigint TYPE bigint')
+ # rubocop: disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(run_migration?)
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+
+ context 'when we are GitLab.com, dev, or test' do
+ let(:run_migration?) { true }
+
+ it 'swaps the integer and bigint columns' do
+ sent_notifications = table(:sent_notifications)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ sent_notifications.reset_column_information
+
+ expect(sent_notifications.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ sent_notifications.reset_column_information
+
+ expect(sent_notifications.columns.find { |c| c.name == 'id' }.sql_type).to eq('bigint')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+ end
+
+ context 'when we are NOT GitLab.com, dev, or test' do
+ let(:run_migration?) { false }
+
+ it 'does not swap the integer and bigint columns' do
+ sent_notifications = table(:sent_notifications)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ sent_notifications.reset_column_information
+
+ expect(sent_notifications.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ sent_notifications.reset_column_information
+
+ expect(sent_notifications.columns.find { |c| c.name == 'id' }.sql_type).to eq('integer')
+ expect(sent_notifications.columns.find { |c| c.name == 'id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/swap_snippet_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_snippet_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..628c0fba528
--- /dev/null
+++ b/spec/migrations/swap_snippet_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapSnippetUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE snippet_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE snippet_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:snippet_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:snippet_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_suggestions_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_suggestions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..48d72ec151e
--- /dev/null
+++ b/spec/migrations/swap_suggestions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapSuggestionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE suggestions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE suggestions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ suggestions = table(:suggestions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ suggestions.reset_column_information
+
+ expect(suggestions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(suggestions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ suggestions.reset_column_information
+
+ expect(suggestions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(suggestions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ suggestions = table(:suggestions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ suggestions.reset_column_information
+
+ expect(suggestions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(suggestions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ suggestions.reset_column_information
+
+ expect(suggestions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(suggestions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_system_note_metadata_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_system_note_metadata_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..4fa5814986a
--- /dev/null
+++ b/spec/migrations/swap_system_note_metadata_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapSystemNoteMetadataNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE system_note_metadata ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE system_note_metadata ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ metadata = table(:system_note_metadata)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ metadata.reset_column_information
+
+ expect(metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ metadata.reset_column_information
+
+ expect(metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ metadata = table(:system_note_metadata)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ metadata.reset_column_information
+
+ expect(metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ metadata.reset_column_information
+
+ expect(metadata.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(metadata.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_timelogs_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_timelogs_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..708688ec446
--- /dev/null
+++ b/spec/migrations/swap_timelogs_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapTimelogsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE timelogs ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE timelogs ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ timelogs = table(:timelogs)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ timelogs.reset_column_information
+
+ expect(timelogs.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(timelogs.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ timelogs.reset_column_information
+
+ expect(timelogs.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(timelogs.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ timelogs = table(:timelogs)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ timelogs.reset_column_information
+
+ expect(timelogs.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(timelogs.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ timelogs.reset_column_information
+
+ expect(timelogs.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(timelogs.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_todos_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_todos_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..e71c921998a
--- /dev/null
+++ b/spec/migrations/swap_todos_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapTodosNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE todos ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE todos ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ todos = table(:todos)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ todos.reset_column_information
+
+ expect(todos.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(todos.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ todos.reset_column_information
+
+ expect(todos.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(todos.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ todos = table(:todos)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ todos.reset_column_information
+
+ expect(todos.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(todos.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ todos.reset_column_information
+
+ expect(todos.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(todos.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/swap_vulnerability_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_vulnerability_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..1e358387536
--- /dev/null
+++ b/spec/migrations/swap_vulnerability_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapVulnerabilityUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE vulnerability_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE vulnerability_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:vulnerability_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:vulnerability_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/migrations/sync_new_amount_used_for_ci_namespace_monthly_usages_spec.rb b/spec/migrations/sync_new_amount_used_for_ci_namespace_monthly_usages_spec.rb
index da8790f4450..c60447d04a1 100644
--- a/spec/migrations/sync_new_amount_used_for_ci_namespace_monthly_usages_spec.rb
+++ b/spec/migrations/sync_new_amount_used_for_ci_namespace_monthly_usages_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
require_migration!
RSpec.describe SyncNewAmountUsedForCiNamespaceMonthlyUsages, migration: :gitlab_ci,
- feature_category: :continuous_integration do
+ feature_category: :continuous_integration do
let(:namespace_usages) { table(:ci_namespace_monthly_usages) }
before do
diff --git a/spec/migrations/sync_new_amount_used_for_ci_project_monthly_usages_spec.rb b/spec/migrations/sync_new_amount_used_for_ci_project_monthly_usages_spec.rb
index 1c9b2711687..d7add66a97f 100644
--- a/spec/migrations/sync_new_amount_used_for_ci_project_monthly_usages_spec.rb
+++ b/spec/migrations/sync_new_amount_used_for_ci_project_monthly_usages_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
require_migration!
RSpec.describe SyncNewAmountUsedForCiProjectMonthlyUsages, migration: :gitlab_ci,
- feature_category: :continuous_integration do
+ feature_category: :continuous_integration do
let(:project_usages) { table(:ci_project_monthly_usages) }
before do
diff --git a/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb b/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
index d249fcecf66..66da9e6653d 100644
--- a/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
+++ b/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe UpdateApplicationSettingsContainerRegistryExpPolWorkerCapacityDefault,
-feature_category: :container_registry do
+ feature_category: :container_registry do
let(:settings) { table(:application_settings) }
context 'with no rows in the application_settings table' do
diff --git a/spec/migrations/update_application_settings_protected_paths_spec.rb b/spec/migrations/update_application_settings_protected_paths_spec.rb
index d61eadf9f9c..c2bd4e8727d 100644
--- a/spec/migrations/update_application_settings_protected_paths_spec.rb
+++ b/spec/migrations/update_application_settings_protected_paths_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_migration!
RSpec.describe UpdateApplicationSettingsProtectedPaths, :aggregate_failures,
-feature_category: :authentication_and_authorization do
+ feature_category: :system_access do
subject(:migration) { described_class.new }
let!(:application_settings) { table(:application_settings) }
diff --git a/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb b/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
index ac7a4171063..15a8e79a610 100644
--- a/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
+++ b/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
@@ -14,13 +14,23 @@ RSpec.describe UpdateDefaultScanMethodOfDastSiteProfile, feature_category: :dyna
project = projects.create!(id: 12, namespace_id: namespace.id, name: 'gitlab', path: 'gitlab')
dast_site = dast_sites.create!(id: 1, url: 'https://www.gitlab.com', project_id: project.id)
- dast_site_profiles.create!(id: 1, project_id: project.id, dast_site_id: dast_site.id,
- name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 0",
- scan_method: 0, target_type: 0)
+ dast_site_profiles.create!(
+ id: 1,
+ project_id: project.id,
+ dast_site_id: dast_site.id,
+ name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 0",
+ scan_method: 0,
+ target_type: 0
+ )
- dast_site_profiles.create!(id: 2, project_id: project.id, dast_site_id: dast_site.id,
- name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 1",
- scan_method: 0, target_type: 1)
+ dast_site_profiles.create!(
+ id: 2,
+ project_id: project.id,
+ dast_site_id: dast_site.id,
+ name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 1",
+ scan_method: 0,
+ target_type: 1
+ )
end
it 'updates the scan_method to 1 for profiles with target_type 1' do