From 71786ddc8e28fbd3cb3fcc4b3ff15e5962a1c82e Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 20 Feb 2023 13:49:51 +0000 Subject: Add latest changes from gitlab-org/gitlab@15-9-stable-ee --- ...move_builds_email_service_from_services_spec.rb | 24 -- ..._delete_legacy_operations_feature_flags_spec.rb | 45 ---- ...061716138_cascade_delete_freeze_periods_spec.rb | 22 -- ...request_diff_users_background_migration_spec.rb | 76 ------ ...00_fix_ci_sources_pipelines_index_names_spec.rb | 67 ------ ...update_issuable_slas_where_issue_closed_spec.rb | 31 --- ...e_flags_correct_flexible_rollout_values_spec.rb | 66 ------ ...10804150320_create_base_work_item_types_spec.rb | 43 ---- ...ans_ci_daily_pipeline_schedule_triggers_spec.rb | 137 ----------- ...0811122206_update_external_project_bots_spec.rb | 25 -- ...remove_duplicate_project_authorizations_spec.rb | 62 ----- ...d_triggers_for_ci_builds_runner_session_spec.rb | 21 -- ...10_cleanup_orphan_project_access_tokens_spec.rb | 2 +- ...10922082019_drop_int4_column_for_events_spec.rb | 2 +- ...rop_int4_column_for_push_event_payloads_spec.rb | 2 +- ...eftover_external_pull_request_deletions_spec.rb | 2 +- ...move_leftover_ci_job_artifact_deletions_spec.rb | 2 +- ...ove_deactivated_user_highest_role_stats_spec.rb | 2 +- ...32350_add_password_expiration_migration_spec.rb | 2 +- ...assword_last_changed_at_to_user_details_spec.rb | 2 +- ...159_update_invalid_dormant_user_setting_spec.rb | 2 +- ...assword_last_changed_at_to_user_details_spec.rb | 2 +- ...assword_last_changed_at_to_user_details_spec.rb | 2 +- ...chedule_prune_stale_project_export_jobs_spec.rb | 2 +- ...1917_schedule_backfill_environment_tier_spec.rb | 2 +- ..._import_sources_on_application_settings_spec.rb | 2 +- ..._import_sources_on_application_settings_spec.rb | 2 +- ...ouse_connection_string_to_encrypted_var_spec.rb | 19 ++ ...ent_packages_size_on_project_statistics_spec.rb | 54 +++++ ...0117114739_clear_duplicate_jobs_cookies_spec.rb | 23 ++ ...3723_rebalance_partition_id_ci_pipeline_spec.rb | 58 +++++ ...5093840_rebalance_partition_id_ci_build_spec.rb | 58 +++++ ...nullify_creator_id_of_orphaned_projects_spec.rb | 32 +++ ...rsion_index_to_installable_npm_packages_spec.rb | 20 ++ ...ize_backfill_environment_tier_migration_spec.rb | 72 ++++++ ...20230202131928_encrypt_ci_trigger_token_spec.rb | 84 +++++++ ...ule_vulnerabilities_feedback_migration4_spec.rb | 31 +++ ..._partition_ids_for_ci_pipeline_variable_spec.rb | 58 +++++ ...9_fix_partition_ids_for_ci_job_artifact_spec.rb | 58 +++++ ...08132608_fix_partition_ids_for_ci_stage_spec.rb | 58 +++++ ...artition_ids_for_ci_build_report_result_spec.rb | 60 +++++ ...rtition_ids_for_ci_build_trace_metadata_spec.rb | 60 +++++ ...fix_partition_ids_for_ci_build_metadata_spec.rb | 60 +++++ ..._fix_partition_ids_for_ci_job_variables_spec.rb | 51 +++++ ...x_partition_ids_on_ci_sources_pipelines_spec.rb | 45 ++++ ...ult_project_approval_rules_vuln_allowed_spec.rb | 35 --- ...d_namespaces_emails_enabled_column_data_spec.rb | 69 ++++++ .../add_premium_and_ultimate_plan_limits_spec.rb | 88 ------- ...add_projects_emails_enabled_column_data_spec.rb | 75 ++++++ .../add_triggers_to_integrations_type_new_spec.rb | 77 ------- .../add_upvotes_count_index_to_issues_spec.rb | 22 -- ...ate_existing_dast_builds_with_variables_spec.rb | 10 - ...dence_id_for_boards_scoped_to_iteration_spec.rb | 108 --------- .../backfill_integrations_type_new_spec.rb | 38 --- .../backfill_issues_upvotes_count_spec.rb | 35 --- spec/migrations/backfill_stage_event_hash_spec.rb | 103 --------- ..._issue_when_admin_changed_primary_email_spec.rb | 2 +- ...fixing_regression_with_new_users_emails_spec.rb | 2 +- .../cleanup_remaining_orphan_invites_spec.rb | 37 --- spec/migrations/confirm_security_bot_spec.rb | 38 --- ..._policies_linked_to_no_container_images_spec.rb | 46 ---- ...hed_migrations_old_format_job_arguments_spec.rb | 63 ----- .../generate_customers_dot_jwt_signing_key_spec.rb | 42 ---- ...e_protected_attribute_to_pending_builds_spec.rb | 34 --- .../orphaned_invite_tokens_cleanup_spec.rb | 50 ---- .../queue_backfill_user_details_fields_spec.rb | 2 +- .../queue_populate_projects_star_count_spec.rb | 2 +- ...ith_all_security_related_artifact_types_spec.rb | 62 ----- .../recount_epic_cache_counts_v3_spec.rb | 32 +++ .../remove_duplicate_dast_site_tokens_spec.rb | 53 ----- ...licate_dast_site_tokens_with_same_token_spec.rb | 53 ----- .../remove_invalid_deploy_access_level_spec.rb | 48 ++++ .../rename_services_to_integrations_spec.rb | 255 --------------------- .../replace_external_wiki_triggers_spec.rb | 132 ----------- .../reschedule_delete_orphaned_deployments_spec.rb | 74 ------ .../reset_job_token_scope_enabled_again_spec.rb | 25 -- .../reset_job_token_scope_enabled_spec.rb | 25 -- .../reset_severity_levels_to_new_default_spec.rb | 33 --- .../retry_backfill_traversal_ids_spec.rb | 93 -------- .../sanitize_confidential_note_todos_spec.rb | 33 --- ...py_ci_builds_columns_to_security_scans2_spec.rb | 10 - .../schedule_security_setting_creation_spec.rb | 58 ----- .../set_default_job_token_scope_true_spec.rb | 33 --- ...ing_send_user_confirmation_email_column_spec.rb | 3 +- ...om_send_user_confirmation_email_setting_spec.rb | 2 +- ...rge_request_diff_commit_users_migration_spec.rb | 29 --- ...integrations_trigger_type_new_on_insert_spec.rb | 102 --------- 87 files changed, 1147 insertions(+), 2536 deletions(-) delete mode 100644 spec/migrations/20210603222333_remove_builds_email_service_from_services_spec.rb delete mode 100644 spec/migrations/20210610153556_delete_legacy_operations_feature_flags_spec.rb delete mode 100644 spec/migrations/2021061716138_cascade_delete_freeze_periods_spec.rb delete mode 100644 spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb delete mode 100644 spec/migrations/20210713042000_fix_ci_sources_pipelines_index_names_spec.rb delete mode 100644 spec/migrations/20210722042939_update_issuable_slas_where_issue_closed_spec.rb delete mode 100644 spec/migrations/20210722150102_operations_feature_flags_correct_flexible_rollout_values_spec.rb delete mode 100644 spec/migrations/20210804150320_create_base_work_item_types_spec.rb delete mode 100644 spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb delete mode 100644 spec/migrations/20210811122206_update_external_project_bots_spec.rb delete mode 100644 spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb delete mode 100644 spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb create mode 100644 spec/migrations/20221219122320_copy_clickhouse_connection_string_to_encrypted_var_spec.rb create mode 100644 spec/migrations/20221226153252_queue_fix_incoherent_packages_size_on_project_statistics_spec.rb create mode 100644 spec/migrations/20230117114739_clear_duplicate_jobs_cookies_spec.rb create mode 100644 spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb create mode 100644 spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb create mode 100644 spec/migrations/20230130073109_nullify_creator_id_of_orphaned_projects_spec.rb create mode 100644 spec/migrations/20230131125844_add_project_id_name_id_version_index_to_installable_npm_packages_spec.rb create mode 100644 spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb create mode 100644 spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb create mode 100644 spec/migrations/20230203122602_schedule_vulnerabilities_feedback_migration4_spec.rb create mode 100644 spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb create mode 100644 spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb create mode 100644 spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb create mode 100644 spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb create mode 100644 spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb create mode 100644 spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb create mode 100644 spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb create mode 100644 spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb delete mode 100644 spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb create mode 100644 spec/migrations/add_namespaces_emails_enabled_column_data_spec.rb delete mode 100644 spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb create mode 100644 spec/migrations/add_projects_emails_enabled_column_data_spec.rb delete mode 100644 spec/migrations/add_triggers_to_integrations_type_new_spec.rb delete mode 100644 spec/migrations/add_upvotes_count_index_to_issues_spec.rb delete mode 100644 spec/migrations/associate_existing_dast_builds_with_variables_spec.rb delete mode 100644 spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb delete mode 100644 spec/migrations/backfill_integrations_type_new_spec.rb delete mode 100644 spec/migrations/backfill_issues_upvotes_count_spec.rb delete mode 100644 spec/migrations/backfill_stage_event_hash_spec.rb delete mode 100644 spec/migrations/cleanup_remaining_orphan_invites_spec.rb delete mode 100644 spec/migrations/confirm_security_bot_spec.rb delete mode 100644 spec/migrations/disable_expiration_policies_linked_to_no_container_images_spec.rb delete mode 100644 spec/migrations/fix_batched_migrations_old_format_job_arguments_spec.rb delete mode 100644 spec/migrations/generate_customers_dot_jwt_signing_key_spec.rb delete mode 100644 spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb delete mode 100644 spec/migrations/orphaned_invite_tokens_cleanup_spec.rb delete mode 100644 spec/migrations/re_schedule_latest_pipeline_id_population_with_all_security_related_artifact_types_spec.rb create mode 100644 spec/migrations/recount_epic_cache_counts_v3_spec.rb delete mode 100644 spec/migrations/remove_duplicate_dast_site_tokens_spec.rb delete mode 100644 spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb create mode 100644 spec/migrations/remove_invalid_deploy_access_level_spec.rb delete mode 100644 spec/migrations/rename_services_to_integrations_spec.rb delete mode 100644 spec/migrations/replace_external_wiki_triggers_spec.rb delete mode 100644 spec/migrations/reschedule_delete_orphaned_deployments_spec.rb delete mode 100644 spec/migrations/reset_job_token_scope_enabled_again_spec.rb delete mode 100644 spec/migrations/reset_job_token_scope_enabled_spec.rb delete mode 100644 spec/migrations/reset_severity_levels_to_new_default_spec.rb delete mode 100644 spec/migrations/retry_backfill_traversal_ids_spec.rb delete mode 100644 spec/migrations/sanitize_confidential_note_todos_spec.rb delete mode 100644 spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb delete mode 100644 spec/migrations/schedule_security_setting_creation_spec.rb delete mode 100644 spec/migrations/set_default_job_token_scope_true_spec.rb delete mode 100644 spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb delete mode 100644 spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb (limited to 'spec/migrations') diff --git a/spec/migrations/20210603222333_remove_builds_email_service_from_services_spec.rb b/spec/migrations/20210603222333_remove_builds_email_service_from_services_spec.rb deleted file mode 100644 index 706e0b14492..00000000000 --- a/spec/migrations/20210603222333_remove_builds_email_service_from_services_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe RemoveBuildsEmailServiceFromServices, feature_category: :navigation do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:services) { table(:services) } - let(:namespace) { namespaces.create!(name: 'foo', path: 'bar') } - let(:project) { projects.create!(namespace_id: namespace.id) } - - it 'correctly deletes `BuildsEmailService` services' do - services.create!(project_id: project.id, type: 'BuildsEmailService') - services.create!(project_id: project.id, type: 'OtherService') - - expect(services.all.pluck(:type)).to match_array %w[BuildsEmailService OtherService] - - migrate! - - expect(services.all.pluck(:type)).to eq %w[OtherService] - end -end diff --git a/spec/migrations/20210610153556_delete_legacy_operations_feature_flags_spec.rb b/spec/migrations/20210610153556_delete_legacy_operations_feature_flags_spec.rb deleted file mode 100644 index 300c43b9133..00000000000 --- a/spec/migrations/20210610153556_delete_legacy_operations_feature_flags_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe DeleteLegacyOperationsFeatureFlags, feature_category: :feature_flags do - let(:namespace) { table(:namespaces).create!(name: 'foo', path: 'bar') } - let(:project) { table(:projects).create!(namespace_id: namespace.id) } - let(:issue) { table(:issues).create!(id: 123, project_id: project.id) } - let(:operations_feature_flags) { table(:operations_feature_flags) } - let(:operations_feature_flag_scopes) { table(:operations_feature_flag_scopes) } - let(:operations_strategies) { table(:operations_strategies) } - let(:operations_scopes) { table(:operations_scopes) } - let(:operations_feature_flags_issues) { table(:operations_feature_flags_issues) } - - it 'correctly deletes legacy feature flags' do - # Legacy version of a feature flag - dropped support in GitLab 14.0. - legacy_flag = operations_feature_flags.create!(project_id: project.id, version: 1, name: 'flag_a', active: true, iid: 1) - operations_feature_flag_scopes.create!(feature_flag_id: legacy_flag.id, active: true) - operations_feature_flags_issues.create!(feature_flag_id: legacy_flag.id, issue_id: issue.id) - # New version of a feature flag. - new_flag = operations_feature_flags.create!(project_id: project.id, version: 2, name: 'flag_b', active: true, iid: 2) - new_strategy = operations_strategies.create!(feature_flag_id: new_flag.id, name: 'default') - operations_scopes.create!(strategy_id: new_strategy.id, environment_scope: '*') - operations_feature_flags_issues.create!(feature_flag_id: new_flag.id, issue_id: issue.id) - - expect(operations_feature_flags.all.pluck(:version)).to contain_exactly(1, 2) - expect(operations_feature_flag_scopes.count).to eq(1) - expect(operations_strategies.count).to eq(1) - expect(operations_scopes.count).to eq(1) - expect(operations_feature_flags_issues.all.pluck(:feature_flag_id)).to contain_exactly(legacy_flag.id, new_flag.id) - - migrate! - - # Legacy flag is deleted. - expect(operations_feature_flags.all.pluck(:version)).to contain_exactly(2) - # The associated entries of the legacy flag are deleted too. - expect(operations_feature_flag_scopes.count).to eq(0) - # The associated entries of the new flag stay instact. - expect(operations_strategies.count).to eq(1) - expect(operations_scopes.count).to eq(1) - expect(operations_feature_flags_issues.all.pluck(:feature_flag_id)).to contain_exactly(new_flag.id) - end -end diff --git a/spec/migrations/2021061716138_cascade_delete_freeze_periods_spec.rb b/spec/migrations/2021061716138_cascade_delete_freeze_periods_spec.rb deleted file mode 100644 index baa5fd7efbd..00000000000 --- a/spec/migrations/2021061716138_cascade_delete_freeze_periods_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe CascadeDeleteFreezePeriods, :suppress_gitlab_schemas_validate_connection, feature_category: :continuous_delivery do - let(:namespace) { table(:namespaces).create!(name: 'deploy_freeze', path: 'deploy_freeze') } - let(:project) { table(:projects).create!(id: 1, namespace_id: namespace.id) } - let(:freeze_periods) { table(:ci_freeze_periods) } - - describe "#up" do - it 'allows for a project to be deleted' do - freeze_periods.create!(id: 1, project_id: project.id, freeze_start: '5 * * * *', freeze_end: '6 * * * *', cron_timezone: 'UTC') - migrate! - - project.delete - - expect(freeze_periods.where(project_id: project.id).count).to be_zero - end - end -end diff --git a/spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb b/spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb deleted file mode 100644 index 0f202129e82..00000000000 --- a/spec/migrations/20210708130419_reschedule_merge_request_diff_users_background_migration_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RescheduleMergeRequestDiffUsersBackgroundMigration, - :migration, feature_category: :code_review_workflow do - let(:migration) { described_class.new } - - describe '#up' do - before do - allow(described_class::MergeRequestDiff) - .to receive(:minimum) - .with(:id) - .and_return(42) - - allow(described_class::MergeRequestDiff) - .to receive(:maximum) - .with(:id) - .and_return(85_123) - end - - it 'deletes existing background migration job records' do - args = [150_000, 300_000] - - Gitlab::Database::BackgroundMigrationJob - .create!(class_name: described_class::MIGRATION_NAME, arguments: args) - - migration.up - - found = Gitlab::Database::BackgroundMigrationJob - .where(class_name: described_class::MIGRATION_NAME, arguments: args) - .count - - expect(found).to eq(0) - end - - it 'schedules the migrations in batches' do - expect(migration) - .to receive(:migrate_in) - .ordered - .with(2.minutes.to_i, described_class::MIGRATION_NAME, [42, 40_042]) - - expect(migration) - .to receive(:migrate_in) - .ordered - .with(4.minutes.to_i, described_class::MIGRATION_NAME, [40_042, 80_042]) - - expect(migration) - .to receive(:migrate_in) - .ordered - .with(6.minutes.to_i, described_class::MIGRATION_NAME, [80_042, 120_042]) - - migration.up - end - - it 'creates rows to track the background migration jobs' do - expect(Gitlab::Database::BackgroundMigrationJob) - .to receive(:create!) - .ordered - .with(class_name: described_class::MIGRATION_NAME, arguments: [42, 40_042]) - - expect(Gitlab::Database::BackgroundMigrationJob) - .to receive(:create!) - .ordered - .with(class_name: described_class::MIGRATION_NAME, arguments: [40_042, 80_042]) - - expect(Gitlab::Database::BackgroundMigrationJob) - .to receive(:create!) - .ordered - .with(class_name: described_class::MIGRATION_NAME, arguments: [80_042, 120_042]) - - migration.up - end - end -end diff --git a/spec/migrations/20210713042000_fix_ci_sources_pipelines_index_names_spec.rb b/spec/migrations/20210713042000_fix_ci_sources_pipelines_index_names_spec.rb deleted file mode 100644 index 6761b69aed5..00000000000 --- a/spec/migrations/20210713042000_fix_ci_sources_pipelines_index_names_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe FixCiSourcesPipelinesIndexNames, :migration, feature_category: :continuous_integration do - def validate_foreign_keys_and_index! - aggregate_failures do - expect(subject.foreign_key_exists?(:ci_sources_pipelines, :ci_builds, column: :source_job_id, name: 'fk_be5624bf37')).to be_truthy - expect(subject.foreign_key_exists?(:ci_sources_pipelines, :ci_pipelines, column: :pipeline_id, name: 'fk_e1bad85861')).to be_truthy - expect(subject.foreign_key_exists?(:ci_sources_pipelines, :ci_pipelines, column: :source_pipeline_id, name: 'fk_d4e29af7d7')).to be_truthy - expect(subject.foreign_key_exists?(:ci_sources_pipelines, :projects, column: :source_project_id, name: 'fk_acd9737679')).to be_truthy - expect(subject.foreign_key_exists?(:ci_sources_pipelines, :projects, name: 'fk_1e53c97c0a')).to be_truthy - expect(subject.foreign_key_exists?(:ci_sources_pipelines, :ci_builds, column: :source_job_id_convert_to_bigint, name: 'fk_be5624bf37_tmp')).to be_falsey - - expect(subject.index_exists_by_name?(:ci_sources_pipelines, described_class::NEW_INDEX_NAME)).to be_truthy - expect(subject.index_exists_by_name?(:ci_sources_pipelines, described_class::OLD_INDEX_NAME)).to be_falsey - end - end - - it 'existing foreign keys and indexes are untouched' do - validate_foreign_keys_and_index! - - migrate! - - validate_foreign_keys_and_index! - end - - context 'with a legacy (pre-GitLab 10.0) foreign key' do - let(:old_foreign_keys) { described_class::OLD_TO_NEW_FOREIGN_KEY_DEFS.keys } - let(:new_foreign_keys) { described_class::OLD_TO_NEW_FOREIGN_KEY_DEFS.values.map { |entry| entry[:name] } } - - before do - new_foreign_keys.each { |name| subject.remove_foreign_key_if_exists(:ci_sources_pipelines, name: name) } - - # GitLab 9.5.4: https://gitlab.com/gitlab-org/gitlab/-/blob/v9.5.4-ee/db/schema.rb#L2026-2030 - subject.add_foreign_key(:ci_sources_pipelines, :ci_builds, column: :source_job_id, name: 'fk_3f0c88d7dc', on_delete: :cascade) - subject.add_foreign_key(:ci_sources_pipelines, :ci_pipelines, column: :pipeline_id, name: "fk_b8c0fac459", on_delete: :cascade) - subject.add_foreign_key(:ci_sources_pipelines, :ci_pipelines, column: :source_pipeline_id, name: "fk_3a3e3cb83a", on_delete: :cascade) - subject.add_foreign_key(:ci_sources_pipelines, :projects, column: :source_project_id, name: "fk_8868d0f3e4", on_delete: :cascade) - subject.add_foreign_key(:ci_sources_pipelines, :projects, name: "fk_83b4346e48", on_delete: :cascade) - - # https://gitlab.com/gitlab-org/gitlab/-/blob/v9.5.4-ee/db/schema.rb#L443 - subject.add_index "ci_sources_pipelines", ["source_job_id"], name: described_class::OLD_INDEX_NAME, using: :btree - end - - context 'when new index already exists' do - it 'corrects foreign key constraints and drops old index' do - expect { migrate! }.to change { subject.foreign_key_exists?(:ci_sources_pipelines, :ci_builds, column: :source_job_id, name: 'fk_3f0c88d7dc') }.from(true).to(false) - - validate_foreign_keys_and_index! - end - end - - context 'when new index does not exist' do - before do - subject.remove_index("ci_sources_pipelines", name: described_class::NEW_INDEX_NAME) - end - - it 'drops the old index' do - expect { migrate! }.to change { subject.index_exists_by_name?(:ci_sources_pipelines, described_class::OLD_INDEX_NAME) }.from(true).to(false) - - validate_foreign_keys_and_index! - end - end - end -end diff --git a/spec/migrations/20210722042939_update_issuable_slas_where_issue_closed_spec.rb b/spec/migrations/20210722042939_update_issuable_slas_where_issue_closed_spec.rb deleted file mode 100644 index 5674efbf187..00000000000 --- a/spec/migrations/20210722042939_update_issuable_slas_where_issue_closed_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe UpdateIssuableSlasWhereIssueClosed, :migration, feature_category: :team_planning do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:issues) { table(:issues) } - let(:issuable_slas) { table(:issuable_slas) } - let(:issue_params) { { title: 'title', project_id: project.id } } - let(:issue_closed_state) { 2 } - - let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') } - let!(:project) { projects.create!(namespace_id: namespace.id) } - let!(:issue_open) { issues.create!(issue_params) } - let!(:issue_closed) { issues.create!(issue_params.merge(state_id: issue_closed_state)) } - - let!(:issuable_sla_open_issue) { issuable_slas.create!(issue_id: issue_open.id, due_at: Time.now) } - let!(:issuable_sla_closed_issue) { issuable_slas.create!(issue_id: issue_closed.id, due_at: Time.now) } - - it 'sets the issuable_closed attribute to false' do - expect(issuable_sla_open_issue.issuable_closed).to eq(false) - expect(issuable_sla_closed_issue.issuable_closed).to eq(false) - - migrate! - - expect(issuable_sla_open_issue.reload.issuable_closed).to eq(false) - expect(issuable_sla_closed_issue.reload.issuable_closed).to eq(true) - end -end diff --git a/spec/migrations/20210722150102_operations_feature_flags_correct_flexible_rollout_values_spec.rb b/spec/migrations/20210722150102_operations_feature_flags_correct_flexible_rollout_values_spec.rb deleted file mode 100644 index 098dd647b27..00000000000 --- a/spec/migrations/20210722150102_operations_feature_flags_correct_flexible_rollout_values_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe OperationsFeatureFlagsCorrectFlexibleRolloutValues, :migration, feature_category: :feature_flags do - let!(:strategies) { table(:operations_strategies) } - - let(:namespace) { table(:namespaces).create!(name: 'feature_flag', path: 'feature_flag') } - let(:project) { table(:projects).create!(namespace_id: namespace.id) } - let(:feature_flag) { table(:operations_feature_flags).create!(project_id: project.id, active: true, name: 'foo', iid: 1) } - - describe "#up" do - described_class::STICKINESS.each do |old, new| - it "corrects parameters for flexible rollout stickiness #{old}" do - reversible_migration do |migration| - parameters = { groupId: "default", rollout: "100", stickiness: old } - strategy = create_strategy(parameters) - - migration.before -> { - expect(strategy.reload.parameters).to eq({ "groupId" => "default", "rollout" => "100", "stickiness" => old }) - } - - migration.after -> { - expect(strategy.reload.parameters).to eq({ "groupId" => "default", "rollout" => "100", "stickiness" => new }) - } - end - end - end - - it 'ignores other strategies' do - reversible_migration do |migration| - parameters = { "groupId" => "default", "rollout" => "100", "stickiness" => "USERID" } - strategy = create_strategy(parameters, name: 'default') - - migration.before -> { - expect(strategy.reload.parameters).to eq(parameters) - } - - migration.after -> { - expect(strategy.reload.parameters).to eq(parameters) - } - end - end - - it 'ignores other stickiness' do - reversible_migration do |migration| - parameters = { "groupId" => "default", "rollout" => "100", "stickiness" => "FOO" } - strategy = create_strategy(parameters) - - migration.before -> { - expect(strategy.reload.parameters).to eq(parameters) - } - - migration.after -> { - expect(strategy.reload.parameters).to eq(parameters) - } - end - end - end - - def create_strategy(params, name: 'flexibleRollout') - strategies.create!(name: name, parameters: params, feature_flag_id: feature_flag.id) - end -end diff --git a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb b/spec/migrations/20210804150320_create_base_work_item_types_spec.rb deleted file mode 100644 index e7f76eb0ae0..00000000000 --- a/spec/migrations/20210804150320_create_base_work_item_types_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe CreateBaseWorkItemTypes, :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 - - # We use append_after to make sure this runs after the schema was reset to its latest state - append_after(:all) do - # Make sure base types are recreated after running the migration - # because migration specs are not run in a transaction - reset_work_item_types - end - - it 'creates default data' do - # Need to delete all as base types are seeded before entire test suite - work_item_types.delete_all - - 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 - } - - 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 diff --git a/spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb b/spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb deleted file mode 100644 index d18673db757..00000000000 --- a/spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb +++ /dev/null @@ -1,137 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe UpdateTrialPlansCiDailyPipelineScheduleTriggers, :migration, feature_category: :purchase do - let!(:plans) { table(:plans) } - let!(:plan_limits) { table(:plan_limits) } - let!(:premium_trial_plan) { plans.create!(name: 'premium_trial', title: 'Premium Trial') } - let!(:ultimate_trial_plan) { plans.create!(name: 'ultimate_trial', title: 'Ultimate Trial') } - - describe '#up' do - let!(:premium_trial_plan_limits) { plan_limits.create!(plan_id: premium_trial_plan.id, ci_daily_pipeline_schedule_triggers: 0) } - let!(:ultimate_trial_plan_limits) { plan_limits.create!(plan_id: ultimate_trial_plan.id, ci_daily_pipeline_schedule_triggers: 0) } - - context 'when the environment is dev or com' do - before do - allow(Gitlab).to receive(:com?).and_return(true) - end - - it 'sets the trial plan limits for ci_daily_pipeline_schedule_triggers' do - disable_migrations_output { migrate! } - - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - end - - it 'does not change the plan limits if the ultimate trial plan is missing' do - ultimate_trial_plan.destroy! - - expect { disable_migrations_output { migrate! } }.not_to change { plan_limits.count } - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - end - - it 'does not change the plan limits if the ultimate trial plan limits is missing' do - ultimate_trial_plan_limits.destroy! - - expect { disable_migrations_output { migrate! } }.not_to change { plan_limits.count } - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - end - - it 'does not change the plan limits if the premium trial plan is missing' do - premium_trial_plan.destroy! - - expect { disable_migrations_output { migrate! } }.not_to change { plan_limits.count } - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - end - - it 'does not change the plan limits if the premium trial plan limits is missing' do - premium_trial_plan_limits.destroy! - - expect { disable_migrations_output { migrate! } }.not_to change { plan_limits.count } - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - end - end - - context 'when the environment is anything other than dev or com' do - before do - allow(Gitlab).to receive(:com?).and_return(false) - end - - it 'does not update the plan limits' do - disable_migrations_output { migrate! } - - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - end - end - end - - describe '#down' do - let!(:premium_trial_plan_limits) { plan_limits.create!(plan_id: premium_trial_plan.id, ci_daily_pipeline_schedule_triggers: 288) } - let!(:ultimate_trial_plan_limits) { plan_limits.create!(plan_id: ultimate_trial_plan.id, ci_daily_pipeline_schedule_triggers: 288) } - - context 'when the environment is dev or com' do - before do - allow(Gitlab).to receive(:com?).and_return(true) - end - - it 'sets the trial plan limits ci_daily_pipeline_schedule_triggers to zero' do - migrate_down! - - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(0) - end - - it 'does not change the plan limits if the ultimate trial plan is missing' do - ultimate_trial_plan.destroy! - - expect { migrate_down! }.not_to change { plan_limits.count } - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - end - - it 'does not change the plan limits if the ultimate trial plan limits is missing' do - ultimate_trial_plan_limits.destroy! - - expect { migrate_down! }.not_to change { plan_limits.count } - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - end - - it 'does not change the plan limits if the premium trial plan is missing' do - premium_trial_plan.destroy! - - expect { migrate_down! }.not_to change { plan_limits.count } - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - end - - it 'does not change the plan limits if the premium trial plan limits is missing' do - premium_trial_plan_limits.destroy! - - expect { migrate_down! }.not_to change { plan_limits.count } - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - end - end - - context 'when the environment is anything other than dev or com' do - before do - allow(Gitlab).to receive(:com?).and_return(false) - end - - it 'does not change the ultimate trial plan limits' do - migrate_down! - - expect(ultimate_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - expect(premium_trial_plan_limits.reload.ci_daily_pipeline_schedule_triggers).to eq(288) - end - end - end - - def migrate_down! - disable_migrations_output do - migrate! - described_class.new.down - end - end -end diff --git a/spec/migrations/20210811122206_update_external_project_bots_spec.rb b/spec/migrations/20210811122206_update_external_project_bots_spec.rb deleted file mode 100644 index aa0bce63865..00000000000 --- a/spec/migrations/20210811122206_update_external_project_bots_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe UpdateExternalProjectBots, :migration, feature_category: :users do - def create_user(**extra_options) - defaults = { projects_limit: 0, email: "#{extra_options[:username]}@example.com" } - - table(:users).create!(defaults.merge(extra_options)) - end - - it 'sets bot users as external if were created by external users' do - internal_user = create_user(username: 'foo') - external_user = create_user(username: 'bar', external: true) - - internal_project_bot = create_user(username: 'foo2', user_type: 6, created_by_id: internal_user.id, external: false) - external_project_bot = create_user(username: 'bar2', user_type: 6, created_by_id: external_user.id, external: false) - - migrate! - - expect(table(:users).find(internal_project_bot.id).external).to eq false - expect(table(:users).find(external_project_bot.id).external).to eq true - end -end diff --git a/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb b/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb deleted file mode 100644 index fcc2e1657d0..00000000000 --- a/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration!('remove_duplicate_project_authorizations') - -RSpec.describe RemoveDuplicateProjectAuthorizations, :migration, feature_category: :authentication_and_authorization do - let(:users) { table(:users) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:project_authorizations) { table(:project_authorizations) } - - let!(:user_1) { users.create! email: 'user1@example.com', projects_limit: 0 } - let!(:user_2) { users.create! email: 'user2@example.com', projects_limit: 0 } - let!(:namespace_1) { namespaces.create! name: 'namespace 1', path: 'namespace1' } - let!(:namespace_2) { namespaces.create! name: 'namespace 2', path: 'namespace2' } - let!(:project_1) { projects.create! namespace_id: namespace_1.id } - let!(:project_2) { projects.create! namespace_id: namespace_2.id } - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 2) - end - - describe '#up' do - subject { migrate! } - - context 'User with multiple projects' do - before do - project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER - project_authorizations.create! project_id: project_2.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER - end - - it { expect { subject }.not_to change { ProjectAuthorization.count } } - end - - context 'Project with multiple users' do - before do - project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER - project_authorizations.create! project_id: project_1.id, user_id: user_2.id, access_level: Gitlab::Access::DEVELOPER - end - - it { expect { subject }.not_to change { ProjectAuthorization.count } } - end - - context 'Same project and user but different access level' do - before do - project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER - project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::MAINTAINER - project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::REPORTER - end - - it { expect { subject }.to change { ProjectAuthorization.count }.from(3).to(1) } - - it 'retains the highest access level' do - subject - - all_records = ProjectAuthorization.all.to_a - expect(all_records.count).to eq 1 - expect(all_records.first.access_level).to eq Gitlab::Access::MAINTAINER - end - end - end -end diff --git a/spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb b/spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb deleted file mode 100644 index e48f933ad5f..00000000000 --- a/spec/migrations/20210819145000_drop_temporary_columns_and_triggers_for_ci_builds_runner_session_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildsRunnerSession, :migration, feature_category: :runner do - let(:ci_builds_runner_session_table) { table(:ci_builds_runner_session) } - - it 'correctly migrates up and down' do - reversible_migration do |migration| - migration.before -> { - expect(ci_builds_runner_session_table.column_names).to include('build_id_convert_to_bigint') - } - - migration.after -> { - ci_builds_runner_session_table.reset_column_information - expect(ci_builds_runner_session_table.column_names).not_to include('build_id_convert_to_bigint') - } - 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 index a9a814f9a48..a198ae9e473 100644 --- a/spec/migrations/20210914095310_cleanup_orphan_project_access_tokens_spec.rb +++ b/spec/migrations/20210914095310_cleanup_orphan_project_access_tokens_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe CleanupOrphanProjectAccessTokens, :migration, feature_category: :users do +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" } diff --git a/spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb b/spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb index f615c8bb50e..49cf1a01f2a 100644 --- a/spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb +++ b/spec/migrations/20210922082019_drop_int4_column_for_events_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe DropInt4ColumnForEvents, feature_category: :users do +RSpec.describe DropInt4ColumnForEvents, feature_category: :user_profile do let(:events) { table(:events) } it 'correctly migrates up and down' do 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 index 5c39e7530ff..3e241438339 100644 --- 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 @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe DropInt4ColumnForPushEventPayloads, feature_category: :users do +RSpec.describe DropInt4ColumnForPushEventPayloads, feature_category: :user_profile do let(:push_event_payloads) { table(:push_event_payloads) } it 'correctly migrates up and down' do 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 a57d3633ecf..c0b94313d4d 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: :sharding do +RSpec.describe RemoveLeftoverExternalPullRequestDeletions, feature_category: :pods 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/20220329175119_remove_leftover_ci_job_artifact_deletions_spec.rb b/spec/migrations/20220329175119_remove_leftover_ci_job_artifact_deletions_spec.rb index 555856788b7..e9bca42f37f 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: :sharding do +RSpec.describe RemoveLeftoverCiJobArtifactDeletions, feature_category: :pods do let(:deleted_records) { table(:loose_foreign_keys_deleted_records) } target_table_name = Ci::JobArtifact.table_name 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 dd77ce503b8..36c65612bb9 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: :utilization do +RSpec.describe RemoveDeactivatedUserHighestRoleStats, feature_category: :subscription_cost_management do let!(:users) { table(:users) } let!(:user_highest_roles) { table(:user_highest_roles) } diff --git a/spec/migrations/20221008032350_add_password_expiration_migration_spec.rb b/spec/migrations/20221008032350_add_password_expiration_migration_spec.rb index 1663966816c..ee6c2aeca9c 100644 --- a/spec/migrations/20221008032350_add_password_expiration_migration_spec.rb +++ b/spec/migrations/20221008032350_add_password_expiration_migration_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' require_migration! -RSpec.describe AddPasswordExpirationMigration, feature_category: :users do +RSpec.describe AddPasswordExpirationMigration, feature_category: :user_profile do let(:application_setting) { table(:application_settings).create! } describe "#up" do diff --git a/spec/migrations/20221012033107_add_password_last_changed_at_to_user_details_spec.rb b/spec/migrations/20221012033107_add_password_last_changed_at_to_user_details_spec.rb index e2c508938fd..5c228381b57 100644 --- a/spec/migrations/20221012033107_add_password_last_changed_at_to_user_details_spec.rb +++ b/spec/migrations/20221012033107_add_password_last_changed_at_to_user_details_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' require_migration! -RSpec.describe AddPasswordLastChangedAtToUserDetails, feature_category: :users do +RSpec.describe AddPasswordLastChangedAtToUserDetails, feature_category: :user_profile do let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } let!(:users) { table(:users) } let!(:user) { create_user! } diff --git a/spec/migrations/20221013154159_update_invalid_dormant_user_setting_spec.rb b/spec/migrations/20221013154159_update_invalid_dormant_user_setting_spec.rb index 0686d9ca786..ad644b63060 100644 --- a/spec/migrations/20221013154159_update_invalid_dormant_user_setting_spec.rb +++ b/spec/migrations/20221013154159_update_invalid_dormant_user_setting_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe UpdateInvalidDormantUserSetting, :migration, feature_category: :users do +RSpec.describe UpdateInvalidDormantUserSetting, :migration, feature_category: :user_profile do let(:settings) { table(:application_settings) } context 'with no rows in the application_settings table' do diff --git a/spec/migrations/20221025043930_change_default_value_on_password_last_changed_at_to_user_details_spec.rb b/spec/migrations/20221025043930_change_default_value_on_password_last_changed_at_to_user_details_spec.rb index d6acf31fdc6..0e5bb419e32 100644 --- a/spec/migrations/20221025043930_change_default_value_on_password_last_changed_at_to_user_details_spec.rb +++ b/spec/migrations/20221025043930_change_default_value_on_password_last_changed_at_to_user_details_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe ChangeDefaultValueOnPasswordLastChangedAtToUserDetails, :migration, feature_category: :users do +RSpec.describe ChangeDefaultValueOnPasswordLastChangedAtToUserDetails, :migration, feature_category: :user_profile do let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } let(:users) { table(:users) } let(:user_details) { table(:user_details) } diff --git a/spec/migrations/20221028022627_add_index_on_password_last_changed_at_to_user_details_spec.rb b/spec/migrations/20221028022627_add_index_on_password_last_changed_at_to_user_details_spec.rb index 6b6fb553b1f..332b3a5abba 100644 --- a/spec/migrations/20221028022627_add_index_on_password_last_changed_at_to_user_details_spec.rb +++ b/spec/migrations/20221028022627_add_index_on_password_last_changed_at_to_user_details_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe AddIndexOnPasswordLastChangedAtToUserDetails, :migration, feature_category: :users do +RSpec.describe AddIndexOnPasswordLastChangedAtToUserDetails, :migration, feature_category: :user_profile do let(:index_name) { 'index_user_details_on_password_last_changed_at' } it 'correctly migrates up and down' do diff --git a/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb b/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb index 5a5bc42a37b..9eaab56de7c 100644 --- a/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb +++ b/spec/migrations/20221122132812_schedule_prune_stale_project_export_jobs_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe SchedulePruneStaleProjectExportJobs, category: :importers do +RSpec.describe SchedulePruneStaleProjectExportJobs, feature_category: :importers do let!(:batched_migration) { described_class::MIGRATION } it 'schedules a new batched migration' do diff --git a/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb b/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb index b76f889d743..e03fd9c9daf 100644 --- a/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb +++ b/spec/migrations/20221205151917_schedule_backfill_environment_tier_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe ScheduleBackfillEnvironmentTier, category: :continuous_delivery do +RSpec.describe ScheduleBackfillEnvironmentTier, feature_category: :continuous_delivery do let!(:batched_migration) { described_class::MIGRATION } it 'schedules a new batched migration' do diff --git a/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb b/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb index 899074399a1..d8270816afe 100644 --- a/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb +++ b/spec/migrations/20221209110934_update_import_sources_on_application_settings_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe UpdateImportSourcesOnApplicationSettings, feature_category: :migration do +RSpec.describe UpdateImportSourcesOnApplicationSettings, feature_category: :importers do let(:settings) { table(:application_settings) } let(:import_sources_with_google) { %w[google_code github git bitbucket bitbucket_server] } let(:import_sources_without_google) { %w[github git bitbucket bitbucket_server] } diff --git a/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb b/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb index e5b20b2d48a..1f276109b24 100644 --- a/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb +++ b/spec/migrations/20221209110935_fix_update_import_sources_on_application_settings_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe FixUpdateImportSourcesOnApplicationSettings, feature_category: :migration do +RSpec.describe FixUpdateImportSourcesOnApplicationSettings, feature_category: :importers do let(:settings) { table(:application_settings) } let(:import_sources) { %w[github git bitbucket bitbucket_server] } diff --git a/spec/migrations/20221219122320_copy_clickhouse_connection_string_to_encrypted_var_spec.rb b/spec/migrations/20221219122320_copy_clickhouse_connection_string_to_encrypted_var_spec.rb new file mode 100644 index 00000000000..7ff033ab0c2 --- /dev/null +++ b/spec/migrations/20221219122320_copy_clickhouse_connection_string_to_encrypted_var_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe CopyClickhouseConnectionStringToEncryptedVar, feature_category: :product_analytics do + let!(:migration) { described_class.new } + let(:setting) { table(:application_settings).create!(clickhouse_connection_string: 'https://example.com/test') } + + it 'copies the clickhouse_connection_string to the encrypted column' do + expect(setting.clickhouse_connection_string).to eq('https://example.com/test') + + migrate! + + setting.reload + expect(setting.clickhouse_connection_string).to eq('https://example.com/test') + expect(setting.encrypted_product_analytics_clickhouse_connection_string).not_to be_nil + end +end diff --git a/spec/migrations/20221226153252_queue_fix_incoherent_packages_size_on_project_statistics_spec.rb b/spec/migrations/20221226153252_queue_fix_incoherent_packages_size_on_project_statistics_spec.rb new file mode 100644 index 00000000000..b375546b90e --- /dev/null +++ b/spec/migrations/20221226153252_queue_fix_incoherent_packages_size_on_project_statistics_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe QueueFixIncoherentPackagesSizeOnProjectStatistics, feature_category: :package_registry do + let(:batched_migration) { described_class::MIGRATION } + + context 'with no packages' do + it 'does not schedule a new batched migration' do + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + end + end + end + + context 'with some packages' do + before do + namespace = table(:namespaces) + .create!(name: 'project', path: 'project', type: 'Project') + project = table(:projects).create!( + name: 'project', + path: 'project', + project_namespace_id: namespace.id, + namespace_id: namespace.id + ) + table(:packages_packages) + .create!(name: 'test', version: '1.2.3', package_type: 2, project_id: project.id) + end + + it 'schedules a new batched migration' do + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).to have_scheduled_batched_migration( + table_name: :project_statistics, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE + ) + } + end + end + end +end diff --git a/spec/migrations/20230117114739_clear_duplicate_jobs_cookies_spec.rb b/spec/migrations/20230117114739_clear_duplicate_jobs_cookies_spec.rb new file mode 100644 index 00000000000..5c572b49d3d --- /dev/null +++ b/spec/migrations/20230117114739_clear_duplicate_jobs_cookies_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ClearDuplicateJobsCookies, :migration, feature_category: :redis do + def with_redis(&block) + Gitlab::Redis::Queues.with(&block) + end + + it 'deletes duplicate jobs cookies' do + delete = ['resque:gitlab:duplicate:blabla:1:cookie:v2', 'resque:gitlab:duplicate:foobar:2:cookie:v2'] + keep = ['resque:gitlab:duplicate:something', 'something:cookie:v2'] + with_redis { |r| (delete + keep).each { |key| r.set(key, 'value') } } + + expect(with_redis { |r| r.exists(delete + keep) }).to eq(4) + + migrate! + + expect(with_redis { |r| r.exists(delete) }).to eq(0) + expect(with_redis { |r| r.exists(keep) }).to eq(2) + end +end diff --git a/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb b/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb new file mode 100644 index 00000000000..3ccd92e15a4 --- /dev/null +++ b/spec/migrations/20230125093723_rebalance_partition_id_ci_pipeline_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RebalancePartitionIdCiPipeline, migration: :gitlab_ci, feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on sass' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of ci_builds' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_pipelines, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb b/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb new file mode 100644 index 00000000000..b983564a2d9 --- /dev/null +++ b/spec/migrations/20230125093840_rebalance_partition_id_ci_build_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RebalancePartitionIdCiBuild, migration: :gitlab_ci, feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on sass' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of ci_builds' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_builds, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230130073109_nullify_creator_id_of_orphaned_projects_spec.rb b/spec/migrations/20230130073109_nullify_creator_id_of_orphaned_projects_spec.rb new file mode 100644 index 00000000000..9d4d50fab54 --- /dev/null +++ b/spec/migrations/20230130073109_nullify_creator_id_of_orphaned_projects_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe NullifyCreatorIdOfOrphanedProjects, feature_category: :projects do + let!(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background migration' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :projects, + column_name: :id, + interval: described_class::INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it '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/20230131125844_add_project_id_name_id_version_index_to_installable_npm_packages_spec.rb b/spec/migrations/20230131125844_add_project_id_name_id_version_index_to_installable_npm_packages_spec.rb new file mode 100644 index 00000000000..5d8c7ab4745 --- /dev/null +++ b/spec/migrations/20230131125844_add_project_id_name_id_version_index_to_installable_npm_packages_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe AddProjectIdNameIdVersionIndexToInstallableNpmPackages, feature_category: :package_registry do + it 'schedules an index creation' do + reversible_migration do |migration| + migration.before -> { + expect(ActiveRecord::Base.connection.indexes('packages_packages').map(&:name)) + .not_to include('idx_packages_on_project_id_name_id_version_when_installable_npm') + } + + migration.after -> { + expect(ActiveRecord::Base.connection.indexes('packages_packages').map(&:name)) + .to include('idx_packages_on_project_id_name_id_version_when_installable_npm') + } + end + 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 new file mode 100644 index 00000000000..3fc9c7d8af7 --- /dev/null +++ b/spec/migrations/20230201171450_finalize_backfill_environment_tier_migration_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FinalizeBackfillEnvironmentTierMigration, :migration, feature_category: :continuous_delivery 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('BackfillEnvironmentTiers', :environments, :id, []) + 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!(:group_member_namespace_id_backfill) do + batched_migrations.create!( + job_class_name: 'BackfillEnvironmentTiers', + table_name: :environments, + column_name: :id, + job_arguments: [], + interval: 2.minutes, + min_value: 1, + max_value: 2, + batch_size: 1000, + sub_batch_size: 200, + gitlab_schema: :gitlab_main, + status: 3 # finished + ) + end + + context 'when migration finished successfully' do + it 'does not raise exception' do + expect { migrate! }.not_to raise_error + end + end + + context 'with different migration statuses' do + using RSpec::Parameterized::TableSyntax + + where(:status, :description) do + 0 | 'paused' + 1 | 'active' + 4 | 'failed' + 5 | 'finalizing' + end + + with_them do + before do + group_member_namespace_id_backfill.update!(status: status) + end + + it_behaves_like 'finalizes the migration' + end + end + end + end +end diff --git a/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb b/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb new file mode 100644 index 00000000000..a8896e7d3cf --- /dev/null +++ b/spec/migrations/20230202131928_encrypt_ci_trigger_token_spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe EncryptCiTriggerToken, migration: :gitlab_ci, feature_category: :continuous_integration 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('EncryptCiTriggerToken', :ci_triggers, :id, []) + end + end + end + + context 'with migration present' do + let!(:ci_trigger_token_encryption_migration) do + batched_migrations.create!( + job_class_name: 'EncryptCiTriggerToken', + table_name: :ci_triggers, + column_name: :token, + job_arguments: [], + interval: 2.minutes, + min_value: 1, + max_value: 2, + batch_size: 1000, + sub_batch_size: 100, + gitlab_schema: :gitlab_ci, + status: 3 # finished + ) + end + + context 'when migration finished successfully' do + it 'does not raise exception' do + expect { migrate! }.not_to raise_error + end + + it 'schedules background jobs for each batch of ci_triggers' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_triggers, + column_name: :token, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + 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 + + 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/20230203122602_schedule_vulnerabilities_feedback_migration4_spec.rb b/spec/migrations/20230203122602_schedule_vulnerabilities_feedback_migration4_spec.rb new file mode 100644 index 00000000000..26c63e6deb2 --- /dev/null +++ b/spec/migrations/20230203122602_schedule_vulnerabilities_feedback_migration4_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleVulnerabilitiesFeedbackMigration4, feature_category: :vulnerability_management do + let(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background jobs for each batch of Vulnerabilities::Feedback' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :vulnerability_feedback, + column_name: :id, + interval: described_class::JOB_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/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb b/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb new file mode 100644 index 00000000000..fb0e1fe17ec --- /dev/null +++ b/spec/migrations/20230208100917_fix_partition_ids_for_ci_pipeline_variable_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsForCiPipelineVariable, migration: :gitlab_ci, feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on saas' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of ci_pipeline_variables' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_pipeline_variables, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb b/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb new file mode 100644 index 00000000000..de2386c6a0d --- /dev/null +++ b/spec/migrations/20230208103009_fix_partition_ids_for_ci_job_artifact_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsForCiJobArtifact, migration: :gitlab_ci, feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on saas' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of ci_job_artifacts' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_job_artifacts, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb b/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb new file mode 100644 index 00000000000..8b057afc1e9 --- /dev/null +++ b/spec/migrations/20230208132608_fix_partition_ids_for_ci_stage_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsForCiStage, migration: :gitlab_ci, feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on saas' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of ci_stages' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_stages, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb b/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb new file mode 100644 index 00000000000..f0ac8239f58 --- /dev/null +++ b/spec/migrations/20230209090702_fix_partition_ids_for_ci_build_report_result_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsForCiBuildReportResult, + migration: :gitlab_ci, + feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on saas' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of ci_build_report_results' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_build_report_results, + column_name: :build_id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb b/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb new file mode 100644 index 00000000000..a93ba36d9ae --- /dev/null +++ b/spec/migrations/20230209092204_fix_partition_ids_for_ci_build_trace_metadata_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsForCiBuildTraceMetadata, + migration: :gitlab_ci, + feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on saas' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of ci_build_trace_metadata' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :ci_build_trace_metadata, + column_name: :build_id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb b/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb new file mode 100644 index 00000000000..c354d68749f --- /dev/null +++ b/spec/migrations/20230209140102_fix_partition_ids_for_ci_build_metadata_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsForCiBuildMetadata, + migration: :gitlab_ci, + feature_category: :continuous_integration do + let(:migration) { described_class::MIGRATION } + + context 'when on saas' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of p_ci_builds_metadata' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_ci, + table_name: :p_ci_builds_metadata, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end + end + + context 'when on self-managed instance' do + let(:migration) { described_class.new } + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb b/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb new file mode 100644 index 00000000000..64275855262 --- /dev/null +++ b/spec/migrations/20230214122717_fix_partition_ids_for_ci_job_variables_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsForCiJobVariables, migration: :gitlab_ci, feature_category: :continuous_integration do + let(:builds) { table(:ci_builds, database: :ci) } + let(:job_variables) { table(:ci_job_variables, database: :ci) } + let(:connection) { job_variables.connection } + + around do |example| + connection.execute "ALTER TABLE #{job_variables.quoted_table_name} DISABLE TRIGGER ALL;" + + example.run + ensure + connection.execute "ALTER TABLE #{job_variables.quoted_table_name} ENABLE TRIGGER ALL;" + end + + before do + job = builds.create!(partition_id: 100) + + job_variables.insert_all!([ + { job_id: job.id, partition_id: 100, key: 'variable-100' }, + { job_id: job.id, partition_id: 101, key: 'variable-101' } + ]) + end + + describe '#up', :aggregate_failures do + context 'when on sass' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + it 'fixes partition_id' do + expect { migrate! }.not_to raise_error + + expect(job_variables.where(partition_id: 100).count).to eq(2) + expect(job_variables.where(partition_id: 101).count).to eq(0) + end + end + + context 'when on self managed' do + it 'does not change partition_id' do + expect { migrate! }.not_to raise_error + + expect(job_variables.where(partition_id: 100).count).to eq(1) + expect(job_variables.where(partition_id: 101).count).to eq(1) + end + end + end +end diff --git a/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb b/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb new file mode 100644 index 00000000000..44031175497 --- /dev/null +++ b/spec/migrations/20230214154101_fix_partition_ids_on_ci_sources_pipelines_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe FixPartitionIdsOnCiSourcesPipelines, migration: :gitlab_ci, feature_category: :continuous_integration do + let(:sources_pipelines) { table(:ci_sources_pipelines, database: :ci) } + + before do + sources_pipelines.insert_all!([ + { partition_id: 100, source_partition_id: 100 }, + { partition_id: 100, source_partition_id: 101 }, + { partition_id: 101, source_partition_id: 100 }, + { partition_id: 101, source_partition_id: 101 } + ]) + end + + describe '#up' do + context 'when on sass' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + it 'fixes partition_id and source_partition_id' do + expect { migrate! }.not_to raise_error + + expect(sources_pipelines.where(partition_id: 100).count).to eq(4) + expect(sources_pipelines.where(partition_id: 101).count).to eq(0) + expect(sources_pipelines.where(source_partition_id: 100).count).to eq(4) + expect(sources_pipelines.where(source_partition_id: 101).count).to eq(0) + end + end + + context 'when on self managed' do + it 'does not change partition_id or source_partition_id' do + expect { migrate! }.not_to raise_error + + expect(sources_pipelines.where(partition_id: 100).count).to eq(2) + expect(sources_pipelines.where(partition_id: 100).count).to eq(2) + expect(sources_pipelines.where(source_partition_id: 101).count).to eq(2) + expect(sources_pipelines.where(source_partition_id: 101).count).to eq(2) + end + end + end +end diff --git a/spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb b/spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb deleted file mode 100644 index a6c892db131..00000000000 --- a/spec/migrations/add_default_project_approval_rules_vuln_allowed_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AddDefaultProjectApprovalRulesVulnAllowed, feature_category: :source_code_management do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') } - let(:project) { projects.create!(name: 'project', path: 'project', namespace_id: namespace.id) } - let(:approval_project_rules) { table(:approval_project_rules) } - - it 'updates records when vulnerabilities_allowed is nil' do - records_to_migrate = 10 - - records_to_migrate.times do |i| - approval_project_rules.create!(name: "rule #{i}", project_id: project.id) - end - - expect { migrate! } - .to change { approval_project_rules.where(vulnerabilities_allowed: nil).count } - .from(records_to_migrate) - .to(0) - end - - it 'defaults vulnerabilities_allowed to 0' do - approval_project_rule = approval_project_rules.create!(name: "new rule", project_id: project.id) - - expect(approval_project_rule.vulnerabilities_allowed).to be_nil - - migrate! - - expect(approval_project_rule.reload.vulnerabilities_allowed).to eq(0) - end -end diff --git a/spec/migrations/add_namespaces_emails_enabled_column_data_spec.rb b/spec/migrations/add_namespaces_emails_enabled_column_data_spec.rb new file mode 100644 index 00000000000..6cab3ca3d8f --- /dev/null +++ b/spec/migrations/add_namespaces_emails_enabled_column_data_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'rake_helper' +require_migration! + +RSpec.describe AddNamespacesEmailsEnabledColumnData, :migration, feature_category: :database do + before :all do + Rake.application.rake_require 'active_record/railties/databases' + Rake.application.rake_require 'tasks/gitlab/db' + + # empty task as env is already loaded + Rake::Task.define_task :environment + end + + let(:migration) { described_class::MIGRATION } + let(:projects) { table(:projects) } + let(:namespace_settings_table) { table(:namespace_settings) } + let(:namespaces) { table(:namespaces) } + + before do + stub_const("#{described_class.name}::SUB_BATCH_SIZE", 2) + end + + it 'schedules background migrations', :aggregate_failures do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :namespaces, + column_name: :id, + interval: described_class::DELAY_INTERVAL + ) + 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 + + it 'sets emails_enabled to be the opposite of emails_disabled' do + disabled_records_to_migrate = 6 + enabled_records_to_migrate = 4 + + disabled_records_to_migrate.times do |i| + namespace = namespaces.create!(name: 'namespace', + path: "namespace#{i}", + emails_disabled: true) + namespace_settings_table.create!(namespace_id: namespace.id) + end + + enabled_records_to_migrate.times do |i| + namespace = namespaces.create!(name: 'namespace', + path: "namespace#{i}", + emails_disabled: false) + namespace_settings_table.create!(namespace_id: namespace.id) + end + + migrate! + run_rake_task('gitlab:db:execute_batched_migrations') + # rubocop: disable CodeReuse/ActiveRecord + expect(namespace_settings_table.where(emails_enabled: true).count).to eq(enabled_records_to_migrate) + expect(namespace_settings_table.where(emails_enabled: false).count).to eq(disabled_records_to_migrate) + # rubocop: enable CodeReuse/ActiveRecord + end +end diff --git a/spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb b/spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb deleted file mode 100644 index 670541128a0..00000000000 --- a/spec/migrations/add_premium_and_ultimate_plan_limits_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe AddPremiumAndUltimatePlanLimits, :migration, feature_category: :purchase do - shared_examples_for 'a migration that does not alter plans or plan limits' do - it do - expect { migrate! }.not_to change { - [ - AddPremiumAndUltimatePlanLimits::Plan.count, - AddPremiumAndUltimatePlanLimits::PlanLimits.count - ] - } - end - end - - describe '#up' do - context 'when not .com?' do - before do - allow(Gitlab).to receive(:com?).and_return false - end - - it_behaves_like 'a migration that does not alter plans or plan limits' - end - - context 'when .com?' do - before do - allow(Gitlab).to receive(:com?).and_return true - end - - context 'when source plan does not exist' do - it_behaves_like 'a migration that does not alter plans or plan limits' - end - - context 'when target plan does not exist' do - before do - table(:plans).create!(name: 'silver', title: 'Silver') - table(:plans).create!(name: 'gold', title: 'Gold') - end - - it_behaves_like 'a migration that does not alter plans or plan limits' - end - - context 'when source and target plans exist' do - let!(:silver) { table(:plans).create!(name: 'silver', title: 'Silver') } - let!(:gold) { table(:plans).create!(name: 'gold', title: 'Gold') } - let!(:premium) { table(:plans).create!(name: 'premium', title: 'Premium') } - let!(:ultimate) { table(:plans).create!(name: 'ultimate', title: 'Ultimate') } - - let!(:silver_limits) { table(:plan_limits).create!(plan_id: silver.id, storage_size_limit: 111) } - let!(:gold_limits) { table(:plan_limits).create!(plan_id: gold.id, storage_size_limit: 222) } - - context 'when target has plan limits' do - before do - table(:plan_limits).create!(plan_id: premium.id, storage_size_limit: 999) - table(:plan_limits).create!(plan_id: ultimate.id, storage_size_limit: 999) - end - - it 'does not overwrite the limits' do - expect { migrate! }.not_to change { - [ - AddPremiumAndUltimatePlanLimits::Plan.count, - AddPremiumAndUltimatePlanLimits::PlanLimits.pluck(:id, :storage_size_limit).sort - ] - } - end - end - - context 'when target has no plan limits' do - it 'creates plan limits from the source plan' do - migrate! - - expect(AddPremiumAndUltimatePlanLimits::PlanLimits.pluck(:plan_id, :storage_size_limit)) - .to match_array( - [ - [silver.id, silver_limits.storage_size_limit], - [gold.id, gold_limits.storage_size_limit], - [premium.id, silver_limits.storage_size_limit], - [ultimate.id, gold_limits.storage_size_limit] - ]) - end - end - end - end - end -end diff --git a/spec/migrations/add_projects_emails_enabled_column_data_spec.rb b/spec/migrations/add_projects_emails_enabled_column_data_spec.rb new file mode 100644 index 00000000000..1d021ecd439 --- /dev/null +++ b/spec/migrations/add_projects_emails_enabled_column_data_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'rake_helper' +require_migration! + +RSpec.describe AddProjectsEmailsEnabledColumnData, :migration, feature_category: :database do + before :all do + Rake.application.rake_require 'active_record/railties/databases' + Rake.application.rake_require 'tasks/gitlab/db' + + # empty task as env is already loaded + Rake::Task.define_task :environment + end + + let(:migration) { described_class::MIGRATION } + let(:project_settings) { table(:project_settings) } + let(:projects) { table(:projects) } + let(:namespaces) { table(:namespaces) } + + before do + stub_const("#{described_class.name}::SUB_BATCH_SIZE", 2) + end + + it 'schedules background migrations', :aggregate_failures do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :projects, + column_name: :id, + interval: described_class::DELAY_INTERVAL + ) + 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 + + it 'sets emails_enabled to be the opposite of emails_disabled' do + disabled_records_to_migrate = 4 + enabled_records_to_migrate = 2 + + disabled_records_to_migrate.times do |i| + namespace = namespaces.create!(name: 'namespace', path: "namespace#{i}") + project = projects.create!(name: "Project Disabled #{i}", + path: "projectDisabled#{i}", + namespace_id: namespace.id, + project_namespace_id: namespace.id, + emails_disabled: true) + project_settings.create!(project_id: project.id) + end + + enabled_records_to_migrate.times do |i| + namespace = namespaces.create!(name: 'namespace', path: "namespace#{i}") + project = projects.create!(name: "Project Enabled #{i}", + path: "projectEnabled#{i}", + namespace_id: namespace.id, + project_namespace_id: namespace.id, + emails_disabled: false) + project_settings.create!(project_id: project.id) + end + + migrate! + run_rake_task('gitlab:db:execute_batched_migrations') + # rubocop: disable CodeReuse/ActiveRecord + expect(project_settings.where(emails_enabled: true).count).to eq(enabled_records_to_migrate) + expect(project_settings.where(emails_enabled: false).count).to eq(disabled_records_to_migrate) + # rubocop: enable CodeReuse/ActiveRecord + end +end diff --git a/spec/migrations/add_triggers_to_integrations_type_new_spec.rb b/spec/migrations/add_triggers_to_integrations_type_new_spec.rb deleted file mode 100644 index 4fa5fe31d2b..00000000000 --- a/spec/migrations/add_triggers_to_integrations_type_new_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe AddTriggersToIntegrationsTypeNew, feature_category: :purchase do - let(:migration) { described_class.new } - let(:integrations) { table(:integrations) } - - # This matches Gitlab::Integrations::StiType at the time the trigger was added - let(:namespaced_integrations) do - %w[ - Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog - Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost - MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker - Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack - - Github GitlabSlackApplication - ] - end - - describe '#up' do - before do - migrate! - end - - describe 'INSERT trigger' do - it 'sets `type_new` to the transformed `type` class name' do - namespaced_integrations.each do |type| - integration = integrations.create!(type: "#{type}Service") - - expect(integration.reload).to have_attributes( - type: "#{type}Service", - type_new: "Integrations::#{type}" - ) - end - end - - it 'ignores types that are not namespaced' do - # We don't actually have any integrations without namespaces, - # but we can abuse one of the integration base classes. - integration = integrations.create!(type: 'BaseIssueTracker') - - expect(integration.reload).to have_attributes( - type: 'BaseIssueTracker', - type_new: nil - ) - end - - it 'ignores types that are unknown' do - integration = integrations.create!(type: 'FooBar') - - expect(integration.reload).to have_attributes( - type: 'FooBar', - type_new: nil - ) - end - end - end - - describe '#down' do - before do - migration.up - migration.down - end - - it 'drops the INSERT trigger' do - integration = integrations.create!(type: 'JiraService') - - expect(integration.reload).to have_attributes( - type: 'JiraService', - type_new: nil - ) - end - end -end diff --git a/spec/migrations/add_upvotes_count_index_to_issues_spec.rb b/spec/migrations/add_upvotes_count_index_to_issues_spec.rb deleted file mode 100644 index 0012b8a0b96..00000000000 --- a/spec/migrations/add_upvotes_count_index_to_issues_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AddUpvotesCountIndexToIssues, feature_category: :team_planning do - let(:migration_instance) { described_class.new } - - describe '#up' do - it 'adds index' do - expect { migrate! }.to change { migration_instance.index_exists?(:issues, [:project_id, :upvotes_count], name: described_class::INDEX_NAME) }.from(false).to(true) - end - end - - describe '#down' do - it 'removes index' do - migrate! - - expect { schema_migrate_down! }.to change { migration_instance.index_exists?(:issues, [:project_id, :upvotes_count], name: described_class::INDEX_NAME) }.from(true).to(false) - end - end -end diff --git a/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb b/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb deleted file mode 100644 index 67d215c781b..00000000000 --- a/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe AssociateExistingDastBuildsWithVariables, feature_category: :dynamic_application_security_testing do - it 'is a no-op' do - migrate! - end -end diff --git a/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb b/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb deleted file mode 100644 index a9500b9f942..00000000000 --- a/spec/migrations/backfill_cadence_id_for_boards_scoped_to_iteration_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe BackfillCadenceIdForBoardsScopedToIteration, :migration, feature_category: :team_planning do - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - let(:iterations_cadences) { table(:iterations_cadences) } - let(:boards) { table(:boards) } - - let!(:group) { namespaces.create!(name: 'group1', path: 'group1', type: 'Group') } - let!(:cadence) { iterations_cadences.create!(title: 'group cadence', group_id: group.id, start_date: Time.current) } - let!(:project) { projects.create!(name: 'gitlab1', path: 'gitlab1', namespace_id: group.id, visibility_level: 0) } - let!(:project_board1) { boards.create!(name: 'Project Dev1', project_id: project.id) } - let!(:project_board2) { boards.create!(name: 'Project Dev2', project_id: project.id, iteration_id: -4) } - let!(:project_board3) { boards.create!(name: 'Project Dev3', project_id: project.id, iteration_id: -4) } - let!(:project_board4) { boards.create!(name: 'Project Dev4', project_id: project.id, iteration_id: -4) } - - let!(:group_board1) { boards.create!(name: 'Group Dev1', group_id: group.id) } - let!(:group_board2) { boards.create!(name: 'Group Dev2', group_id: group.id, iteration_id: -4) } - let!(:group_board3) { boards.create!(name: 'Group Dev3', group_id: group.id, iteration_id: -4) } - let!(:group_board4) { boards.create!(name: 'Group Dev4', group_id: group.id, iteration_id: -4) } - - describe '#up' do - it 'schedules background migrations' do - Sidekiq::Testing.fake! do - freeze_time do - described_class.new.up - - migration = described_class::MIGRATION - - expect(migration).to be_scheduled_delayed_migration(2.minutes, 'group', 'up', group_board2.id, group_board4.id) - expect(migration).to be_scheduled_delayed_migration(2.minutes, 'project', 'up', project_board2.id, project_board4.id) - expect(BackgroundMigrationWorker.jobs.size).to eq 2 - end - end - end - - context 'in batches' do - before do - stub_const('BackfillCadenceIdForBoardsScopedToIteration::BATCH_SIZE', 2) - end - - it 'schedules background migrations' do - Sidekiq::Testing.fake! do - freeze_time do - described_class.new.up - - migration = described_class::MIGRATION - - expect(migration).to be_scheduled_delayed_migration(2.minutes, 'group', 'up', group_board2.id, group_board3.id) - expect(migration).to be_scheduled_delayed_migration(4.minutes, 'group', 'up', group_board4.id, group_board4.id) - expect(migration).to be_scheduled_delayed_migration(2.minutes, 'project', 'up', project_board2.id, project_board3.id) - expect(migration).to be_scheduled_delayed_migration(4.minutes, 'project', 'up', project_board4.id, project_board4.id) - expect(BackgroundMigrationWorker.jobs.size).to eq 4 - end - end - end - end - end - - describe '#down' do - let!(:project_board1) { boards.create!(name: 'Project Dev1', project_id: project.id) } - let!(:project_board2) { boards.create!(name: 'Project Dev2', project_id: project.id, iteration_cadence_id: cadence.id) } - let!(:project_board3) { boards.create!(name: 'Project Dev3', project_id: project.id, iteration_id: -4, iteration_cadence_id: cadence.id) } - let!(:project_board4) { boards.create!(name: 'Project Dev4', project_id: project.id, iteration_id: -4, iteration_cadence_id: cadence.id) } - - let!(:group_board1) { boards.create!(name: 'Group Dev1', group_id: group.id) } - let!(:group_board2) { boards.create!(name: 'Group Dev2', group_id: group.id, iteration_cadence_id: cadence.id) } - let!(:group_board3) { boards.create!(name: 'Group Dev3', group_id: group.id, iteration_id: -4, iteration_cadence_id: cadence.id) } - let!(:group_board4) { boards.create!(name: 'Group Dev4', group_id: group.id, iteration_id: -4, iteration_cadence_id: cadence.id) } - - it 'schedules background migrations' do - Sidekiq::Testing.fake! do - freeze_time do - described_class.new.down - - migration = described_class::MIGRATION - - expect(migration).to be_scheduled_delayed_migration(2.minutes, 'none', 'down', project_board2.id, group_board4.id) - expect(BackgroundMigrationWorker.jobs.size).to eq 1 - end - end - end - - context 'in batches' do - before do - stub_const('BackfillCadenceIdForBoardsScopedToIteration::BATCH_SIZE', 2) - end - - it 'schedules background migrations' do - Sidekiq::Testing.fake! do - freeze_time do - described_class.new.down - - migration = described_class::MIGRATION - - expect(migration).to be_scheduled_delayed_migration(2.minutes, 'none', 'down', project_board2.id, project_board3.id) - expect(migration).to be_scheduled_delayed_migration(4.minutes, 'none', 'down', project_board4.id, group_board2.id) - expect(migration).to be_scheduled_delayed_migration(6.minutes, 'none', 'down', group_board3.id, group_board4.id) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 - end - end - end - end - end -end diff --git a/spec/migrations/backfill_integrations_type_new_spec.rb b/spec/migrations/backfill_integrations_type_new_spec.rb deleted file mode 100644 index 79519c4439a..00000000000 --- a/spec/migrations/backfill_integrations_type_new_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe BackfillIntegrationsTypeNew, feature_category: :integrations do - let!(:migration) { described_class::MIGRATION } - let!(:integrations) { table(:integrations) } - - before do - integrations.create!(id: 1) - integrations.create!(id: 2) - integrations.create!(id: 3) - integrations.create!(id: 4) - integrations.create!(id: 5) - end - - describe '#up' do - it 'schedules background jobs for each batch of integrations' do - migrate! - - expect(migration).to have_scheduled_batched_migration( - table_name: :integrations, - column_name: :id, - interval: described_class::INTERVAL - ) - 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_issues_upvotes_count_spec.rb b/spec/migrations/backfill_issues_upvotes_count_spec.rb deleted file mode 100644 index b8687595b35..00000000000 --- a/spec/migrations/backfill_issues_upvotes_count_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe BackfillIssuesUpvotesCount, feature_category: :team_planning do - let(:migration) { described_class.new } - let(:issues) { table(:issues) } - let(:award_emoji) { table(:award_emoji) } - - let!(:issue1) { issues.create! } - let!(:issue2) { issues.create! } - let!(:issue3) { issues.create! } - let!(:issue4) { issues.create! } - let!(:issue4_without_thumbsup) { issues.create! } - - let!(:award_emoji1) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue1.id) } - let!(:award_emoji2) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue2.id) } - let!(:award_emoji3) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue3.id) } - let!(:award_emoji4) { award_emoji.create!( name: 'thumbsup', awardable_type: 'Issue', awardable_id: issue4.id) } - - it 'correctly schedules background migrations', :aggregate_failures do - stub_const("#{described_class.name}::BATCH_SIZE", 2) - - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(described_class::MIGRATION).to be_scheduled_migration(issue1.id, issue2.id) - expect(described_class::MIGRATION).to be_scheduled_migration(issue3.id, issue4.id) - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - end - end - end -end diff --git a/spec/migrations/backfill_stage_event_hash_spec.rb b/spec/migrations/backfill_stage_event_hash_spec.rb deleted file mode 100644 index 399a9c4dfde..00000000000 --- a/spec/migrations/backfill_stage_event_hash_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe BackfillStageEventHash, schema: 20210730103808, feature_category: :value_stream_management do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:labels) { table(:labels) } - let(:group_stages) { table(:analytics_cycle_analytics_group_stages) } - let(:project_stages) { table(:analytics_cycle_analytics_project_stages) } - let(:group_value_streams) { table(:analytics_cycle_analytics_group_value_streams) } - let(:project_value_streams) { table(:analytics_cycle_analytics_project_value_streams) } - let(:stage_event_hashes) { table(:analytics_cycle_analytics_stage_event_hashes) } - - let(:issue_created) { 1 } - let(:issue_closed) { 3 } - let(:issue_label_removed) { 9 } - let(:unknown_stage_event) { -1 } - - let(:namespace) { namespaces.create!(name: 'ns', path: 'ns', type: 'Group') } - let(:project) { projects.create!(name: 'project', path: 'project', namespace_id: namespace.id) } - let(:group_label) { labels.create!(title: 'label', type: 'GroupLabel', group_id: namespace.id) } - let(:group_value_stream) { group_value_streams.create!(name: 'group vs', group_id: namespace.id) } - let(:project_value_stream) { project_value_streams.create!(name: 'project vs', project_id: project.id) } - - let(:group_stage_1) do - group_stages.create!( - name: 'stage 1', - group_id: namespace.id, - start_event_identifier: issue_created, - end_event_identifier: issue_closed, - group_value_stream_id: group_value_stream.id - ) - end - - let(:group_stage_2) do - group_stages.create!( - name: 'stage 2', - group_id: namespace.id, - start_event_identifier: issue_created, - end_event_identifier: issue_label_removed, - end_event_label_id: group_label.id, - group_value_stream_id: group_value_stream.id - ) - end - - let(:project_stage_1) do - project_stages.create!( - name: 'stage 1', - project_id: project.id, - start_event_identifier: issue_created, - end_event_identifier: issue_closed, - project_value_stream_id: project_value_stream.id - ) - end - - let(:invalid_group_stage) do - group_stages.create!( - name: 'stage 3', - group_id: namespace.id, - start_event_identifier: issue_created, - end_event_identifier: unknown_stage_event, - group_value_stream_id: group_value_stream.id - ) - end - - describe '#up' do - it 'populates stage_event_hash_id column' do - group_stage_1 - group_stage_2 - project_stage_1 - - migrate! - - group_stage_1.reload - group_stage_2.reload - project_stage_1.reload - - expect(group_stage_1.stage_event_hash_id).not_to be_nil - expect(group_stage_2.stage_event_hash_id).not_to be_nil - expect(project_stage_1.stage_event_hash_id).not_to be_nil - - expect(stage_event_hashes.count).to eq(2) # group_stage_1 and project_stage_1 has the same hash - end - - it 'runs without problem without stages' do - expect { migrate! }.not_to raise_error - end - - context 'when invalid event identifier is discovered' do - it 'removes the stage' do - group_stage_1 - invalid_group_stage - - expect { migrate! }.not_to change { group_stage_1 } - - expect(group_stages.find_by_id(invalid_group_stage.id)).to eq(nil) - end - end - end -end diff --git a/spec/migrations/cleanup_after_fixing_issue_when_admin_changed_primary_email_spec.rb b/spec/migrations/cleanup_after_fixing_issue_when_admin_changed_primary_email_spec.rb index e8dce46bdbc..7c9d2e3170a 100644 --- a/spec/migrations/cleanup_after_fixing_issue_when_admin_changed_primary_email_spec.rb +++ b/spec/migrations/cleanup_after_fixing_issue_when_admin_changed_primary_email_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe CleanupAfterFixingIssueWhenAdminChangedPrimaryEmail, :sidekiq, feature_category: :users do +RSpec.describe CleanupAfterFixingIssueWhenAdminChangedPrimaryEmail, :sidekiq, feature_category: :user_profile do let(:migration) { described_class.new } let(:users) { table(:users) } let(:emails) { table(:emails) } diff --git a/spec/migrations/cleanup_after_fixing_regression_with_new_users_emails_spec.rb b/spec/migrations/cleanup_after_fixing_regression_with_new_users_emails_spec.rb index 01ceef9f3a1..ce7be6aed73 100644 --- a/spec/migrations/cleanup_after_fixing_regression_with_new_users_emails_spec.rb +++ b/spec/migrations/cleanup_after_fixing_regression_with_new_users_emails_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe CleanupAfterFixingRegressionWithNewUsersEmails, :sidekiq, feature_category: :users do +RSpec.describe CleanupAfterFixingRegressionWithNewUsersEmails, :sidekiq, feature_category: :user_profile do let(:migration) { described_class.new } let(:users) { table(:users) } let(:emails) { table(:emails) } diff --git a/spec/migrations/cleanup_remaining_orphan_invites_spec.rb b/spec/migrations/cleanup_remaining_orphan_invites_spec.rb deleted file mode 100644 index 598030c99a0..00000000000 --- a/spec/migrations/cleanup_remaining_orphan_invites_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe CleanupRemainingOrphanInvites, :migration, feature_category: :subgroups do - def create_member(**extra_attributes) - defaults = { - access_level: 10, - source_id: 1, - source_type: "Project", - notification_level: 0, - type: 'ProjectMember' - } - - table(:members).create!(defaults.merge(extra_attributes)) - end - - def create_user(**extra_attributes) - defaults = { projects_limit: 0 } - table(:users).create!(defaults.merge(extra_attributes)) - end - - describe '#up', :aggregate_failures do - it 'removes invite tokens for accepted records' do - record1 = create_member(invite_token: 'foo', user_id: nil) - record2 = create_member(invite_token: 'foo2', user_id: create_user(username: 'foo', email: 'foo@example.com').id) - record3 = create_member(invite_token: nil, user_id: create_user(username: 'bar', email: 'bar@example.com').id) - - migrate! - - expect(table(:members).find(record1.id).invite_token).to eq 'foo' - expect(table(:members).find(record2.id).invite_token).to eq nil - expect(table(:members).find(record3.id).invite_token).to eq nil - end - end -end diff --git a/spec/migrations/confirm_security_bot_spec.rb b/spec/migrations/confirm_security_bot_spec.rb deleted file mode 100644 index 3761c113692..00000000000 --- a/spec/migrations/confirm_security_bot_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ConfirmSecurityBot, :migration, feature_category: :users do - let(:users) { table(:users) } - - let(:user_type) { 8 } - - context 'when bot is not created' do - it 'skips migration' do - migrate! - - bot = users.find_by(user_type: user_type) - - expect(bot).to be_nil - end - end - - context 'when bot is confirmed' do - let(:bot) { table(:users).create!(user_type: user_type, confirmed_at: Time.current, projects_limit: 1) } - - it 'skips migration' do - expect { migrate! }.not_to change { bot.reload.confirmed_at } - end - end - - context 'when bot is not confirmed' do - let(:bot) { table(:users).create!(user_type: user_type, projects_limit: 1) } - - it 'update confirmed_at' do - freeze_time do - expect { migrate! }.to change { bot.reload.confirmed_at }.from(nil).to(Time.current) - end - end - end -end diff --git a/spec/migrations/disable_expiration_policies_linked_to_no_container_images_spec.rb b/spec/migrations/disable_expiration_policies_linked_to_no_container_images_spec.rb deleted file mode 100644 index 1d948257fcc..00000000000 --- a/spec/migrations/disable_expiration_policies_linked_to_no_container_images_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe DisableExpirationPoliciesLinkedToNoContainerImages, feature_category: :container_registry do - let(:projects) { table(:projects) } - let(:container_expiration_policies) { table(:container_expiration_policies) } - let(:container_repositories) { table(:container_repositories) } - let(:namespaces) { table(:namespaces) } - - let!(:namespace) { namespaces.create!(name: 'test', path: 'test') } - let!(:project) { projects.create!(id: 1, namespace_id: namespace.id, name: 'gitlab1') } - let!(:container_expiration_policy) { container_expiration_policies.create!(project_id: project.id, enabled: true) } - - before do - projects.create!(id: 2, namespace_id: namespace.id, name: 'gitlab2') - container_expiration_policies.create!(project_id: 2, enabled: true) - container_repositories.create!(id: 1, project_id: 2, name: 'image2') - - projects.create!(id: 3, namespace_id: namespace.id, name: 'gitlab3') - container_expiration_policies.create!(project_id: 3, enabled: false) - container_repositories.create!(id: 2, project_id: 3, name: 'image3') - end - - it 'correctly disable expiration policies linked to no container images' do - expect(enabled_policies.count).to eq 2 - expect(disabled_policies.count).to eq 1 - expect(container_expiration_policy.enabled).to eq true - - migrate! - - expect(enabled_policies.count).to eq 1 - expect(disabled_policies.count).to eq 2 - expect(container_expiration_policy.reload.enabled).to eq false - end - - def enabled_policies - container_expiration_policies.where(enabled: true) - end - - def disabled_policies - container_expiration_policies.where(enabled: false) - end -end diff --git a/spec/migrations/fix_batched_migrations_old_format_job_arguments_spec.rb b/spec/migrations/fix_batched_migrations_old_format_job_arguments_spec.rb deleted file mode 100644 index 8def53e1858..00000000000 --- a/spec/migrations/fix_batched_migrations_old_format_job_arguments_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -# rubocop:disable Style/WordArray -RSpec.describe FixBatchedMigrationsOldFormatJobArguments, feature_category: :users do - let(:batched_background_migrations) { table(:batched_background_migrations) } - - context 'when migrations with legacy job arguments exists' do - it 'updates job arguments to current format' do - legacy_events_migration = create_batched_migration('events', 'id', ['id', 'id_convert_to_bigint']) - legacy_push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', ['event_id', 'event_id_convert_to_bigint']) - - migrate! - - expect(legacy_events_migration.reload.job_arguments).to eq([['id'], ['id_convert_to_bigint']]) - expect(legacy_push_event_payloads_migration.reload.job_arguments).to eq([['event_id'], ['event_id_convert_to_bigint']]) - end - end - - context 'when only migrations with current job arguments exists' do - it 'updates nothing' do - events_migration = create_batched_migration('events', 'id', [['id'], ['id_convert_to_bigint']]) - push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', [['event_id'], ['event_id_convert_to_bigint']]) - - migrate! - - expect(events_migration.reload.job_arguments).to eq([['id'], ['id_convert_to_bigint']]) - expect(push_event_payloads_migration.reload.job_arguments).to eq([['event_id'], ['event_id_convert_to_bigint']]) - end - end - - context 'when migrations with both legacy and current job arguments exist' do - it 'updates nothing' do - legacy_events_migration = create_batched_migration('events', 'id', ['id', 'id_convert_to_bigint']) - events_migration = create_batched_migration('events', 'id', [['id'], ['id_convert_to_bigint']]) - legacy_push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', ['event_id', 'event_id_convert_to_bigint']) - push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', [['event_id'], ['event_id_convert_to_bigint']]) - - migrate! - - expect(legacy_events_migration.reload.job_arguments).to eq(['id', 'id_convert_to_bigint']) - expect(events_migration.reload.job_arguments).to eq([['id'], ['id_convert_to_bigint']]) - expect(legacy_push_event_payloads_migration.reload.job_arguments).to eq(['event_id', 'event_id_convert_to_bigint']) - expect(push_event_payloads_migration.reload.job_arguments).to eq([['event_id'], ['event_id_convert_to_bigint']]) - end - end - - def create_batched_migration(table_name, column_name, job_arguments) - batched_background_migrations.create!( - max_value: 10, - batch_size: 10, - sub_batch_size: 10, - interval: 1, - job_class_name: 'CopyColumnUsingBackgroundMigrationJob', - table_name: table_name, - column_name: column_name, - job_arguments: job_arguments - ) - end -end -# rubocop:enable Style/WordArray diff --git a/spec/migrations/generate_customers_dot_jwt_signing_key_spec.rb b/spec/migrations/generate_customers_dot_jwt_signing_key_spec.rb deleted file mode 100644 index 1385b67b607..00000000000 --- a/spec/migrations/generate_customers_dot_jwt_signing_key_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe GenerateCustomersDotJwtSigningKey, feature_category: :customersdot_application do - let(:application_settings) do - Class.new(ActiveRecord::Base) do - self.table_name = 'application_settings' - - attr_encrypted :customers_dot_jwt_signing_key, { - mode: :per_attribute_iv, - key: Gitlab::Utils.ensure_utf8_size(Rails.application.secrets.db_key_base, bytes: 32.bytes), - algorithm: 'aes-256-gcm', - encode: true - } - end - end - - it 'generates JWT signing key' do - application_settings.create! - - reversible_migration do |migration| - migration.before -> { - settings = application_settings.first - - expect(settings.customers_dot_jwt_signing_key).to be_nil - expect(settings.encrypted_customers_dot_jwt_signing_key).to be_nil - expect(settings.encrypted_customers_dot_jwt_signing_key_iv).to be_nil - } - - migration.after -> { - settings = application_settings.first - - expect(settings.encrypted_customers_dot_jwt_signing_key).to be_present - expect(settings.encrypted_customers_dot_jwt_signing_key_iv).to be_present - expect { OpenSSL::PKey::RSA.new(settings.customers_dot_jwt_signing_key) }.not_to raise_error - } - end - end -end diff --git a/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb b/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb deleted file mode 100644 index 2f62147da9d..00000000000 --- a/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe MigrateProtectedAttributeToPendingBuilds, :suppress_gitlab_schemas_validate_connection, -feature_category: :continuous_integration do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:queue) { table(:ci_pending_builds) } - let(:builds) { table(:ci_builds) } - - before do - namespaces.create!(id: 123, name: 'sample', path: 'sample') - projects.create!(id: 123, name: 'sample', path: 'sample', namespace_id: 123) - - builds.create!(id: 1, project_id: 123, status: 'pending', protected: false, type: 'Ci::Build') - builds.create!(id: 2, project_id: 123, status: 'pending', protected: true, type: 'Ci::Build') - builds.create!(id: 3, project_id: 123, status: 'pending', protected: false, type: 'Ci::Build') - builds.create!(id: 4, project_id: 123, status: 'pending', protected: true, type: 'Ci::Bridge') - builds.create!(id: 5, project_id: 123, status: 'success', protected: true, type: 'Ci::Build') - - queue.create!(id: 1, project_id: 123, build_id: 1) - queue.create!(id: 2, project_id: 123, build_id: 2) - queue.create!(id: 3, project_id: 123, build_id: 3) - end - - it 'updates entries that should be protected' do - migrate! - - expect(queue.where(protected: true).count).to eq 1 - expect(queue.find_by(protected: true).id).to eq 2 - end -end diff --git a/spec/migrations/orphaned_invite_tokens_cleanup_spec.rb b/spec/migrations/orphaned_invite_tokens_cleanup_spec.rb deleted file mode 100644 index 56f47fca864..00000000000 --- a/spec/migrations/orphaned_invite_tokens_cleanup_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe OrphanedInviteTokensCleanup, :migration, feature_category: :subgroups do - def create_member(**extra_attributes) - defaults = { - access_level: 10, - source_id: 1, - source_type: "Project", - notification_level: 0, - type: 'ProjectMember' - } - - table(:members).create!(defaults.merge(extra_attributes)) - end - - shared_examples 'removes orphaned invite tokens' do - it 'removes invite tokens for accepted records with invite_accepted_at < created_at' do - record1 = create_member(invite_token: 'foo', invite_accepted_at: 1.day.ago, created_at: 1.hour.ago) - record2 = create_member(invite_token: 'foo2', invite_accepted_at: nil, created_at: 1.hour.ago) - record3 = create_member(invite_token: 'foo3', invite_accepted_at: 1.day.ago, created_at: 1.year.ago) - - migrate! - - expect(table(:members).find(record1.id).invite_token).to eq nil - expect(table(:members).find(record2.id).invite_token).to eq 'foo2' - expect(table(:members).find(record3.id).invite_token).to eq 'foo3' - end - end - - describe '#up', :aggregate_failures do - it_behaves_like 'removes orphaned invite tokens' - end - - context 'when there is a mix of timestamptz and timestamp types' do - around do |example| - ActiveRecord::Base.connection.execute "ALTER TABLE members alter created_at type timestamp with time zone" - - example.run - - ActiveRecord::Base.connection.execute "ALTER TABLE members alter created_at type timestamp without time zone" - end - - describe '#up', :aggregate_failures do - it_behaves_like 'removes orphaned invite tokens' - end - end -end diff --git a/spec/migrations/queue_backfill_user_details_fields_spec.rb b/spec/migrations/queue_backfill_user_details_fields_spec.rb index e77a66907de..4613a85be40 100644 --- a/spec/migrations/queue_backfill_user_details_fields_spec.rb +++ b/spec/migrations/queue_backfill_user_details_fields_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe QueueBackfillUserDetailsFields, feature_category: :users do +RSpec.describe QueueBackfillUserDetailsFields, feature_category: :user_profile do let!(:batched_migration) { described_class::MIGRATION } it 'schedules a new batched migration' do diff --git a/spec/migrations/queue_populate_projects_star_count_spec.rb b/spec/migrations/queue_populate_projects_star_count_spec.rb index 84565d14d52..b30bb6a578b 100644 --- a/spec/migrations/queue_populate_projects_star_count_spec.rb +++ b/spec/migrations/queue_populate_projects_star_count_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe QueuePopulateProjectsStarCount, feature_category: :users do +RSpec.describe QueuePopulateProjectsStarCount, feature_category: :user_profile do let!(:batched_migration) { described_class::MIGRATION } it 'schedules a new batched migration' do diff --git a/spec/migrations/re_schedule_latest_pipeline_id_population_with_all_security_related_artifact_types_spec.rb b/spec/migrations/re_schedule_latest_pipeline_id_population_with_all_security_related_artifact_types_spec.rb deleted file mode 100644 index 5ebe6787f15..00000000000 --- a/spec/migrations/re_schedule_latest_pipeline_id_population_with_all_security_related_artifact_types_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ReScheduleLatestPipelineIdPopulationWithAllSecurityRelatedArtifactTypes, - :suppress_gitlab_schemas_validate_connection, feature_category: :vulnerability_management do - let(:namespaces) { table(:namespaces) } - let(:pipelines) { table(:ci_pipelines) } - let(:projects) { table(:projects) } - let(:project_settings) { table(:project_settings) } - let(:vulnerability_statistics) { table(:vulnerability_statistics) } - - let(:letter_grade_a) { 0 } - - let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } - let(:project_1) { projects.create!(namespace_id: namespace.id, name: 'Foo 1') } - let(:project_2) { projects.create!(namespace_id: namespace.id, name: 'Foo 2') } - let(:project_3) { projects.create!(namespace_id: namespace.id, name: 'Foo 3') } - let(:project_4) { projects.create!(namespace_id: namespace.id, name: 'Foo 4') } - - before do - project_settings.create!(project_id: project_1.id, has_vulnerabilities: true) - project_settings.create!(project_id: project_2.id, has_vulnerabilities: true) - project_settings.create!(project_id: project_3.id) - project_settings.create!(project_id: project_4.id, has_vulnerabilities: true) - - pipeline = pipelines.create!(project_id: project_2.id, ref: 'master', sha: 'adf43c3a') - - vulnerability_statistics.create!(project_id: project_2.id, letter_grade: letter_grade_a, latest_pipeline_id: pipeline.id) - vulnerability_statistics.create!(project_id: project_4.id, letter_grade: letter_grade_a) - - allow(Gitlab).to receive(:ee?).and_return(is_ee?) - stub_const("#{described_class.name}::BATCH_SIZE", 1) - end - - around do |example| - freeze_time { example.run } - end - - context 'when the installation is FOSS' do - let(:is_ee?) { false } - - it 'does not schedule any background job' do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to be(0) - end - end - - context 'when the installation is EE' do - let(:is_ee?) { true } - - it 'schedules the background jobs' do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to be(2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(described_class::DELAY_INTERVAL, project_1.id, project_1.id) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2 * described_class::DELAY_INTERVAL, project_4.id, project_4.id) - end - end -end diff --git a/spec/migrations/recount_epic_cache_counts_v3_spec.rb b/spec/migrations/recount_epic_cache_counts_v3_spec.rb new file mode 100644 index 00000000000..24b89ab30ca --- /dev/null +++ b/spec/migrations/recount_epic_cache_counts_v3_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RecountEpicCacheCountsV3, :migration, feature_category: :portfolio_management do + let(:migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules a batched background migration' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :epics, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::MAX_BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/remove_duplicate_dast_site_tokens_spec.rb b/spec/migrations/remove_duplicate_dast_site_tokens_spec.rb deleted file mode 100644 index 2b21dc3b67f..00000000000 --- a/spec/migrations/remove_duplicate_dast_site_tokens_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe RemoveDuplicateDastSiteTokens, feature_category: :dynamic_application_security_testing do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:dast_site_tokens) { table(:dast_site_tokens) } - let!(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') } - let!(:project1) { projects.create!(id: 1, namespace_id: namespace.id, path: 'project1') } - # create non duplicate dast site token - let!(:dast_site_token1) { dast_site_tokens.create!(project_id: project1.id, url: 'https://gitlab.com', token: SecureRandom.uuid) } - - context 'when duplicate dast site tokens exists' do - # create duplicate dast site token - let!(:duplicate_url) { 'https://about.gitlab.com' } - - let!(:project2) { projects.create!(id: 2, namespace_id: namespace.id, path: 'project2') } - let!(:dast_site_token2) { dast_site_tokens.create!(project_id: project2.id, url: duplicate_url, token: SecureRandom.uuid) } - let!(:dast_site_token3) { dast_site_tokens.create!(project_id: project2.id, url: 'https://temp_url.com', token: SecureRandom.uuid) } - let!(:dast_site_token4) { dast_site_tokens.create!(project_id: project2.id, url: 'https://other_temp_url.com', token: SecureRandom.uuid) } - - before 'update URL to bypass uniqueness validation' do - dast_site_tokens.where(project_id: 2).update_all(url: duplicate_url) - end - - describe 'migration up' do - it 'does remove duplicated dast site tokens' do - expect(dast_site_tokens.count).to eq(4) - expect(dast_site_tokens.where(project_id: 2, url: duplicate_url).size).to eq(3) - - migrate! - - expect(dast_site_tokens.count).to eq(2) - expect(dast_site_tokens.where(project_id: 2, url: duplicate_url).size).to eq(1) - end - end - end - - context 'when duplicate dast site tokens does not exists' do - before do - dast_site_tokens.create!(project_id: 1, url: 'https://about.gitlab.com/handbook', token: SecureRandom.uuid) - end - - describe 'migration up' do - it 'does remove duplicated dast site tokens' do - expect { migrate! }.not_to change(dast_site_tokens, :count) - end - end - end -end diff --git a/spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb b/spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb deleted file mode 100644 index 6cc25b74d02..00000000000 --- a/spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe RemoveDuplicateDastSiteTokensWithSameToken, feature_category: :dynamic_application_security_testing do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:dast_site_tokens) { table(:dast_site_tokens) } - let!(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') } - let!(:project1) { projects.create!(id: 1, namespace_id: namespace.id, path: 'project1') } - # create non duplicate dast site token - let!(:dast_site_token1) { dast_site_tokens.create!(project_id: project1.id, url: 'https://gitlab.com', token: SecureRandom.uuid) } - - context 'when duplicate dast site tokens exists' do - # create duplicate dast site token - let!(:duplicate_token) { 'duplicate_token' } - let!(:other_duplicate_token) { 'other_duplicate_token' } - - let!(:project2) { projects.create!(id: 2, namespace_id: namespace.id, path: 'project2') } - let!(:dast_site_token2) { dast_site_tokens.create!(project_id: project2.id, url: 'https://gitlab2.com', token: duplicate_token) } - let!(:dast_site_token3) { dast_site_tokens.create!(project_id: project2.id, url: 'https://gitlab3.com', token: duplicate_token) } - let!(:dast_site_token4) { dast_site_tokens.create!(project_id: project2.id, url: 'https://gitlab4.com', token: duplicate_token) } - - let!(:project3) { projects.create!(id: 3, namespace_id: namespace.id, path: 'project3') } - let!(:dast_site_token5) { dast_site_tokens.create!(project_id: project3.id, url: 'https://gitlab2.com', token: other_duplicate_token) } - let!(:dast_site_token6) { dast_site_tokens.create!(project_id: project3.id, url: 'https://gitlab3.com', token: other_duplicate_token) } - let!(:dast_site_token7) { dast_site_tokens.create!(project_id: project3.id, url: 'https://gitlab4.com', token: other_duplicate_token) } - - describe 'migration up' do - it 'does remove duplicated dast site tokens with the same token' do - expect(dast_site_tokens.count).to eq(7) - expect(dast_site_tokens.where(token: duplicate_token).size).to eq(3) - - migrate! - - expect(dast_site_tokens.count).to eq(3) - expect(dast_site_tokens.where(token: duplicate_token).size).to eq(1) - end - end - end - - context 'when duplicate dast site tokens do not exist' do - let!(:dast_site_token5) { dast_site_tokens.create!(project_id: 1, url: 'https://gitlab5.com', token: SecureRandom.uuid) } - - describe 'migration up' do - it 'does not remove any dast site tokens' do - expect { migrate! }.not_to change(dast_site_tokens, :count) - end - 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 new file mode 100644 index 00000000000..cc0f5679dda --- /dev/null +++ b/spec/migrations/remove_invalid_deploy_access_level_spec.rb @@ -0,0 +1,48 @@ +# 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/rename_services_to_integrations_spec.rb b/spec/migrations/rename_services_to_integrations_spec.rb deleted file mode 100644 index a90b0bfabd2..00000000000 --- a/spec/migrations/rename_services_to_integrations_spec.rb +++ /dev/null @@ -1,255 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe RenameServicesToIntegrations, feature_category: :integrations do - let(:migration) { described_class.new } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:integrations) { table(:integrations) } - let(:services) { table(:services) } - - before do - @namespace = namespaces.create!(name: 'foo', path: 'foo') - @project = projects.create!(namespace_id: @namespace.id) - end - - RSpec.shared_examples 'a table (or view) with triggers' do - describe 'INSERT tracker trigger' do - it 'sets `has_external_issue_tracker` to true when active `issue_tracker` is inserted' do - expect do - subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - end.to change { @project.reload.has_external_issue_tracker }.to(true) - end - - it 'does not set `has_external_issue_tracker` to true when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - - expect do - subject.create!(category: 'issue_tracker', active: true, project_id: different_project.id) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not set `has_external_issue_tracker` to true when inactive `issue_tracker` is inserted' do - expect do - subject.create!(category: 'issue_tracker', active: false, project_id: @project.id) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not set `has_external_issue_tracker` to true when a non-`issue tracker` active integration is inserted' do - expect do - subject.create!(category: 'my_type', active: true, project_id: @project.id) - end.not_to change { @project.reload.has_external_issue_tracker } - end - end - - describe 'UPDATE tracker trigger' do - it 'sets `has_external_issue_tracker` to true when `issue_tracker` is made active' do - integration = subject.create!(category: 'issue_tracker', active: false, project_id: @project.id) - - expect do - integration.update!(active: true) - end.to change { @project.reload.has_external_issue_tracker }.to(true) - end - - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive' do - integration = subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - integration.update!(active: false) - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive, and an inactive `issue_tracker` exists' do - subject.create!(category: 'issue_tracker', active: false, project_id: @project.id) - integration = subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - integration.update!(active: false) - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'does not change `has_external_issue_tracker` when `issue_tracker` is made inactive, if an active `issue_tracker` exists' do - subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - integration = subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - integration.update!(active: false) - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not change `has_external_issue_tracker` when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - integration = subject.create!(category: 'issue_tracker', active: false, project_id: different_project.id) - - expect do - integration.update!(active: true) - end.not_to change { @project.reload.has_external_issue_tracker } - end - end - - describe 'DELETE tracker trigger' do - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted' do - integration = subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - integration.delete - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted, if an inactive `issue_tracker` still exists' do - subject.create!(category: 'issue_tracker', active: false, project_id: @project.id) - integration = subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - integration.delete - end.to change { @project.reload.has_external_issue_tracker }.to(false) - end - - it 'does not change `has_external_issue_tracker` when `issue_tracker` is deleted, if an active `issue_tracker` still exists' do - subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - integration = subject.create!(category: 'issue_tracker', active: true, project_id: @project.id) - - expect do - integration.delete - end.not_to change { @project.reload.has_external_issue_tracker } - end - - it 'does not change `has_external_issue_tracker` when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - integration = subject.create!(category: 'issue_tracker', active: true, project_id: different_project.id) - - expect do - integration.delete - end.not_to change { @project.reload.has_external_issue_tracker } - end - end - - describe 'INSERT wiki trigger' do - it 'sets `has_external_wiki` to true when active `ExternalWikiService` is inserted' do - expect do - subject.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - end.to change { @project.reload.has_external_wiki }.to(true) - end - - it 'does not set `has_external_wiki` to true when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - - expect do - subject.create!(type: 'ExternalWikiService', active: true, project_id: different_project.id) - end.not_to change { @project.reload.has_external_wiki } - end - - it 'does not set `has_external_wiki` to true when inactive `ExternalWikiService` is inserted' do - expect do - subject.create!(type: 'ExternalWikiService', active: false, project_id: @project.id) - end.not_to change { @project.reload.has_external_wiki } - end - - it 'does not set `has_external_wiki` to true when active other integration is inserted' do - expect do - subject.create!(type: 'MyService', active: true, project_id: @project.id) - end.not_to change { @project.reload.has_external_wiki } - end - end - - describe 'UPDATE wiki trigger' do - it 'sets `has_external_wiki` to true when `ExternalWikiService` is made active' do - integration = subject.create!(type: 'ExternalWikiService', active: false, project_id: @project.id) - - expect do - integration.update!(active: true) - end.to change { @project.reload.has_external_wiki }.to(true) - end - - it 'sets `has_external_wiki` to false when `ExternalWikiService` is made inactive' do - integration = subject.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - - expect do - integration.update!(active: false) - end.to change { @project.reload.has_external_wiki }.to(false) - end - - it 'does not change `has_external_wiki` when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - integration = subject.create!(type: 'ExternalWikiService', active: false, project_id: different_project.id) - - expect do - integration.update!(active: true) - end.not_to change { @project.reload.has_external_wiki } - end - end - - describe 'DELETE wiki trigger' do - it 'sets `has_external_wiki` to false when `ExternalWikiService` is deleted' do - integration = subject.create!(type: 'ExternalWikiService', active: true, project_id: @project.id) - - expect do - integration.delete - end.to change { @project.reload.has_external_wiki }.to(false) - end - - it 'does not change `has_external_wiki` when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - integration = subject.create!(type: 'ExternalWikiService', active: true, project_id: different_project.id) - - expect do - integration.delete - end.not_to change { @project.reload.has_external_wiki } - end - end - end - - RSpec.shared_examples 'a table (or view) without triggers' do - specify do - number_of_triggers = ActiveRecord::Base.connection - .execute("SELECT count(*) FROM information_schema.triggers WHERE event_object_table = '#{subject.table_name}'") - .first['count'] - - expect(number_of_triggers).to eq(0) - end - end - - describe '#up' do - before do - # LOCK TABLE statements must be in a transaction - ActiveRecord::Base.transaction { migrate! } - end - - context 'the integrations table' do - subject { integrations } - - it_behaves_like 'a table (or view) with triggers' - end - - context 'the services table' do - subject { services } - - it_behaves_like 'a table (or view) without triggers' - end - end - - describe '#down' do - before do - # LOCK TABLE statements must be in a transaction - ActiveRecord::Base.transaction do - migration.up - migration.down - end - end - - context 'the services table' do - subject { services } - - it_behaves_like 'a table (or view) with triggers' - end - - context 'the integrations table' do - subject { integrations } - - it_behaves_like 'a table (or view) without triggers' - end - end -end diff --git a/spec/migrations/replace_external_wiki_triggers_spec.rb b/spec/migrations/replace_external_wiki_triggers_spec.rb deleted file mode 100644 index c2bc5c44c77..00000000000 --- a/spec/migrations/replace_external_wiki_triggers_spec.rb +++ /dev/null @@ -1,132 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe ReplaceExternalWikiTriggers, feature_category: :integrations do - let(:migration) { described_class.new } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:integrations) { table(:integrations) } - - before do - @namespace = namespaces.create!(name: 'foo', path: 'foo') - @project = projects.create!(namespace_id: @namespace.id) - end - - def create_external_wiki_integration(**attrs) - attrs.merge!(type_info) - - integrations.create!(**attrs) - end - - def has_external_wiki - !!@project.reload.has_external_wiki - end - - shared_examples 'external wiki triggers' do - describe 'INSERT trigger' do - it 'sets `has_external_wiki` to true when active external wiki integration is inserted' do - expect do - create_external_wiki_integration(active: true, project_id: @project.id) - end.to change { has_external_wiki }.to(true) - end - - it 'does not set `has_external_wiki` to true when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - - expect do - create_external_wiki_integration(active: true, project_id: different_project.id) - end.not_to change { has_external_wiki } - end - - it 'does not set `has_external_wiki` to true when inactive external wiki integration is inserted' do - expect do - create_external_wiki_integration(active: false, project_id: @project.id) - end.not_to change { has_external_wiki } - end - - it 'does not set `has_external_wiki` to true when active other service is inserted' do - expect do - integrations.create!(type_new: 'Integrations::MyService', type: 'MyService', active: true, project_id: @project.id) - end.not_to change { has_external_wiki } - end - end - - describe 'UPDATE trigger' do - it 'sets `has_external_wiki` to true when `ExternalWikiService` is made active' do - service = create_external_wiki_integration(active: false, project_id: @project.id) - - expect do - service.update!(active: true) - end.to change { has_external_wiki }.to(true) - end - - it 'sets `has_external_wiki` to false when integration is made inactive' do - service = create_external_wiki_integration(active: true, project_id: @project.id) - - expect do - service.update!(active: false) - end.to change { has_external_wiki }.to(false) - end - - it 'does not change `has_external_wiki` when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - service = create_external_wiki_integration(active: false, project_id: different_project.id) - - expect do - service.update!(active: true) - end.not_to change { has_external_wiki } - end - end - - describe 'DELETE trigger' do - it 'sets `has_external_wiki` to false when integration is deleted' do - service = create_external_wiki_integration(active: true, project_id: @project.id) - - expect do - service.delete - end.to change { has_external_wiki }.to(false) - end - - it 'does not change `has_external_wiki` when integration is for a different project' do - different_project = projects.create!(namespace_id: @namespace.id) - service = create_external_wiki_integration(active: true, project_id: different_project.id) - - expect do - service.delete - end.not_to change { has_external_wiki } - end - end - end - - describe '#up' do - before do - migrate! - end - - context 'when integrations are created with the new STI value' do - let(:type_info) { { type_new: 'Integrations::ExternalWiki' } } - - it_behaves_like 'external wiki triggers' - end - - context 'when integrations are created with the old STI value' do - let(:type_info) { { type: 'ExternalWikiService' } } - - it_behaves_like 'external wiki triggers' - end - end - - describe '#down' do - before do - migration.up - migration.down - end - - let(:type_info) { { type: 'ExternalWikiService' } } - - it_behaves_like 'external wiki triggers' - end -end diff --git a/spec/migrations/reschedule_delete_orphaned_deployments_spec.rb b/spec/migrations/reschedule_delete_orphaned_deployments_spec.rb deleted file mode 100644 index bbc4494837a..00000000000 --- a/spec/migrations/reschedule_delete_orphaned_deployments_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe RescheduleDeleteOrphanedDeployments, :sidekiq, schema: 20210617161348, - feature_category: :continuous_delivery do - let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } - let!(:project) { table(:projects).create!(namespace_id: namespace.id) } - let!(:environment) { table(:environments).create!(name: 'production', slug: 'production', project_id: project.id) } - let(:background_migration_jobs) { table(:background_migration_jobs) } - - before do - create_deployment!(environment.id, project.id) - create_deployment!(environment.id, project.id) - create_deployment!(environment.id, project.id) - create_deployment!(non_existing_record_id, project.id) - create_deployment!(non_existing_record_id, project.id) - create_deployment!(non_existing_record_id, project.id) - create_deployment!(non_existing_record_id, project.id) - - stub_const("#{described_class}::BATCH_SIZE", 1) - end - - it 'steal existing background migration jobs' do - expect(Gitlab::BackgroundMigration).to receive(:steal).with('DeleteOrphanedDeployments') - - migrate! - end - - it 'cleans up background migration jobs tracking records' do - old_successful_job = background_migration_jobs.create!( - class_name: 'DeleteOrphanedDeployments', - status: Gitlab::Database::BackgroundMigrationJob.statuses[:succeeded], - arguments: [table(:deployments).minimum(:id), table(:deployments).minimum(:id)] - ) - - old_pending_job = background_migration_jobs.create!( - class_name: 'DeleteOrphanedDeployments', - status: Gitlab::Database::BackgroundMigrationJob.statuses[:pending], - arguments: [table(:deployments).maximum(:id), table(:deployments).maximum(:id)] - ) - - migrate! - - expect { old_successful_job.reload }.to raise_error(ActiveRecord::RecordNotFound) - expect { old_pending_job.reload }.to raise_error(ActiveRecord::RecordNotFound) - end - - it 'schedules DeleteOrphanedDeployments background jobs' do - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(7) - table(:deployments).find_each do |deployment| - expect(described_class::MIGRATION).to be_scheduled_migration(deployment.id, deployment.id) - end - end - end - end - - def create_deployment!(environment_id, project_id) - table(:deployments).create!( - environment_id: environment_id, - project_id: project_id, - ref: 'master', - tag: false, - sha: 'x', - status: 1, - iid: table(:deployments).count + 1) - end -end diff --git a/spec/migrations/reset_job_token_scope_enabled_again_spec.rb b/spec/migrations/reset_job_token_scope_enabled_again_spec.rb deleted file mode 100644 index 9f1180b6e24..00000000000 --- a/spec/migrations/reset_job_token_scope_enabled_again_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe ResetJobTokenScopeEnabledAgain, feature_category: :continuous_integration do - let(:settings) { table(:project_ci_cd_settings) } - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } - let(:project_1) { projects.create!(name: 'proj-1', path: 'gitlab-org', namespace_id: namespace.id) } - let(:project_2) { projects.create!(name: 'proj-2', path: 'gitlab-org', namespace_id: namespace.id) } - - before do - settings.create!(id: 1, project_id: project_1.id, job_token_scope_enabled: true) - settings.create!(id: 2, project_id: project_2.id, job_token_scope_enabled: false) - end - - it 'migrates job_token_scope_enabled to be always false' do - expect { migrate! } - .to change { settings.where(job_token_scope_enabled: false).count } - .from(1).to(2) - end -end diff --git a/spec/migrations/reset_job_token_scope_enabled_spec.rb b/spec/migrations/reset_job_token_scope_enabled_spec.rb deleted file mode 100644 index 4ce9078246a..00000000000 --- a/spec/migrations/reset_job_token_scope_enabled_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe ResetJobTokenScopeEnabled, feature_category: :continuous_integration do - let(:settings) { table(:project_ci_cd_settings) } - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } - let(:project_1) { projects.create!(name: 'proj-1', path: 'gitlab-org', namespace_id: namespace.id) } - let(:project_2) { projects.create!(name: 'proj-2', path: 'gitlab-org', namespace_id: namespace.id) } - - before do - settings.create!(id: 1, project_id: project_1.id, job_token_scope_enabled: true) - settings.create!(id: 2, project_id: project_2.id, job_token_scope_enabled: false) - end - - it 'migrates job_token_scope_enabled to be always false' do - expect { migrate! } - .to change { settings.where(job_token_scope_enabled: false).count } - .from(1).to(2) - end -end diff --git a/spec/migrations/reset_severity_levels_to_new_default_spec.rb b/spec/migrations/reset_severity_levels_to_new_default_spec.rb deleted file mode 100644 index 83e57b852a0..00000000000 --- a/spec/migrations/reset_severity_levels_to_new_default_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe ResetSeverityLevelsToNewDefault, feature_category: :source_code_management do - let(:approval_project_rules) { table(:approval_project_rules) } - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - let(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') } - let(:project) { projects.create!(name: 'project', path: 'project', namespace_id: namespace.id) } - let(:approval_project_rule) { approval_project_rules.create!(name: 'rule', project_id: project.id, severity_levels: severity_levels) } - - context 'without having all severity levels selected' do - let(:severity_levels) { ['high'] } - - it 'does not change severity_levels' do - expect(approval_project_rule.severity_levels).to eq(severity_levels) - expect { migrate! }.not_to change { approval_project_rule.reload.severity_levels } - end - end - - context 'with all scanners selected' do - let(:severity_levels) { ::Enums::Vulnerability::SEVERITY_LEVELS.keys } - let(:default_levels) { %w(unknown high critical) } - - it 'changes severity_levels to the default value' do - expect(approval_project_rule.severity_levels).to eq(severity_levels) - expect { migrate! }.to change { approval_project_rule.reload.severity_levels }.from(severity_levels).to(default_levels) - end - end -end diff --git a/spec/migrations/retry_backfill_traversal_ids_spec.rb b/spec/migrations/retry_backfill_traversal_ids_spec.rb deleted file mode 100644 index f3658d1b8a3..00000000000 --- a/spec/migrations/retry_backfill_traversal_ids_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe RetryBackfillTraversalIds, :migration, feature_category: :subgroups do - include ReloadHelpers - - let!(:namespaces_table) { table(:namespaces) } - - context 'when BackfillNamespaceTraversalIdsRoots jobs are pending' do - before do - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsRoots', - arguments: [1, 4, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['pending'] - ) - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsRoots', - arguments: [5, 9, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded'] - ) - end - - it 'queues pending jobs' do - migrate! - - expect(BackgroundMigrationWorker.jobs.length).to eq(1) - expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['BackfillNamespaceTraversalIdsRoots', [1, 4, 100]]) - expect(BackgroundMigrationWorker.jobs[0]['at']).to be_nil - end - end - - context 'when BackfillNamespaceTraversalIdsChildren jobs are pending' do - before do - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsChildren', - arguments: [1, 4, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['pending'] - ) - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsRoots', - arguments: [5, 9, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded'] - ) - end - - it 'queues pending jobs' do - migrate! - - expect(BackgroundMigrationWorker.jobs.length).to eq(1) - expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['BackfillNamespaceTraversalIdsChildren', [1, 4, 100]]) - expect(BackgroundMigrationWorker.jobs[0]['at']).to be_nil - end - end - - context 'when BackfillNamespaceTraversalIdsRoots and BackfillNamespaceTraversalIdsChildren jobs are pending' do - before do - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsRoots', - arguments: [1, 4, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['pending'] - ) - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsChildren', - arguments: [5, 9, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['pending'] - ) - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsRoots', - arguments: [11, 14, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded'] - ) - table(:background_migration_jobs).create!( - class_name: 'BackfillNamespaceTraversalIdsChildren', - arguments: [15, 19, 100], - status: Gitlab::Database::BackgroundMigrationJob.statuses['succeeded'] - ) - end - - it 'queues pending jobs' do - freeze_time do - migrate! - - expect(BackgroundMigrationWorker.jobs.length).to eq(2) - expect(BackgroundMigrationWorker.jobs[0]['args']).to eq(['BackfillNamespaceTraversalIdsRoots', [1, 4, 100]]) - expect(BackgroundMigrationWorker.jobs[0]['at']).to be_nil - expect(BackgroundMigrationWorker.jobs[1]['args']).to eq(['BackfillNamespaceTraversalIdsChildren', [5, 9, 100]]) - expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(RetryBackfillTraversalIds::DELAY_INTERVAL.from_now.to_f) - end - end - end -end diff --git a/spec/migrations/sanitize_confidential_note_todos_spec.rb b/spec/migrations/sanitize_confidential_note_todos_spec.rb deleted file mode 100644 index 142378e07e1..00000000000 --- a/spec/migrations/sanitize_confidential_note_todos_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe SanitizeConfidentialNoteTodos, feature_category: :team_planning 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: :notes, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - batch_size: described_class::BATCH_SIZE, - max_batch_size: described_class::MAX_BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - end - end - - describe '#down' do - it 'deletes all batched migration records' do - migrate! - schema_migrate_down! - - expect(migration).not_to have_scheduled_batched_migration - end - end -end diff --git a/spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb b/spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb deleted file mode 100644 index 63678a094a7..00000000000 --- a/spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleCopyCiBuildsColumnsToSecurityScans2, feature_category: :dependency_scanning do - it 'is a no-op' do - migrate! - end -end diff --git a/spec/migrations/schedule_security_setting_creation_spec.rb b/spec/migrations/schedule_security_setting_creation_spec.rb deleted file mode 100644 index edabb2a2299..00000000000 --- a/spec/migrations/schedule_security_setting_creation_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleSecuritySettingCreation, :sidekiq, feature_category: :projects do - describe '#up' do - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - - context 'for EE version' do - before do - stub_const("#{described_class.name}::BATCH_SIZE", 2) - allow(Gitlab).to receive(:ee?).and_return(true) - end - - it 'schedules background migration job' do - namespace = namespaces.create!(name: 'test', path: 'test') - projects.create!(id: 12, namespace_id: namespace.id, name: 'red', path: 'red') - projects.create!(id: 13, namespace_id: namespace.id, name: 'green', path: 'green') - projects.create!(id: 14, namespace_id: namespace.id, name: 'blue', path: 'blue') - - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(5.minutes, 12, 13) - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(10.minutes, 14, 14) - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - end - end - end - end - - context 'for FOSS version' do - before do - allow(Gitlab).to receive(:ee?).and_return(false) - end - - it 'does not schedule any jobs' do - namespace = namespaces.create!(name: 'test', path: 'test') - projects.create!(id: 12, namespace_id: namespace.id, name: 'red', path: 'red') - - Sidekiq::Testing.fake! do - freeze_time do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(0) - end - end - end - end - end -end diff --git a/spec/migrations/set_default_job_token_scope_true_spec.rb b/spec/migrations/set_default_job_token_scope_true_spec.rb deleted file mode 100644 index 25f4f07e15a..00000000000 --- a/spec/migrations/set_default_job_token_scope_true_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe SetDefaultJobTokenScopeTrue, schema: 20210819153805, feature_category: :continuous_integration do - let(:ci_cd_settings) { table(:project_ci_cd_settings) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - - let(:namespace) { namespaces.create!(name: 'test', path: 'path', type: 'Group') } - let(:project) { projects.create!(namespace_id: namespace.id) } - - describe '#up' do - it 'sets the job_token_scope_enabled default to true' do - described_class.new.up - - settings = ci_cd_settings.create!(project_id: project.id) - - expect(settings.job_token_scope_enabled).to be_truthy - end - end - - describe '#down' do - it 'sets the job_token_scope_enabled default to false' do - described_class.new.down - - settings = ci_cd_settings.create!(project_id: project.id) - - expect(settings.job_token_scope_enabled).to be_falsey - 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 4303713744e..8e00fbe4b89 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 @@ -3,7 +3,8 @@ require 'spec_helper' require_migration! -RSpec.describe SetEmailConfirmationSettingBeforeRemovingSendUserConfirmationEmailColumn, feature_category: :users do +RSpec.describe SetEmailConfirmationSettingBeforeRemovingSendUserConfirmationEmailColumn, + 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_send_user_confirmation_email_setting_spec.rb b/spec/migrations/set_email_confirmation_setting_from_send_user_confirmation_email_setting_spec.rb index e08aa8679a1..ef1ced530c9 100644 --- a/spec/migrations/set_email_confirmation_setting_from_send_user_confirmation_email_setting_spec.rb +++ b/spec/migrations/set_email_confirmation_setting_from_send_user_confirmation_email_setting_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe SetEmailConfirmationSettingFromSendUserConfirmationEmailSetting, feature_category: :users do +RSpec.describe SetEmailConfirmationSettingFromSendUserConfirmationEmailSetting, feature_category: :user_profile do let(:migration) { described_class.new } let(:application_settings_table) { table(:application_settings) } diff --git a/spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb b/spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb deleted file mode 100644 index d2cd7a6980d..00000000000 --- a/spec/migrations/steal_merge_request_diff_commit_users_migration_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe StealMergeRequestDiffCommitUsersMigration, :migration, feature_category: :source_code_management do - let(:migration) { described_class.new } - - describe '#up' do - it 'schedules a job if there are pending jobs' do - Gitlab::Database::BackgroundMigrationJob.create!( - class_name: 'MigrateMergeRequestDiffCommitUsers', - arguments: [10, 20] - ) - - expect(migration) - .to receive(:migrate_in) - .with(1.hour, 'StealMigrateMergeRequestDiffCommitUsers', [10, 20]) - - migration.up - end - - it 'does not schedule any jobs when all jobs have been completed' do - expect(migration).not_to receive(:migrate_in) - - migration.up - end - end -end diff --git a/spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb b/spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb deleted file mode 100644 index efc051d9a68..00000000000 --- a/spec/migrations/update_integrations_trigger_type_new_on_insert_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require_migration! - -RSpec.describe UpdateIntegrationsTriggerTypeNewOnInsert, feature_category: :integrations do - let(:migration) { described_class.new } - let(:integrations) { table(:integrations) } - - shared_examples 'transforms known types' do - # This matches Gitlab::Integrations::StiType at the time the original trigger - # was added in db/migrate/20210721135638_add_triggers_to_integrations_type_new.rb - let(:namespaced_integrations) do - %w[ - Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog - Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost - MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker - Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack - - Github GitlabSlackApplication - ] - end - - it 'sets `type_new` to the transformed `type` class name' do - namespaced_integrations.each do |type| - integration = integrations.create!(type: "#{type}Service") - - expect(integration.reload).to have_attributes( - type: "#{type}Service", - type_new: "Integrations::#{type}" - ) - end - end - end - - describe '#up' do - before do - migrate! - end - - describe 'INSERT trigger with dynamic mapping' do - it_behaves_like 'transforms known types' - - it 'transforms unknown types if it ends in "Service"' do - integration = integrations.create!(type: 'AcmeService') - - expect(integration.reload).to have_attributes( - type: 'AcmeService', - type_new: 'Integrations::Acme' - ) - end - - it 'ignores "Service" occurring elsewhere in the type' do - integration = integrations.create!(type: 'ServiceAcmeService') - - expect(integration.reload).to have_attributes( - type: 'ServiceAcmeService', - type_new: 'Integrations::ServiceAcme' - ) - end - - it 'copies unknown types if it does not end with "Service"' do - integration = integrations.create!(type: 'Integrations::Acme') - - expect(integration.reload).to have_attributes( - type: 'Integrations::Acme', - type_new: 'Integrations::Acme' - ) - end - end - end - - describe '#down' do - before do - migration.up - migration.down - end - - describe 'INSERT trigger with static mapping' do - it_behaves_like 'transforms known types' - - it 'ignores types that are already namespaced' do - integration = integrations.create!(type: 'Integrations::Asana') - - expect(integration.reload).to have_attributes( - type: 'Integrations::Asana', - type_new: nil - ) - end - - it 'ignores types that are unknown' do - integration = integrations.create!(type: 'FooBar') - - expect(integration.reload).to have_attributes( - type: 'FooBar', - type_new: nil - ) - end - end - end -end -- cgit v1.2.3