From 9dc93a4519d9d5d7be48ff274127136236a3adb3 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 20 Apr 2021 23:50:22 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-11-stable-ee --- .../20210226141517_dedup_issue_metrics_spec.rb | 66 +++++++++++++++ ...otal_tuple_count_for_batched_migrations_spec.rb | 43 ++++++++++ ...schedule_artifact_expiry_backfill_again_spec.rb | 38 +++++++++ spec/migrations/add_new_trail_plans_spec.rb | 95 ++++++++++++++++++++++ ...ackfill_operations_feature_flags_active_spec.rb | 4 +- .../backfill_operations_feature_flags_iid_spec.rb | 4 +- ...ean_up_noteable_id_for_notes_on_commits_spec.rb | 2 +- spec/migrations/confirm_support_bot_user_spec.rb | 86 ++++++++++++++++++++ ..._internal_ids_where_feature_flags_usage_spec.rb | 4 +- .../delete_security_findings_without_uuid_spec.rb | 35 ++++++++ .../migrate_bot_type_to_user_type_spec.rb | 2 +- .../migrate_elastic_index_settings_spec.rb | 44 ++++++++++ ...ps_feature_flags_scopes_target_user_ids_spec.rb | 4 +- ...r_registry_enabled_to_project_features2_spec.rb | 47 +++++++++++ ...er_registry_enabled_to_project_features_spec.rb | 43 ---------- ...smissal_information_for_vulnerabilities_spec.rb | 61 ++++++++++++++ ...cords_without_group_from_webhooks_table_spec.rb | 27 ++++++ .../schedule_migrate_pages_to_zip_storage_spec.rb | 46 +++++++++++ 18 files changed, 594 insertions(+), 57 deletions(-) create mode 100644 spec/migrations/20210226141517_dedup_issue_metrics_spec.rb create mode 100644 spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb create mode 100644 spec/migrations/20210413132500_reschedule_artifact_expiry_backfill_again_spec.rb create mode 100644 spec/migrations/add_new_trail_plans_spec.rb create mode 100644 spec/migrations/confirm_support_bot_user_spec.rb create mode 100644 spec/migrations/delete_security_findings_without_uuid_spec.rb create mode 100644 spec/migrations/migrate_elastic_index_settings_spec.rb create mode 100644 spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb delete mode 100644 spec/migrations/move_container_registry_enabled_to_project_features_spec.rb create mode 100644 spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb create mode 100644 spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb create mode 100644 spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb (limited to 'spec/migrations') diff --git a/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb b/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb new file mode 100644 index 00000000000..043884eb7b2 --- /dev/null +++ b/spec/migrations/20210226141517_dedup_issue_metrics_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20210226141517_dedup_issue_metrics.rb') + +RSpec.describe DedupIssueMetrics, :migration, schema: 20210205104425 do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:issues) { table(:issues) } + let(:metrics) { table(:issue_metrics) } + let(:issue_params) { { title: 'title', project_id: project.id } } + + let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') } + let!(:project) { projects.create!(namespace_id: namespace.id) } + let!(:issue_1) { issues.create!(issue_params) } + let!(:issue_2) { issues.create!(issue_params) } + let!(:issue_3) { issues.create!(issue_params) } + + let!(:duplicated_metrics_1) { metrics.create!(issue_id: issue_1.id, first_mentioned_in_commit_at: 1.day.ago, first_added_to_board_at: 5.days.ago, updated_at: 2.months.ago) } + let!(:duplicated_metrics_2) { metrics.create!(issue_id: issue_1.id, first_mentioned_in_commit_at: Time.now, first_associated_with_milestone_at: Time.now, updated_at: 1.month.ago) } + + let!(:duplicated_metrics_3) { metrics.create!(issue_id: issue_3.id, first_mentioned_in_commit_at: 1.day.ago, updated_at: 2.months.ago) } + let!(:duplicated_metrics_4) { metrics.create!(issue_id: issue_3.id, first_added_to_board_at: 1.day.ago, updated_at: 1.month.ago) } + + let!(:non_duplicated_metrics) { metrics.create!(issue_id: issue_2.id, first_added_to_board_at: 2.days.ago) } + + it 'deduplicates issue_metrics table' do + expect { migrate! }.to change { metrics.count }.from(5).to(3) + end + + it 'merges `duplicated_metrics_1` with `duplicated_metrics_2`' do + migrate! + + expect(metrics.where(id: duplicated_metrics_1.id)).not_to exist + + merged_metrics = metrics.find_by(id: duplicated_metrics_2.id) + + expect(merged_metrics).to be_present + expect(merged_metrics.first_mentioned_in_commit_at).to be_like_time(duplicated_metrics_2.first_mentioned_in_commit_at) + expect(merged_metrics.first_added_to_board_at).to be_like_time(duplicated_metrics_1.first_added_to_board_at) + end + + it 'merges `duplicated_metrics_3` with `duplicated_metrics_4`' do + migrate! + + expect(metrics.where(id: duplicated_metrics_3.id)).not_to exist + + merged_metrics = metrics.find_by(id: duplicated_metrics_4.id) + + expect(merged_metrics).to be_present + expect(merged_metrics.first_mentioned_in_commit_at).to be_like_time(duplicated_metrics_3.first_mentioned_in_commit_at) + expect(merged_metrics.first_added_to_board_at).to be_like_time(duplicated_metrics_4.first_added_to_board_at) + end + + it 'does not change non duplicated records' do + expect { migrate! }.not_to change { non_duplicated_metrics.reload.attributes } + end + + it 'does nothing when there are no metrics' do + metrics.delete_all + + migrate! + + expect(metrics.count).to eq(0) + end +end diff --git a/spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb b/spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb new file mode 100644 index 00000000000..e1727cb2a1c --- /dev/null +++ b/spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20210406144743_backfill_total_tuple_count_for_batched_migrations.rb') + +RSpec.describe BackfillTotalTupleCountForBatchedMigrations, :migration, schema: 20210406140057 do + let_it_be(:table_name) { 'projects' } + + let_it_be(:migrations) { table(:batched_background_migrations) } + + let_it_be(:migration) do + migrations.create!( + created_at: Time.now, + updated_at: Time.now, + min_value: 1, + max_value: 10_000, + batch_size: 1_000, + sub_batch_size: 100, + interval: 120, + status: 0, + job_class_name: 'Foo', + table_name: table_name, + column_name: :id, + total_tuple_count: nil + ) + end + + describe '#up' do + before do + expect(Gitlab::Database::PgClass).to receive(:for_table).with(table_name).and_return(estimate) + end + + let(:estimate) { double('estimate', cardinality_estimate: 42) } + + it 'updates total_tuple_count attribute' do + migrate! + + migrations.all.each do |migration| + expect(migration.total_tuple_count).to eq(estimate.cardinality_estimate) + end + end + end +end diff --git a/spec/migrations/20210413132500_reschedule_artifact_expiry_backfill_again_spec.rb b/spec/migrations/20210413132500_reschedule_artifact_expiry_backfill_again_spec.rb new file mode 100644 index 00000000000..4f36a95f9cf --- /dev/null +++ b/spec/migrations/20210413132500_reschedule_artifact_expiry_backfill_again_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require Rails.root.join('db', 'post_migrate', '20210413132500_reschedule_artifact_expiry_backfill_again.rb') + +RSpec.describe RescheduleArtifactExpiryBackfillAgain, :migration do + let(:migration_class) { Gitlab::BackgroundMigration::BackfillArtifactExpiryDate } + let(:migration_name) { migration_class.to_s.demodulize } + + before do + table(:namespaces).create!(id: 123, name: 'test_namespace', path: 'test_namespace') + table(:projects).create!(id: 123, name: 'sample_project', path: 'sample_project', namespace_id: 123) + end + + it 'correctly schedules background migrations' do + first_artifact = create_artifact(job_id: 0, expire_at: nil, created_at: Date.new(2020, 06, 21)) + second_artifact = create_artifact(job_id: 1, expire_at: nil, created_at: Date.new(2020, 06, 21)) + create_artifact(job_id: 2, expire_at: Date.yesterday, created_at: Date.new(2020, 06, 21)) + create_artifact(job_id: 3, expire_at: nil, created_at: Date.new(2020, 06, 23)) + + Sidekiq::Testing.fake! do + freeze_time do + migrate! + + expect(BackgroundMigrationWorker.jobs.size).to eq(1) + expect(migration_name).to be_scheduled_migration_with_multiple_args(first_artifact.id, second_artifact.id) + end + end + end + + private + + def create_artifact(params) + table(:ci_builds).create!(id: params[:job_id], project_id: 123) + table(:ci_job_artifacts).create!(project_id: 123, file_type: 1, **params) + end +end diff --git a/spec/migrations/add_new_trail_plans_spec.rb b/spec/migrations/add_new_trail_plans_spec.rb new file mode 100644 index 00000000000..8ba6da11ad1 --- /dev/null +++ b/spec/migrations/add_new_trail_plans_spec.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe AddNewTrailPlans, :migration do + describe '#up' do + before do + allow(Gitlab).to receive(:dev_env_or_com?).and_return true + end + + it 'creates 2 entries within the plans table' do + expect { migrate! }.to change { AddNewTrailPlans::Plan.count }.by 2 + expect(AddNewTrailPlans::Plan.last(2).pluck(:name)).to match_array(%w(ultimate_trial premium_trial)) + end + + it 'creates 2 entries for plan limits' do + expect { migrate! }.to change { AddNewTrailPlans::PlanLimits.count }.by 2 + end + + context 'when the plan limits for gold and silver exists' do + before do + table(:plans).create!(id: 1, name: 'gold', title: 'Gold') + table(:plan_limits).create!(id: 1, plan_id: 1, storage_size_limit: 2000) + table(:plans).create!(id: 2, name: 'silver', title: 'Silver') + table(:plan_limits).create!(id: 2, plan_id: 2, storage_size_limit: 1000) + end + + it 'duplicates the gold and silvers plan limits entries' do + migrate! + + ultimate_plan_limits = AddNewTrailPlans::Plan.find_by(name: 'ultimate_trial').limits + expect(ultimate_plan_limits.storage_size_limit).to be 2000 + + premium_plan_limits = AddNewTrailPlans::Plan.find_by(name: 'premium_trial').limits + expect(premium_plan_limits.storage_size_limit).to be 1000 + end + end + + context 'when the instance is not SaaS' do + before do + allow(Gitlab).to receive(:dev_env_or_com?).and_return false + end + + it 'does not create plans and plan limits and returns' do + expect { migrate! }.not_to change { AddNewTrailPlans::Plan.count } + expect { migrate! }.not_to change { AddNewTrailPlans::Plan.count } + end + end + end + + describe '#down' do + before do + table(:plans).create!(id: 3, name: 'other') + table(:plan_limits).create!(plan_id: 3) + end + + context 'when the instance is SaaS' do + before do + allow(Gitlab).to receive(:dev_env_or_com?).and_return true + end + + it 'removes the newly added ultimate and premium trial entries' do + migrate! + + expect { described_class.new.down }.to change { AddNewTrailPlans::Plan.count }.by(-2) + expect(AddNewTrailPlans::Plan.find_by(name: 'premium_trial')).to be_nil + expect(AddNewTrailPlans::Plan.find_by(name: 'ultimate_trial')).to be_nil + + other_plan = AddNewTrailPlans::Plan.find_by(name: 'other') + expect(other_plan).to be_persisted + expect(AddNewTrailPlans::PlanLimits.count).to eq(1) + expect(AddNewTrailPlans::PlanLimits.first.plan_id).to eq(other_plan.id) + end + end + + context 'when the instance is not SaaS' do + before do + allow(Gitlab).to receive(:dev_env_or_com?).and_return false + table(:plans).create!(id: 1, name: 'ultimate_trial', title: 'Ultimate Trial') + table(:plans).create!(id: 2, name: 'premium_trial', title: 'Premium Trial') + table(:plan_limits).create!(id: 1, plan_id: 1) + table(:plan_limits).create!(id: 2, plan_id: 2) + end + + it 'does not delete plans and plan limits and returns' do + migrate! + + expect { described_class.new.down }.not_to change { AddNewTrailPlans::Plan.count } + expect(AddNewTrailPlans::PlanLimits.count).to eq(3) + end + end + end +end diff --git a/spec/migrations/backfill_operations_feature_flags_active_spec.rb b/spec/migrations/backfill_operations_feature_flags_active_spec.rb index 4ec2a4a2a92..e49b317d850 100644 --- a/spec/migrations/backfill_operations_feature_flags_active_spec.rb +++ b/spec/migrations/backfill_operations_feature_flags_active_spec.rb @@ -10,9 +10,7 @@ RSpec.describe BackfillOperationsFeatureFlagsActive do def setup namespace = namespaces.create!(name: 'foo', path: 'foo') - project = projects.create!(namespace_id: namespace.id) - - project + projects.create!(namespace_id: namespace.id) end it 'executes successfully when there are no flags in the table' do diff --git a/spec/migrations/backfill_operations_feature_flags_iid_spec.rb b/spec/migrations/backfill_operations_feature_flags_iid_spec.rb index bafe5830652..1ade08f657e 100644 --- a/spec/migrations/backfill_operations_feature_flags_iid_spec.rb +++ b/spec/migrations/backfill_operations_feature_flags_iid_spec.rb @@ -10,9 +10,7 @@ RSpec.describe BackfillOperationsFeatureFlagsIid do def setup namespace = namespaces.create!(name: 'foo', path: 'foo') - project = projects.create!(namespace_id: namespace.id) - - project + projects.create!(namespace_id: namespace.id) end it 'migrates successfully when there are no flags in the database' do diff --git a/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb b/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb index 531c1dbb76a..268fadee0af 100644 --- a/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb +++ b/spec/migrations/clean_up_noteable_id_for_notes_on_commits_spec.rb @@ -25,7 +25,7 @@ RSpec.describe CleanUpNoteableIdForNotesOnCommits do end def dirty_notes_on_commits - notes.where(noteable_type: 'Commit').where('noteable_id IS NOT NULL') + notes.where(noteable_type: 'Commit').where.not(noteable_id: nil) end def other_notes diff --git a/spec/migrations/confirm_support_bot_user_spec.rb b/spec/migrations/confirm_support_bot_user_spec.rb new file mode 100644 index 00000000000..f6bcab4aa7d --- /dev/null +++ b/spec/migrations/confirm_support_bot_user_spec.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ConfirmSupportBotUser, :migration do + let(:users) { table(:users) } + + context 'when support bot user is currently unconfirmed' do + let!(:support_bot) do + create_user!( + created_at: 2.days.ago, + user_type: User::USER_TYPES['support_bot'] + ) + end + + it 'updates the `confirmed_at` attribute' do + expect { migrate! }.to change { support_bot.reload.confirmed_at } + end + + it 'sets `confirmed_at` to be the same as their `created_at` attribute' do + migrate! + + expect(support_bot.reload.confirmed_at).to eq(support_bot.created_at) + end + end + + context 'when support bot user is already confirmed' do + let!(:confirmed_support_bot) do + create_user!( + user_type: User::USER_TYPES['support_bot'], + confirmed_at: 1.day.ago + ) + end + + it 'does not change their `confirmed_at` attribute' do + expect { migrate! }.not_to change { confirmed_support_bot.reload.confirmed_at } + end + end + + context 'when support bot user created_at is null' do + let!(:support_bot) do + create_user!( + user_type: User::USER_TYPES['support_bot'], + confirmed_at: nil, + record_timestamps: false + ) + end + + it 'updates the `confirmed_at` attribute' do + expect { migrate! }.to change { support_bot.reload.confirmed_at }.from(nil) + end + + it 'does not change the `created_at` attribute' do + expect { migrate!}.not_to change { support_bot.reload.created_at }.from(nil) + end + end + + context 'with human users that are currently unconfirmed' do + let!(:unconfirmed_human) do + create_user!( + name: 'human', + email: 'human@example.com', + user_type: nil + ) + end + + it 'does not update their `confirmed_at` attribute' do + expect { migrate! }.not_to change { unconfirmed_human.reload.confirmed_at } + end + end + + private + + def create_user!(name: 'GitLab Support Bot', email: 'support@example.com', user_type:, created_at: Time.now, confirmed_at: nil, record_timestamps: true) + users.create!( + name: name, + email: email, + username: name, + projects_limit: 0, + user_type: user_type, + confirmed_at: confirmed_at, + record_timestamps: record_timestamps + ) + end +end diff --git a/spec/migrations/delete_internal_ids_where_feature_flags_usage_spec.rb b/spec/migrations/delete_internal_ids_where_feature_flags_usage_spec.rb index a58121fb708..50b5897220a 100644 --- a/spec/migrations/delete_internal_ids_where_feature_flags_usage_spec.rb +++ b/spec/migrations/delete_internal_ids_where_feature_flags_usage_spec.rb @@ -10,9 +10,7 @@ RSpec.describe DeleteInternalIdsWhereFeatureFlagsUsage do def setup namespace = namespaces.create!(name: 'foo', path: 'foo') - project = projects.create!(namespace_id: namespace.id) - - project + projects.create!(namespace_id: namespace.id) end it 'deletes feature flag rows from the internal_ids table' do diff --git a/spec/migrations/delete_security_findings_without_uuid_spec.rb b/spec/migrations/delete_security_findings_without_uuid_spec.rb new file mode 100644 index 00000000000..b32ea89f8aa --- /dev/null +++ b/spec/migrations/delete_security_findings_without_uuid_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe DeleteSecurityFindingsWithoutUuid do + let(:users) { table(:users) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:ci_pipelines) { table(:ci_pipelines) } + let(:ci_builds) { table(:ci_builds) } + let(:ci_artifacts) { table(:ci_job_artifacts) } + let(:scanners) { table(:vulnerability_scanners) } + let(:security_scans) { table(:security_scans) } + let(:security_findings) { table(:security_findings) } + let(:sast_file_type) { 5 } + let(:sast_scan_type) { 1 } + + let(:user) { users.create!(email: 'test@gitlab.com', projects_limit: 5) } + let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } + let(:project) { projects.create!(namespace_id: namespace.id, name: 'foo') } + let(:ci_pipeline) { ci_pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success') } + let(:ci_build) { ci_builds.create!(commit_id: ci_pipeline.id, retried: false, type: 'Ci::Build') } + let(:ci_artifact) { ci_artifacts.create!(project_id: project.id, job_id: ci_build.id, file_type: sast_file_type, file_format: 1) } + let(:scanner) { scanners.create!(project_id: project.id, external_id: 'bandit', name: 'Bandit') } + let(:security_scan) { security_scans.create!(build_id: ci_build.id, scan_type: sast_scan_type) } + + let!(:finding_1) { security_findings.create!(scan_id: security_scan.id, scanner_id: scanner.id, severity: 0, confidence: 0, project_fingerprint: Digest::SHA1.hexdigest(SecureRandom.uuid)) } + let!(:finding_2) { security_findings.create!(scan_id: security_scan.id, scanner_id: scanner.id, severity: 0, confidence: 0, project_fingerprint: Digest::SHA1.hexdigest(SecureRandom.uuid), uuid: SecureRandom.uuid) } + + it 'successfully runs and does not schedule any job' do + expect { migrate! }.to change { described_class::SecurityFinding.count }.by(-1) + .and change { described_class::SecurityFinding.where(id: finding_1) } + end +end diff --git a/spec/migrations/migrate_bot_type_to_user_type_spec.rb b/spec/migrations/migrate_bot_type_to_user_type_spec.rb index 2b85f2a7f69..fcd7f1ebcb8 100644 --- a/spec/migrations/migrate_bot_type_to_user_type_spec.rb +++ b/spec/migrations/migrate_bot_type_to_user_type_spec.rb @@ -15,6 +15,6 @@ RSpec.describe MigrateBotTypeToUserType, :migration do migrate! - expect(users.where('user_type IS NOT NULL').map(&:user_type)).to match_array([1, 2, 3]) + expect(users.where.not(user_type: nil).map(&:user_type)).to match_array([1, 2, 3]) end end diff --git a/spec/migrations/migrate_elastic_index_settings_spec.rb b/spec/migrations/migrate_elastic_index_settings_spec.rb new file mode 100644 index 00000000000..41483773903 --- /dev/null +++ b/spec/migrations/migrate_elastic_index_settings_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require Rails.root.join('db', 'migrate', '20210324131727_migrate_elastic_index_settings.rb') + +RSpec.describe MigrateElasticIndexSettings do + let(:elastic_index_settings) { table(:elastic_index_settings) } + let(:application_settings) { table(:application_settings) } + + context 'with application_settings present' do + before do + application_settings.create!(elasticsearch_replicas: 2, elasticsearch_shards: 15) + end + + it 'migrates settings' do + migrate! + + settings = elastic_index_settings.all + + expect(settings.size).to eq 1 + + setting = settings.first + + expect(setting.number_of_replicas).to eq(2) + expect(setting.number_of_shards).to eq(15) + end + end + + context 'without application_settings present' do + it 'migrates settings' do + migrate! + + settings = elastic_index_settings.all + + expect(settings.size).to eq 1 + + setting = elastic_index_settings.first + + expect(setting.number_of_replicas).to eq(1) + expect(setting.number_of_shards).to eq(5) + end + end +end diff --git a/spec/migrations/migrate_ops_feature_flags_scopes_target_user_ids_spec.rb b/spec/migrations/migrate_ops_feature_flags_scopes_target_user_ids_spec.rb index b2c36db2e1d..f066b9c90cd 100644 --- a/spec/migrations/migrate_ops_feature_flags_scopes_target_user_ids_spec.rb +++ b/spec/migrations/migrate_ops_feature_flags_scopes_target_user_ids_spec.rb @@ -12,9 +12,7 @@ RSpec.describe MigrateOpsFeatureFlagsScopesTargetUserIds do def setup namespace = namespaces.create!(name: 'foo', path: 'foo') project = projects.create!(namespace_id: namespace.id) - flag = flags.create!(project_id: project.id, active: true, name: 'test_flag') - - flag + flags.create!(project_id: project.id, active: true, name: 'test_flag') end it 'migrates successfully when there are no scopes in the database' do diff --git a/spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb b/spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb new file mode 100644 index 00000000000..11d43a36bc9 --- /dev/null +++ b/spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20210401131948_move_container_registry_enabled_to_project_features2.rb') + +RSpec.describe MoveContainerRegistryEnabledToProjectFeatures2, :migration do + let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') } + + let!(:projects) do + [ + table(:projects).create!(namespace_id: namespace.id, name: 'project 1'), + table(:projects).create!(namespace_id: namespace.id, name: 'project 2'), + table(:projects).create!(namespace_id: namespace.id, name: 'project 3'), + table(:projects).create!(namespace_id: namespace.id, name: 'project 4') + ] + end + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 3) + end + + around do |example| + Sidekiq::Testing.fake! do + freeze_time do + example.call + end + end + end + + it 'schedules jobs for ranges of projects' do + migrate! + + # Since track_jobs is true, each job should have an entry in the background_migration_jobs + # table. + expect(table(:background_migration_jobs).count).to eq(2) + + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(2.minutes, projects[0].id, projects[2].id) + + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(4.minutes, projects[3].id, projects[3].id) + end + + it 'schedules jobs according to the configured batch size' do + expect { migrate! }.to change { BackgroundMigrationWorker.jobs.size }.by(2) + end +end diff --git a/spec/migrations/move_container_registry_enabled_to_project_features_spec.rb b/spec/migrations/move_container_registry_enabled_to_project_features_spec.rb deleted file mode 100644 index c7b07f3ef37..00000000000 --- a/spec/migrations/move_container_registry_enabled_to_project_features_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20210226120851_move_container_registry_enabled_to_project_features.rb') - -RSpec.describe MoveContainerRegistryEnabledToProjectFeatures, :migration do - let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') } - - let!(:projects) do - [ - table(:projects).create!(namespace_id: namespace.id, name: 'project 1'), - table(:projects).create!(namespace_id: namespace.id, name: 'project 2'), - table(:projects).create!(namespace_id: namespace.id, name: 'project 3'), - table(:projects).create!(namespace_id: namespace.id, name: 'project 4') - ] - end - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 3) - end - - around do |example| - Sidekiq::Testing.fake! do - freeze_time do - example.call - end - end - end - - it 'schedules jobs for ranges of projects' do - migrate! - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(2.minutes, projects[0].id, projects[2].id) - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(4.minutes, projects[3].id, projects[3].id) - end - - it 'schedules jobs according to the configured batch size' do - expect { migrate! }.to change { BackgroundMigrationWorker.jobs.size }.by(2) - end -end diff --git a/spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb b/spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb new file mode 100644 index 00000000000..1db52781956 --- /dev/null +++ b/spec/migrations/populate_dismissal_information_for_vulnerabilities_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe PopulateDismissalInformationForVulnerabilities do + let(:users) { table(:users) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:vulnerabilities) { table(:vulnerabilities) } + + let(:existing_dismissed_at) { Time.now } + let(:states) { { detected: 1, dismissed: 2, resolved: 3, confirmed: 4 } } + let!(:namespace) { namespaces.create!(name: "foo", path: "bar") } + let!(:user_1) { users.create!(name: 'John Doe', email: 'john_doe+1@example.com', projects_limit: 5) } + let!(:user_2) { users.create!(name: 'John Doe', email: 'john_doe+2@example.com', projects_limit: 5) } + let!(:project) { projects.create!(namespace_id: namespace.id) } + let!(:vulnerability_params) do + { + project_id: project.id, + author_id: user_1.id, + title: 'Vulnerability', + severity: 5, + confidence: 5, + report_type: 5 + } + end + + let!(:detected_vulnerability) { vulnerabilities.create!(**vulnerability_params, state: states[:detected]) } + let!(:resolved_vulnerability) { vulnerabilities.create!(**vulnerability_params, state: states[:resolved]) } + let!(:confirmed_vulnerability) { vulnerabilities.create!(**vulnerability_params, state: states[:confirmed]) } + + let!(:dismissed_vulnerability_1) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], updated_by_id: user_2.id) } + let!(:dismissed_vulnerability_2) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], last_edited_by_id: user_2.id) } + let!(:dismissed_vulnerability_3) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], dismissed_at: existing_dismissed_at, author_id: user_2.id) } + let!(:dismissed_vulnerability_4) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], dismissed_by_id: user_1.id, author_id: user_2.id) } + let!(:dismissed_vulnerability_5) { vulnerabilities.create!(**vulnerability_params, state: states[:dismissed], dismissed_at: existing_dismissed_at, dismissed_by_id: user_1.id, updated_by_id: user_2.id) } + + around do |example| + freeze_time { example.run } + end + + it 'updates the dismissal information for vulnerabilities' do + expect { migrate! }.to change { dismissed_vulnerability_1.reload.dismissed_at }.from(nil).to(dismissed_vulnerability_1.updated_at) + .and change { dismissed_vulnerability_1.reload.dismissed_by_id }.from(nil).to(user_2.id) + .and change { dismissed_vulnerability_2.reload.dismissed_at }.from(nil).to(dismissed_vulnerability_2.updated_at) + .and change { dismissed_vulnerability_2.reload.dismissed_by_id }.from(nil).to(user_2.id) + .and change { dismissed_vulnerability_3.reload.dismissed_by_id }.from(nil).to(user_2.id) + .and change { dismissed_vulnerability_4.reload.dismissed_at }.from(nil).to(dismissed_vulnerability_4.updated_at) + .and not_change { dismissed_vulnerability_3.reload.dismissed_at }.from(existing_dismissed_at) + .and not_change { dismissed_vulnerability_4.reload.dismissed_by_id }.from(user_1.id) + .and not_change { dismissed_vulnerability_5.reload.dismissed_at }.from(existing_dismissed_at) + .and not_change { dismissed_vulnerability_5.reload.dismissed_by_id }.from(user_1.id) + .and not_change { detected_vulnerability.reload.dismissed_at }.from(nil) + .and not_change { detected_vulnerability.reload.dismissed_by_id }.from(nil) + .and not_change { resolved_vulnerability.reload.dismissed_at }.from(nil) + .and not_change { resolved_vulnerability.reload.dismissed_by_id }.from(nil) + .and not_change { confirmed_vulnerability.reload.dismissed_at }.from(nil) + .and not_change { confirmed_vulnerability.reload.dismissed_by_id }.from(nil) + end +end diff --git a/spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb b/spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb new file mode 100644 index 00000000000..a28ca12a10d --- /dev/null +++ b/spec/migrations/remove_records_without_group_from_webhooks_table_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! +require Rails.root.join('db', 'migrate', '20210325092215_add_not_valid_foreign_key_to_group_hooks.rb') + +RSpec.describe RemoveRecordsWithoutGroupFromWebhooksTable, schema: 20210330091751 do + let(:web_hooks) { table(:web_hooks) } + let(:groups) { table(:namespaces) } + + before do + group = groups.create!(name: 'gitlab', path: 'gitlab-org') + web_hooks.create!(group_id: group.id, type: 'GroupHook') + web_hooks.create!(group_id: nil) + + AddNotValidForeignKeyToGroupHooks.new.down + web_hooks.create!(group_id: non_existing_record_id, type: 'GroupHook') + AddNotValidForeignKeyToGroupHooks.new.up + end + + it 'removes group hooks where the referenced group does not exist', :aggregate_failures do + expect { RemoveRecordsWithoutGroupFromWebhooksTable.new.up }.to change { web_hooks.count }.by(-1) + expect(web_hooks.where.not(group_id: groups.select(:id)).count).to eq(0) + expect(web_hooks.where.not(group_id: nil).count).to eq(1) + end +end diff --git a/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb b/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb new file mode 100644 index 00000000000..1d35da528e4 --- /dev/null +++ b/spec/migrations/schedule_migrate_pages_to_zip_storage_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20210302150310_schedule_migrate_pages_to_zip_storage.rb') + +RSpec.describe ScheduleMigratePagesToZipStorage, :sidekiq_might_not_need_inline, schema: 20201231133921 do + let(:migration_class) { described_class::MIGRATION } + let(:migration_name) { migration_class.to_s.demodulize } + + let(:namespaces_table) { table(:namespaces) } + let(:projects_table) { table(:projects) } + let(:metadata_table) { table(:project_pages_metadata) } + let(:deployments_table) { table(:pages_deployments) } + + let(:namespace) { namespaces_table.create!(path: "group", name: "group") } + + def create_project_metadata(path, deployed, with_deployment) + project = projects_table.create!(path: path, namespace_id: namespace.id) + + deployment_id = nil + + if with_deployment + deployment_id = deployments_table.create!(project_id: project.id, file_store: 1, file: '1', file_count: 1, file_sha256: '123', size: 1).id + end + + metadata_table.create!(project_id: project.id, deployed: deployed, pages_deployment_id: deployment_id) + end + + it 'correctly schedules background migrations' do + Sidekiq::Testing.fake! do + freeze_time do + create_project_metadata("not-deployed-project", false, false) + + first_id = create_project_metadata("project1", true, false).id + last_id = create_project_metadata("project2", true, false).id + + create_project_metadata("project-with-deployment", true, true) + + migrate! + + expect(migration_name).to be_scheduled_delayed_migration(5.minutes, first_id, last_id) + expect(BackgroundMigrationWorker.jobs.size).to eq(1) + end + end + end +end -- cgit v1.2.3