diff options
Diffstat (limited to 'spec/migrations')
31 files changed, 651 insertions, 268 deletions
diff --git a/spec/migrations/20210421163509_schedule_update_jira_tracker_data_deployment_type_based_on_url_spec.rb b/spec/migrations/20210421163509_schedule_update_jira_tracker_data_deployment_type_based_on_url_spec.rb deleted file mode 100644 index 9a59c739ecd..00000000000 --- a/spec/migrations/20210421163509_schedule_update_jira_tracker_data_deployment_type_based_on_url_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe ScheduleUpdateJiraTrackerDataDeploymentTypeBasedOnUrl, :migration do - let(:services_table) { table(:services) } - let(:service_jira_cloud) { services_table.create!(id: 1, type: 'JiraService') } - let(:service_jira_server) { services_table.create!(id: 2, type: 'JiraService') } - - before do - jira_tracker_data = Class.new(ApplicationRecord) do - self.table_name = 'jira_tracker_data' - - def self.encryption_options - { - key: Settings.attr_encrypted_db_key_base_32, - encode: true, - mode: :per_attribute_iv, - algorithm: 'aes-256-gcm' - } - end - - attr_encrypted :url, encryption_options - attr_encrypted :api_url, encryption_options - attr_encrypted :username, encryption_options - attr_encrypted :password, encryption_options - end - - stub_const('JiraTrackerData', jira_tracker_data) - stub_const("#{described_class}::BATCH_SIZE", 1) - end - - let!(:tracker_data_cloud) { JiraTrackerData.create!(id: 1, service_id: service_jira_cloud.id, url: "https://test-domain.atlassian.net", deployment_type: 0) } - let!(:tracker_data_server) { JiraTrackerData.create!(id: 2, service_id: service_jira_server.id, url: "http://totally-not-jira-server.company.org", deployment_type: 0) } - - around do |example| - freeze_time { Sidekiq::Testing.fake! { example.run } } - end - - it 'schedules background migration' do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - expect(described_class::MIGRATION).to be_scheduled_migration(tracker_data_cloud.id, tracker_data_cloud.id) - expect(described_class::MIGRATION).to be_scheduled_migration(tracker_data_server.id, tracker_data_server.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 index d35184e78a8..8dfeacc4774 100644 --- a/spec/migrations/2021061716138_cascade_delete_freeze_periods_spec.rb +++ b/spec/migrations/2021061716138_cascade_delete_freeze_periods_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' require_migration! -RSpec.describe CascadeDeleteFreezePeriods do +RSpec.describe CascadeDeleteFreezePeriods, :suppress_gitlab_schemas_validate_connection 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) } diff --git a/spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb b/spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb index 29f554a003b..13a6aa5413e 100644 --- a/spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb +++ b/spec/migrations/20210818185845_backfill_projects_with_coverage_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe BackfillProjectsWithCoverage do +RSpec.describe BackfillProjectsWithCoverage, :suppress_gitlab_schemas_validate_connection do let(:projects) { table(:projects) } let(:ci_pipelines) { table(:ci_pipelines) } let(:ci_daily_build_group_report_results) { table(:ci_daily_build_group_report_results) } diff --git a/spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb b/spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb index c1d96f50dc8..cf6a033b4b8 100644 --- a/spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb +++ b/spec/migrations/20211116111644_schedule_remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb @@ -3,7 +3,8 @@ require 'spec_helper' require_migration! -RSpec.describe ScheduleRemoveOccurrencePipelinesAndDuplicateVulnerabilitiesFindings, :migration do +RSpec.describe ScheduleRemoveOccurrencePipelinesAndDuplicateVulnerabilitiesFindings, + :suppress_gitlab_schemas_validate_connection, :migration do let_it_be(:background_migration_jobs) { table(:background_migration_jobs) } let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } let_it_be(:users) { table(:users) } diff --git a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb index 127f4798f33..3429ccc4df1 100644 --- a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb +++ b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe DedupRunnerProjects, :migration, schema: 20220120085655 do +RSpec.describe DedupRunnerProjects, :migration, :suppress_gitlab_schemas_validate_connection, schema: 20220120085655 do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:runners) { table(:ci_runners) } diff --git a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb index a48464befdf..a23f9995875 100644 --- a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb +++ b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration!('remove_dangling_running_builds') -RSpec.describe RemoveDanglingRunningBuilds do +RSpec.describe RemoveDanglingRunningBuilds, :suppress_gitlab_schemas_validate_connection do let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } let(:project) { table(:projects).create!(namespace_id: namespace.id) } let(:runner) { table(:ci_runners).create!(runner_type: 1) } @@ -47,6 +47,6 @@ RSpec.describe RemoveDanglingRunningBuilds do migrate! expect(running_metadata.reload).to be_present - expect { failed_metadata.reload } .to raise_error(ActiveRecord::RecordNotFound) + expect { failed_metadata.reload }.to raise_error(ActiveRecord::RecordNotFound) end end diff --git a/spec/migrations/20220505174658_update_index_on_alerts_to_exclude_null_fingerprints_spec.rb b/spec/migrations/20220505174658_update_index_on_alerts_to_exclude_null_fingerprints_spec.rb index 0c4d0e86789..ec58a54b085 100644 --- a/spec/migrations/20220505174658_update_index_on_alerts_to_exclude_null_fingerprints_spec.rb +++ b/spec/migrations/20220505174658_update_index_on_alerts_to_exclude_null_fingerprints_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' require_migration! RSpec.describe UpdateIndexOnAlertsToExcludeNullFingerprints do - let(:alerts) { 'alert_management_alerts'} + let(:alerts) { 'alert_management_alerts' } let(:old_index) { described_class::OLD_INDEX_NAME } let(:new_index) { described_class::NEW_INDEX_NAME } diff --git a/spec/migrations/20220506154054_create_sync_namespace_details_trigger_spec.rb b/spec/migrations/20220506154054_create_sync_namespace_details_trigger_spec.rb new file mode 100644 index 00000000000..411b1eacb86 --- /dev/null +++ b/spec/migrations/20220506154054_create_sync_namespace_details_trigger_spec.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe CreateSyncNamespaceDetailsTrigger do + let(:migration) { described_class.new } + let(:namespaces) { table(:namespaces) } + let(:namespace_details) { table(:namespace_details) } + let!(:timestamp) { Time.new(2020, 01, 01).utc } + + let(:synced_attributes) do + { + description: 'description', + description_html: '<p>description</p>', + cached_markdown_version: 1966080, + created_at: timestamp, + updated_at: timestamp + } + end + + let(:other_attributes) do + { + name: 'name', + path: 'path' + } + end + + let(:attributes) { other_attributes.merge(synced_attributes) } + + describe '#up' do + before do + migrate! + end + + describe 'INSERT trigger' do + it 'creates a namespace_detail record' do + expect do + namespaces.create!(attributes) + end.to change(namespace_details, :count).by(1) + end + + it 'the created namespace_details record has matching attributes' do + namespaces.create!(attributes) + synced_namespace_details = namespace_details.last + + expect(synced_namespace_details).to have_attributes(synced_attributes) + end + end + + describe 'UPDATE trigger' do + let!(:namespace) { namespaces.create!(attributes) } + + it 'updates the attribute in the synced namespace_details record' do + namespace.update!(description: 'new_description') + + synced_namespace_details = namespace_details.last + expect(synced_namespace_details.description).to eq('new_description') + end + end + end + + describe '#down' do + before do + migration.up + migration.down + end + + it 'drops the trigger' do + expect do + namespaces.create!(attributes) + end.not_to change(namespace_details, :count) + end + end +end diff --git a/spec/migrations/20220524184149_create_sync_project_namespace_details_trigger_spec.rb b/spec/migrations/20220524184149_create_sync_project_namespace_details_trigger_spec.rb new file mode 100644 index 00000000000..f85a59357e1 --- /dev/null +++ b/spec/migrations/20220524184149_create_sync_project_namespace_details_trigger_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe CreateSyncProjectNamespaceDetailsTrigger do + let(:migration) { described_class.new } + let(:projects) { table(:projects) } + let(:namespaces) { table(:namespaces) } + let(:namespace_details) { table(:namespace_details) } + let!(:timestamp) { Time.new(2020, 01, 01).utc } + let!(:project_namespace) { namespaces.create!(name: 'name', path: 'path') } + let!(:namespace) { namespaces.create!(name: 'group', path: 'group_path') } + + let(:synced_attributes) do + { + description: 'description', + description_html: '<p>description</p>', + cached_markdown_version: 1966080, + updated_at: timestamp + } + end + + let(:other_attributes) do + { + name: 'project_name', + project_namespace_id: project_namespace.id, + namespace_id: namespace.id + } + end + + let(:attributes) { other_attributes.merge(synced_attributes) } + + describe '#up' do + before do + migrate! + end + + describe 'INSERT trigger' do + it 'the created namespace_details record has matching attributes' do + project = projects.create!(attributes) + synced_namespace_details = namespace_details.find_by(namespace_id: project.project_namespace_id) + + expect(synced_namespace_details).to have_attributes(synced_attributes) + end + end + + describe 'UPDATE trigger' do + let!(:project) { projects.create!(attributes) } + + it 'updates the attribute in the synced namespace_details record' do + project.update!(description: 'new_description') + + synced_namespace_details = namespace_details.find_by(namespace_id: project.project_namespace_id) + expect(synced_namespace_details.description).to eq('new_description') + end + end + end + + describe '#down' do + before do + migration.up + migration.down + end + + it 'drops the trigger' do + expect do + projects.create!(attributes) + end.not_to change(namespace_details, :count) + end + end +end diff --git a/spec/migrations/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent_spec.rb b/spec/migrations/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent_spec.rb new file mode 100644 index 00000000000..3f1a2d8c4b9 --- /dev/null +++ b/spec/migrations/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleBackfillVulnerabilityReadsClusterAgent do + let_it_be(:batched_migration) { described_class::MIGRATION_NAME } + + it 'schedules background jobs for each batch of vulnerability reads' do + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).to have_scheduled_batched_migration( + table_name: :vulnerability_reads, + column_name: :id, + interval: described_class::DELAY_INTERVAL + ) + } + end + end +end diff --git a/spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb b/spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb new file mode 100644 index 00000000000..68fac1c2221 --- /dev/null +++ b/spec/migrations/20220607082910_add_sync_tmp_index_for_potentially_misassociated_vulnerability_occurrences_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require "spec_helper" + +require_migration! + +RSpec.describe AddSyncTmpIndexForPotentiallyMisassociatedVulnerabilityOccurrences do + let(:table) { "vulnerability_occurrences" } + let(:index) { described_class::INDEX_NAME } + + it "creates and drops the index" do + reversible_migration do |migration| + migration.before -> do + expect(ActiveRecord::Base.connection.indexes(table).map(&:name)).not_to include(index) + end + + migration.after -> do + expect(ActiveRecord::Base.connection.indexes(table).map(&:name)).to include(index) + end + end + end +end diff --git a/spec/migrations/20220721031446_schedule_disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb b/spec/migrations/20220721031446_schedule_disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb new file mode 100644 index 00000000000..b17a0215f4e --- /dev/null +++ b/spec/migrations/20220721031446_schedule_disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleDisableLegacyOpenSourceLicenseForOneMemberNoRepoProjects do + context 'when on gitlab.com' do + let(:migration) { described_class::MIGRATION } + + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of projects' 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 '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 } + + before do + allow(Gitlab).to receive(:com?).and_return(false) + end + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20220520040416_schedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb b/spec/migrations/20220722084543_schedule_disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb index e3bc832a10b..cb0f941aea1 100644 --- a/spec/migrations/20220520040416_schedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb +++ b/spec/migrations/20220722084543_schedule_disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' require_migration! -RSpec.describe ScheduleSetLegacyOpenSourceLicenseAvailableForNonPublicProjects do - context 'on gitlab.com' do +RSpec.describe ScheduleDisableLegacyOpenSourceLicenseForNoIssuesNoRepoProjects do + context 'when on gitlab.com' do let(:migration) { described_class::MIGRATION } before do @@ -21,6 +21,7 @@ RSpec.describe ScheduleSetLegacyOpenSourceLicenseAvailableForNonPublicProjects d 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 ) ) @@ -37,7 +38,7 @@ RSpec.describe ScheduleSetLegacyOpenSourceLicenseAvailableForNonPublicProjects d end end - context 'on self-managed instance' do + context 'when on self-managed instance' do let(:migration) { described_class.new } before do diff --git a/spec/migrations/20220722110026_reschedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb b/spec/migrations/20220722110026_reschedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb new file mode 100644 index 00000000000..99a30c7f2a9 --- /dev/null +++ b/spec/migrations/20220722110026_reschedule_set_legacy_open_source_license_available_for_non_public_projects_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RescheduleSetLegacyOpenSourceLicenseAvailableForNonPublicProjects do + context 'when on gitlab.com' do + let(:migration) { described_class::MIGRATION } + + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + describe '#up' do + it 'schedules background jobs for each batch of projects' 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 '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 } + + before do + allow(Gitlab).to receive(:com?).and_return(false) + end + + describe '#up' do + it 'does not schedule background job' do + expect(migration).not_to receive(:queue_batched_background_migration) + + migration.up + end + end + + describe '#down' do + it 'does not delete background job' do + expect(migration).not_to receive(:delete_batched_background_migration) + + migration.down + end + end + end +end diff --git a/spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb b/spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb new file mode 100644 index 00000000000..2651e46ba53 --- /dev/null +++ b/spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe UpdateJiraTrackerDataDeploymentTypeBasedOnUrl, :migration do + let(:integrations_table) { table(:integrations) } + let(:service_jira_cloud) { integrations_table.create!(id: 1, type_new: 'JiraService') } + let(:service_jira_server) { integrations_table.create!(id: 2, type_new: 'JiraService') } + + before do + jira_tracker_data = Class.new(ApplicationRecord) do + self.table_name = 'jira_tracker_data' + + def self.encryption_options + { + key: Settings.attr_encrypted_db_key_base_32, + encode: true, + mode: :per_attribute_iv, + algorithm: 'aes-256-gcm' + } + end + + attr_encrypted :url, encryption_options + attr_encrypted :api_url, encryption_options + attr_encrypted :username, encryption_options + attr_encrypted :password, encryption_options + end + + stub_const('JiraTrackerData', jira_tracker_data) + stub_const("#{described_class}::BATCH_SIZE", 1) + stub_const("#{described_class}::SUB_BATCH_SIZE", 1) + end + + # rubocop:disable Layout/LineLength + # rubocop:disable RSpec/ScatteredLet + let!(:tracker_data_cloud) { JiraTrackerData.create!(id: 1, integration_id: service_jira_cloud.id, url: "https://test-domain.atlassian.net", deployment_type: 0) } + let!(:tracker_data_server) { JiraTrackerData.create!(id: 2, integration_id: service_jira_server.id, url: "http://totally-not-jira-server.company.org", deployment_type: 0) } + # rubocop:enable Layout/LineLength + # rubocop:enable RSpec/ScatteredLet + + around do |example| + freeze_time { Sidekiq::Testing.fake! { example.run } } + end + + let(:migration) { described_class::MIGRATION } # rubocop:disable RSpec/ScatteredLet + + it 'schedules background migration' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :jira_tracker_data, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + gitlab_schema: :gitlab_main + ) + end +end diff --git a/spec/migrations/20220802114351_reschedule_backfill_container_registry_size_into_project_statistics_spec.rb b/spec/migrations/20220802114351_reschedule_backfill_container_registry_size_into_project_statistics_spec.rb new file mode 100644 index 00000000000..cc1c1dac4c3 --- /dev/null +++ b/spec/migrations/20220802114351_reschedule_backfill_container_registry_size_into_project_statistics_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RescheduleBackfillContainerRegistrySizeIntoProjectStatistics do + let_it_be(:batched_migration) { described_class::MIGRATION_CLASS } + + it 'does not schedule background jobs when Gitlab.com is false' do + allow(Gitlab).to receive(:com?).and_return(false) + allow(Gitlab).to receive(:dev_or_test_env?).and_return(false) + + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + end + end + + it 'schedules background jobs for each batch of container_repository' do + allow(Gitlab).to receive(:com?).and_return(true) + + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).to have_scheduled_batched_migration( + table_name: :container_repositories, + column_name: :project_id, + interval: described_class::DELAY_INTERVAL + ) + } + end + end +end 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 new file mode 100644 index 00000000000..3ea286ca138 --- /dev/null +++ b/spec/migrations/20220802204737_remove_deactivated_user_highest_role_stats_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RemoveDeactivatedUserHighestRoleStats do + let!(:users) { table(:users) } + let!(:user_highest_roles) { table(:user_highest_roles) } + + let!(:user1) do + users.create!(username: 'user1', email: 'user1@example.com', projects_limit: 10, state: 'active') + end + + let!(:user2) do + users.create!(username: 'user2', email: 'user2@example.com', projects_limit: 10, state: 'deactivated') + end + + let!(:highest_role1) { user_highest_roles.create!(user_id: user1.id) } + let!(:highest_role2) { user_highest_roles.create!(user_id: user2.id) } + + describe '#up' do + context 'when on gitlab.com' do + it 'does not change user highest role records' do + allow(Gitlab).to receive(:com?).and_return(true) + expect { migrate! }.not_to change(user_highest_roles, :count) + end + end + + context 'when not on gitlab.com' do + it 'removes all user highest role records for deactivated users' do + allow(Gitlab).to receive(:com?).and_return(false) + migrate! + expect(user_highest_roles.pluck(:user_id)).to contain_exactly( + user1.id + ) + end + 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 index 74429e498df..dd86989912f 100644 --- a/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb +++ b/spec/migrations/associate_existing_dast_builds_with_variables_spec.rb @@ -4,73 +4,7 @@ require 'spec_helper' require_migration! RSpec.describe AssociateExistingDastBuildsWithVariables do - subject(:migration) { described_class.new } - - let_it_be(:namespaces_table) { table(:namespaces) } - let_it_be(:projects_table) { table(:projects) } - let_it_be(:ci_pipelines_table) { table(:ci_pipelines) } - let_it_be(:ci_builds_table) { table(:ci_builds) } - let_it_be(:dast_sites_table) { table(:dast_sites) } - let_it_be(:dast_site_profiles_table) { table(:dast_site_profiles) } - let_it_be(:dast_scanner_profiles_table) { table(:dast_scanner_profiles) } - let_it_be(:dast_site_profiles_builds_table) { table(:dast_site_profiles_builds) } - let_it_be(:dast_profiles_table) { table(:dast_profiles) } - let_it_be(:dast_profiles_pipelines_table) { table(:dast_profiles_pipelines) } - - let!(:group) { namespaces_table.create!(type: 'Group', name: 'group', path: 'group') } - let!(:project) { projects_table.create!(name: 'project', path: 'project', namespace_id: group.id) } - - let!(:pipeline_0) { ci_pipelines_table.create!(project_id: project.id, source: 13) } - let!(:pipeline_1) { ci_pipelines_table.create!(project_id: project.id, source: 13) } - let!(:build_0) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_0.id, name: :dast, stage: :dast) } - let!(:build_1) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_0.id, name: :dast, stage: :dast) } - let!(:build_2) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_1.id, name: :dast, stage: :dast) } - let!(:build_3) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_1.id, name: :dast) } - let!(:build_4) { ci_builds_table.create!(project_id: project.id, commit_id: pipeline_1.id, stage: :dast) } - - let!(:dast_site) { dast_sites_table.create!(project_id: project.id, url: generate(:url)) } - let!(:dast_site_profile) { dast_site_profiles_table.create!(project_id: project.id, dast_site_id: dast_site.id, name: SecureRandom.hex) } - let!(:dast_scanner_profile) { dast_scanner_profiles_table.create!(project_id: project.id, name: SecureRandom.hex) } - - let!(:dast_profile) do - dast_profiles_table.create!( - project_id: project.id, - dast_site_profile_id: dast_site_profile.id, - dast_scanner_profile_id: dast_scanner_profile.id, - name: SecureRandom.hex, - description: SecureRandom.hex - ) - end - - let!(:dast_profiles_pipeline_0) { dast_profiles_pipelines_table.create!(dast_profile_id: dast_profile.id, ci_pipeline_id: pipeline_0.id) } - let!(:dast_profiles_pipeline_1) { dast_profiles_pipelines_table.create!(dast_profile_id: dast_profile.id, ci_pipeline_id: pipeline_1.id) } - - context 'when there are ci_pipelines with associated dast_profiles' do - describe 'migration up' do - it 'adds association of dast_site_profiles to ci_builds', :aggregate_failures do - expect(dast_site_profiles_builds_table.all).to be_empty - - migration.up - - expected_results = [ - [dast_site_profile.id, build_0.id], - [dast_site_profile.id, build_1.id], - [dast_site_profile.id, build_2.id] - ] - - expect(dast_site_profiles_builds_table.all.map { |assoc| [assoc.dast_site_profile_id, assoc.ci_build_id] }).to contain_exactly(*expected_results) - end - end - end - - describe 'migration down' do - it 'deletes all records in the dast_site_profiles_builds table', :aggregate_failures do - expect(dast_site_profiles_builds_table.all).to be_empty - - migration.up - migration.down - - expect(dast_site_profiles_builds_table.all).to be_empty - end + it 'is a no-op' do + migrate! end end diff --git a/spec/migrations/backfill_project_import_level_spec.rb b/spec/migrations/backfill_project_import_level_spec.rb new file mode 100644 index 00000000000..c24ddac0730 --- /dev/null +++ b/spec/migrations/backfill_project_import_level_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe BackfillProjectImportLevel do + let_it_be(:batched_migration) { described_class::MIGRATION } + + describe '#up' do + it 'schedules background jobs for each batch of namespaces' do + migrate! + + expect(batched_migration).to have_scheduled_batched_migration( + table_name: :namespaces, + column_name: :id, + interval: described_class::INTERVAL + ) + end + end + + describe '#down' do + it 'deletes all batched migration records' do + migrate! + schema_migrate_down! + + expect(batched_migration).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/change_public_projects_cost_factor_spec.rb b/spec/migrations/change_public_projects_cost_factor_spec.rb index 78030736093..039edda750b 100644 --- a/spec/migrations/change_public_projects_cost_factor_spec.rb +++ b/spec/migrations/change_public_projects_cost_factor_spec.rb @@ -3,16 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe ChangePublicProjectsCostFactor, :migration do - # This is a workaround to force the migration to run against the - # `gitlab_ci` schema. Otherwise it only runs against `gitlab_main`. - around do |example| # rubocop: disable Style/MultilineIfModifier - with_reestablished_active_record_base do - reconfigure_db_connection(name: :ci) - example.run - end - end if Gitlab::Database.has_config?(:ci) - +RSpec.describe ChangePublicProjectsCostFactor, migration: :gitlab_ci do let(:runners) { table(:ci_runners) } let!(:shared_1) { runners.create!(runner_type: 1, public_projects_minutes_cost_factor: 0) } diff --git a/spec/migrations/clean_up_pending_builds_table_spec.rb b/spec/migrations/clean_up_pending_builds_table_spec.rb index 9c8d4413337..17e62e1b486 100644 --- a/spec/migrations/clean_up_pending_builds_table_spec.rb +++ b/spec/migrations/clean_up_pending_builds_table_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe CleanUpPendingBuildsTable do +RSpec.describe CleanUpPendingBuildsTable, :suppress_gitlab_schemas_validate_connection do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:queue) { table(:ci_pending_builds) } diff --git a/spec/migrations/cleanup_mr_attention_request_todos_spec.rb b/spec/migrations/cleanup_mr_attention_request_todos_spec.rb new file mode 100644 index 00000000000..9f593ca8292 --- /dev/null +++ b/spec/migrations/cleanup_mr_attention_request_todos_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe CleanupMrAttentionRequestTodos, :migration do + let(:projects) { table(:projects) } + let(:namespaces) { table(:namespaces) } + let(:users) { table(:users) } + let(:todos) { table(:todos) } + + let(:author) { users.create!(projects_limit: 1) } + let(:namespace) { namespaces.create!(name: 'test', path: 'test') } + let(:project) do + projects.create!( + namespace_id: namespace.id, + project_namespace_id: namespace.id, + name: 'test-project' + ) + end + + let(:attention_requested) { 10 } + let(:todo_attrs) do + { + project_id: project.id, + author_id: author.id, + user_id: author.id, + target_type: 'TestType', + state: 'pending' + } + end + + let!(:todo1) { todos.create!(todo_attrs.merge(action: Todo::ASSIGNED)) } + let!(:todo2) { todos.create!(todo_attrs.merge(action: Todo::MENTIONED)) } + let!(:todo3) { todos.create!(todo_attrs.merge(action: Todo::REVIEW_REQUESTED)) } + let!(:todo4) { todos.create!(todo_attrs.merge(action: attention_requested)) } + let!(:todo5) { todos.create!(todo_attrs.merge(action: attention_requested)) } + + describe '#up' do + it 'clean up attention request todos' do + expect { migrate! }.to change(todos, :count).by(-2) + + expect(todos.all).to include(todo1, todo2, todo3) + end + end +end diff --git a/spec/migrations/delete_security_findings_without_uuid_spec.rb b/spec/migrations/delete_security_findings_without_uuid_spec.rb index b32ea89f8aa..bfd89f1aa82 100644 --- a/spec/migrations/delete_security_findings_without_uuid_spec.rb +++ b/spec/migrations/delete_security_findings_without_uuid_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe DeleteSecurityFindingsWithoutUuid do +RSpec.describe DeleteSecurityFindingsWithoutUuid, :suppress_gitlab_schemas_validate_connection do let(:users) { table(:users) } let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } diff --git a/spec/migrations/disable_job_token_scope_when_unused_spec.rb b/spec/migrations/disable_job_token_scope_when_unused_spec.rb index d969c98aa0f..3ce4ef5c102 100644 --- a/spec/migrations/disable_job_token_scope_when_unused_spec.rb +++ b/spec/migrations/disable_job_token_scope_when_unused_spec.rb @@ -4,41 +4,7 @@ require 'spec_helper' require_migration! RSpec.describe DisableJobTokenScopeWhenUnused do - let(:ci_cd_settings) { table(:project_ci_cd_settings) } - let(:links) { table(:ci_job_token_project_scope_links) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - - let(:namespace) { namespaces.create!(name: 'test', path: 'path', type: 'Group') } - - let(:project_with_used_scope) { projects.create!(namespace_id: namespace.id) } - let!(:used_scope_settings) { ci_cd_settings.create!(project_id: project_with_used_scope.id, job_token_scope_enabled: true) } - let(:target_project) { projects.create!(namespace_id: namespace.id) } - let!(:link) { links.create!(source_project_id: project_with_used_scope.id, target_project_id: target_project.id) } - - let(:project_with_unused_scope) { projects.create!(namespace_id: namespace.id) } - let!(:unused_scope_settings) { ci_cd_settings.create!(project_id: project_with_unused_scope.id, job_token_scope_enabled: true) } - - let(:project_with_disabled_scope) { projects.create!(namespace_id: namespace.id) } - let!(:disabled_scope_settings) { ci_cd_settings.create!(project_id: project_with_disabled_scope.id, job_token_scope_enabled: false) } - - describe '#up' do - it 'sets job_token_scope_enabled to false for projects not having job token scope configured' do - migrate! - - expect(unused_scope_settings.reload.job_token_scope_enabled).to be_falsey - end - - it 'keeps the scope enabled for projects that are using it' do - migrate! - - expect(used_scope_settings.reload.job_token_scope_enabled).to be_truthy - end - - it 'keeps the scope disabled for projects having it disabled' do - migrate! - - expect(disabled_scope_settings.reload.job_token_scope_enabled).to be_falsey - end + it 'is a no-op' do + migrate! 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 index 2108adcc973..01805a9eb79 100644 --- a/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb +++ b/spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe MigrateProtectedAttributeToPendingBuilds do +RSpec.describe MigrateProtectedAttributeToPendingBuilds, :suppress_gitlab_schemas_validate_connection do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:queue) { table(:ci_pending_builds) } 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 index 8a9b993b869..45a2772adda 100644 --- 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 @@ -3,7 +3,8 @@ require 'spec_helper' require_migration! -RSpec.describe ReScheduleLatestPipelineIdPopulationWithAllSecurityRelatedArtifactTypes do +RSpec.describe ReScheduleLatestPipelineIdPopulationWithAllSecurityRelatedArtifactTypes, + :suppress_gitlab_schemas_validate_connection do let(:namespaces) { table(:namespaces) } let(:pipelines) { table(:ci_pipelines) } let(:projects) { table(:projects) } diff --git a/spec/migrations/schedule_backfilling_the_namespace_id_for_vulnerability_reads_spec.rb b/spec/migrations/schedule_backfilling_the_namespace_id_for_vulnerability_reads_spec.rb new file mode 100644 index 00000000000..e03096de98d --- /dev/null +++ b/spec/migrations/schedule_backfilling_the_namespace_id_for_vulnerability_reads_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe ScheduleBackfillingTheNamespaceIdForVulnerabilityReads do + let_it_be(:migration) { described_class::MIGRATION_NAME } + + describe '#up' do + it 'schedules background jobs for each batch of vulnerabilities' do + migrate! + + expect(migration).to have_scheduled_batched_migration( + table_name: :vulnerability_reads, + column_name: :vulnerability_id, + interval: 2.minutes, + batch_size: 10_000, + sub_batch_size: 200 + ) + 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 index 012c7d065fc..67d54ea92a0 100644 --- 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 @@ -4,49 +4,7 @@ require 'spec_helper' require_migration! RSpec.describe ScheduleCopyCiBuildsColumnsToSecurityScans2 do - let_it_be(:namespaces) { table(:namespaces) } - let_it_be(:projects) { table(:projects) } - let_it_be(:ci_pipelines) { table(:ci_pipelines) } - let_it_be(:ci_builds) { table(:ci_builds) } - let_it_be(:security_scans) { table(:security_scans) } - let_it_be(:background_migration_jobs) { table(:background_migration_jobs) } - - let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') } - let!(:project) { projects.create!(namespace_id: namespace.id) } - let!(:pipeline) { ci_pipelines.create!(status: "success")} - - let!(:build1) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) } - let!(:build2) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) } - let!(:build3) { ci_builds.create!(commit_id: pipeline.id, type: 'Ci::Build', project_id: project.id) } - - let!(:scan1) { security_scans.create!(build_id: build1.id, scan_type: 1) } - let!(:scan2) { security_scans.create!(build_id: build2.id, scan_type: 1) } - let!(:scan3) { security_scans.create!(build_id: build3.id, scan_type: 1) } - - let!(:job_class_name) { described_class::MIGRATION } - let!(:tracked_pending_job) { background_migration_jobs.create!(class_name: job_class_name, status: 0, arguments: [1]) } - let!(:tracked_successful_job) { background_migration_jobs.create!(class_name: job_class_name, status: 1, arguments: [2]) } - let(:jobs) { Gitlab::Database::BackgroundMigrationJob.where(id: [tracked_pending_job.id, tracked_successful_job.id] ).for_migration_class(job_class_name) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 2) - allow_next_instance_of(Gitlab::BackgroundMigration::CopyCiBuildsColumnsToSecurityScans) do |instance| - allow(instance).to receive(:mark_job_as_succeeded) - end - end - - around do |example| - freeze_time { Sidekiq::Testing.fake! { example.run } } - end - - it 'schedules background migrations', :aggregate_failures do - expect(jobs).not_to be_empty - + it 'is a no-op' do migrate! - - expect(jobs).to be_empty - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, scan1.id, scan2.id) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, scan3.id, scan3.id) end end diff --git a/spec/migrations/schedule_migrate_shared_vulnerability_scanners_spec.rb b/spec/migrations/schedule_migrate_shared_vulnerability_scanners_spec.rb new file mode 100644 index 00000000000..f00d6568b67 --- /dev/null +++ b/spec/migrations/schedule_migrate_shared_vulnerability_scanners_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "spec_helper" + +require_migration! + +RSpec.describe ScheduleMigrateSharedVulnerabilityScanners, :migration do + describe "#up" do + before do + migrate! + end + + it "schedules" do + expect(described_class::MIGRATION).to have_scheduled_batched_migration( + table_name: described_class::TABLE_NAME, + column_name: described_class::BATCH_COLUMN, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + max_batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE, + gitlab_schema: :gitlab_main + ) + end + + describe "ID range" do + let(:expected_range) do + { min_value: described_class::BATCH_MIN_VALUE, + max_value: described_class::BATCH_MAX_VALUE } + end + + subject do + Gitlab::Database::BackgroundMigration::BatchedMigration + .for_configuration(:gitlab_main, + described_class::MIGRATION, + described_class::TABLE_NAME, + described_class::BATCH_COLUMN, + []) + end + + it "is set" do + # The `have_scheduled_batched_migration` matcher accepts the + # `batch_min_value` and `batch_max_value` keywords. However the respective + # column names are `min_value` and `max_value`. Hence the matcher cannot + # be used in this case, as it asserts the wrong attributes. + expect(subject).to all(have_attributes(expected_range)) + end + end + end + + describe '#down' do + before do + schema_migrate_down! + end + + it "deletes" do + expect(described_class::MIGRATION).not_to have_scheduled_batched_migration + end + end +end diff --git a/spec/migrations/schedule_populate_status_column_of_security_scans_spec.rb b/spec/migrations/schedule_populate_status_column_of_security_scans_spec.rb deleted file mode 100644 index 601935db8db..00000000000 --- a/spec/migrations/schedule_populate_status_column_of_security_scans_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe SchedulePopulateStatusColumnOfSecurityScans do - before do - allow(Gitlab).to receive(:ee?).and_return(ee?) - stub_const("#{described_class.name}::BATCH_SIZE", 1) - end - - context 'when the Gitlab instance is CE' do - let(:ee?) { false } - - it 'does not run the migration' do - expect { migrate! }.not_to change { BackgroundMigrationWorker.jobs.size } - end - end - - context 'when the Gitlab instance is EE' do - let(:ee?) { true } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:pipelines) { table(:ci_pipelines) } - let(:builds) { table(:ci_builds) } - let(:security_scans) { table(:security_scans) } - - let(:namespace) { namespaces.create!(name: "foo", path: "bar") } - let(:project) { projects.create!(namespace_id: namespace.id) } - let(:pipeline) { pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success') } - let(:ci_build) { builds.create!(commit_id: pipeline.id, retried: false, type: 'Ci::Build') } - - let!(:security_scan_1) { security_scans.create!(build_id: ci_build.id, scan_type: 1) } - let!(:security_scan_2) { security_scans.create!(build_id: ci_build.id, scan_type: 2) } - - around do |example| - freeze_time { Sidekiq::Testing.fake! { example.run } } - end - - it 'schedules the background jobs', :aggregate_failures do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to be(2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, security_scan_1.id, security_scan_1.id) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, security_scan_2.id, security_scan_2.id) - end - end -end diff --git a/spec/migrations/start_backfill_ci_queuing_tables_spec.rb b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb index a1e4179efb6..08fd244089f 100644 --- a/spec/migrations/start_backfill_ci_queuing_tables_spec.rb +++ b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_migration! -RSpec.describe StartBackfillCiQueuingTables do +RSpec.describe StartBackfillCiQueuingTables, :suppress_gitlab_schemas_validate_connection do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:builds) { table(:ci_builds) } |