diff options
Diffstat (limited to 'spec/lib/gitlab/background_migration')
28 files changed, 798 insertions, 103 deletions
diff --git a/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb b/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb new file mode 100644 index 00000000000..788ed40b61e --- /dev/null +++ b/spec/lib/gitlab/background_migration/backfill_environment_tiers_spec.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::BackfillEnvironmentTiers, + :migration, schema: 20221205151917, feature_category: :continuous_delivery do + let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } + let!(:project) { table(:projects).create!(namespace_id: namespace.id, project_namespace_id: namespace.id) } + + let(:migration) do + described_class.new(start_id: 1, end_id: 1000, + batch_table: :environments, batch_column: :id, + sub_batch_size: 10, pause_ms: 0, + connection: ApplicationRecord.connection) + end + + describe '#perform' do + let!(:production) { table(:environments).create!(name: 'production', slug: 'production', project_id: project.id) } + let!(:staging) { table(:environments).create!(name: 'staging', slug: 'staging', project_id: project.id) } + let!(:testing) { table(:environments).create!(name: 'testing', slug: 'testing', project_id: project.id) } + + let!(:development) do + table(:environments).create!(name: 'development', slug: 'development', project_id: project.id) + end + + let!(:other) { table(:environments).create!(name: 'other', slug: 'other', project_id: project.id) } + + it 'backfill tiers for all environments in range' do + expect(production.tier).to be_nil + expect(staging.tier).to be_nil + expect(testing.tier).to be_nil + expect(development.tier).to be_nil + expect(other.tier).to be_nil + + migration.perform + + expect(production.reload.tier).to eq(described_class::PRODUCTION_TIER) + expect(staging.reload.tier).to eq(described_class::STAGING_TIER) + expect(testing.reload.tier).to eq(described_class::TESTING_TIER) + expect(development.reload.tier).to eq(described_class::DEVELOPMENT_TIER) + expect(other.reload.tier).to eq(described_class::OTHER_TIER) + end + end + + # Equivalent to spec/models/environment_spec.rb#guess_tier + describe 'same behavior with guess tier' do + using RSpec::Parameterized::TableSyntax + + let(:environment) { table(:environments).create!(name: name, slug: name, project_id: project.id) } + + where(:name, :tier) do + 'review/feature' | described_class::DEVELOPMENT_TIER + 'review/product' | described_class::DEVELOPMENT_TIER + 'DEV' | described_class::DEVELOPMENT_TIER + 'development' | described_class::DEVELOPMENT_TIER + 'trunk' | described_class::DEVELOPMENT_TIER + 'dev' | described_class::DEVELOPMENT_TIER + 'review/app' | described_class::DEVELOPMENT_TIER + 'PRODUCTION' | described_class::PRODUCTION_TIER + 'prod' | described_class::PRODUCTION_TIER + 'prod-east-2' | described_class::PRODUCTION_TIER + 'us-prod-east' | described_class::PRODUCTION_TIER + 'fe-production' | described_class::PRODUCTION_TIER + 'test' | described_class::TESTING_TIER + 'TEST' | described_class::TESTING_TIER + 'testing' | described_class::TESTING_TIER + 'testing-prd' | described_class::TESTING_TIER + 'acceptance-testing' | described_class::TESTING_TIER + 'production-test' | described_class::TESTING_TIER + 'test-production' | described_class::TESTING_TIER + 'QC' | described_class::TESTING_TIER + 'qa-env-2' | described_class::TESTING_TIER + 'gstg' | described_class::STAGING_TIER + 'staging' | described_class::STAGING_TIER + 'stage' | described_class::STAGING_TIER + 'Model' | described_class::STAGING_TIER + 'MODL' | described_class::STAGING_TIER + 'Pre-production' | described_class::STAGING_TIER + 'pre' | described_class::STAGING_TIER + 'Demo' | described_class::STAGING_TIER + 'staging' | described_class::STAGING_TIER + 'pre-prod' | described_class::STAGING_TIER + 'blue-kit-stage' | described_class::STAGING_TIER + 'nonprod' | described_class::STAGING_TIER + 'nonlive' | described_class::STAGING_TIER + 'non-prod' | described_class::STAGING_TIER + 'non-live' | described_class::STAGING_TIER + 'gprd' | described_class::PRODUCTION_TIER + 'gprd-cny' | described_class::PRODUCTION_TIER + 'production' | described_class::PRODUCTION_TIER + 'Production' | described_class::PRODUCTION_TIER + 'PRODUCTION' | described_class::PRODUCTION_TIER + 'Production/eu' | described_class::PRODUCTION_TIER + 'production/eu' | described_class::PRODUCTION_TIER + 'PRODUCTION/EU' | described_class::PRODUCTION_TIER + 'productioneu' | described_class::PRODUCTION_TIER + 'store-produce' | described_class::PRODUCTION_TIER + 'unproductive' | described_class::PRODUCTION_TIER + 'production/www.gitlab.com' | described_class::PRODUCTION_TIER + 'prod' | described_class::PRODUCTION_TIER + 'PROD' | described_class::PRODUCTION_TIER + 'Live' | described_class::PRODUCTION_TIER + 'canary' | described_class::OTHER_TIER + 'other' | described_class::OTHER_TIER + 'EXP' | described_class::OTHER_TIER + 'something-else' | described_class::OTHER_TIER + end + + with_them do + it 'backfill tiers for all environments in range' do + expect(environment.tier).to be_nil + + migration.perform + + expect(environment.reload.tier).to eq(tier) + end + end + end +end diff --git a/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb b/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb index 8947262ae9e..479afb56210 100644 --- a/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb @@ -23,6 +23,7 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillImportedIssueSearchData, let!(:issue) do table(:issues).create!( project_id: project.id, + namespace_id: project.project_namespace_id, title: 'Patterson', description: FFaker::HipsterIpsum.paragraph ) @@ -71,6 +72,7 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillImportedIssueSearchData, let!(:issue2) do table(:issues).create!( project_id: project.id, + namespace_id: project.project_namespace_id, title: 'Chatterton', description: FFaker::HipsterIpsum.paragraph ) diff --git a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb index 65f5f8368df..8db45ac0f57 100644 --- a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb @@ -3,11 +3,11 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::BackfillJiraTrackerDeploymentType2, :migration, schema: 20210301200959 do - let_it_be(:jira_integration_temp) { described_class::JiraServiceTemp } - let_it_be(:jira_tracker_data_temp) { described_class::JiraTrackerDataTemp } - let_it_be(:atlassian_host) { 'https://api.atlassian.net' } - let_it_be(:mixedcase_host) { 'https://api.AtlassiaN.nEt' } - let_it_be(:server_host) { 'https://my.server.net' } + let!(:jira_integration_temp) { described_class::JiraServiceTemp } + let!(:jira_tracker_data_temp) { described_class::JiraTrackerDataTemp } + let!(:atlassian_host) { 'https://api.atlassian.net' } + let!(:mixedcase_host) { 'https://api.AtlassiaN.nEt' } + let!(:server_host) { 'https://my.server.net' } let(:jira_integration) { jira_integration_temp.create!(type: 'JiraService', active: true, category: 'issue_tracker') } diff --git a/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb index 77d6cc43114..01daf16d10c 100644 --- a/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_project_namespace_details_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::BackfillProjectNamespaceDetails, :migration do - let_it_be(:namespace_details) { table(:namespace_details) } - let_it_be(:namespaces) { table(:namespaces) } - let_it_be(:projects) { table(:projects) } + let!(:namespace_details) { table(:namespace_details) } + let!(:namespaces) { table(:namespaces) } + let!(:projects) { table(:projects) } subject(:perform_migration) do described_class.new(start_id: projects.minimum(:id), diff --git a/spec/lib/gitlab/background_migration/backfill_project_namespace_on_issues_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_namespace_on_issues_spec.rb index 3ca7d28f09d..5fa92759cf9 100644 --- a/spec/lib/gitlab/background_migration/backfill_project_namespace_on_issues_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_project_namespace_on_issues_spec.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true require 'spec_helper' -# todo: this will need to specify schema version once we introduce the not null constraint on issues#namespace_id -# https://gitlab.com/gitlab-org/gitlab/-/issues/367835 -RSpec.describe Gitlab::BackgroundMigration::BackfillProjectNamespaceOnIssues do + +RSpec.describe Gitlab::BackgroundMigration::BackfillProjectNamespaceOnIssues, + :migration, schema: 20221118103352, feature_category: :team_planning do let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:issues) { table(:issues) } + let(:issue_base_type_enum_value) { 0 } + let(:issue_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_base_type_enum_value) } let(:namespace1) { namespaces.create!(name: 'batchtest1', type: 'Group', path: 'space1') } let(:namespace2) { namespaces.create!(name: 'batchtest2', type: 'Group', parent_id: namespace1.id, path: 'space2') } @@ -18,12 +20,12 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectNamespaceOnIssues do let(:proj1) { projects.create!(name: 'proj1', path: 'proj1', namespace_id: namespace1.id, project_namespace_id: proj_namespace1.id) } let(:proj2) { projects.create!(name: 'proj2', path: 'proj2', namespace_id: namespace2.id, project_namespace_id: proj_namespace2.id) } - let!(:proj1_issue_with_namespace) { issues.create!(title: 'issue1', project_id: proj1.id, namespace_id: proj_namespace1.id) } - let!(:proj1_issue_without_namespace1) { issues.create!(title: 'issue2', project_id: proj1.id) } - let!(:proj1_issue_without_namespace2) { issues.create!(title: 'issue3', project_id: proj1.id) } - let!(:proj2_issue_with_namespace) { issues.create!(title: 'issue4', project_id: proj2.id, namespace_id: proj_namespace2.id) } - let!(:proj2_issue_without_namespace1) { issues.create!(title: 'issue5', project_id: proj2.id) } - let!(:proj2_issue_without_namespace2) { issues.create!(title: 'issue6', project_id: proj2.id) } + let!(:proj1_issue_with_namespace) { issues.create!(title: 'issue1', project_id: proj1.id, namespace_id: proj_namespace1.id, work_item_type_id: issue_type.id) } + let!(:proj1_issue_without_namespace1) { issues.create!(title: 'issue2', project_id: proj1.id, work_item_type_id: issue_type.id) } + let!(:proj1_issue_without_namespace2) { issues.create!(title: 'issue3', project_id: proj1.id, work_item_type_id: issue_type.id) } + let!(:proj2_issue_with_namespace) { issues.create!(title: 'issue4', project_id: proj2.id, namespace_id: proj_namespace2.id, work_item_type_id: issue_type.id) } + let!(:proj2_issue_without_namespace1) { issues.create!(title: 'issue5', project_id: proj2.id, work_item_type_id: issue_type.id) } + let!(:proj2_issue_without_namespace2) { issues.create!(title: 'issue6', project_id: proj2.id, work_item_type_id: issue_type.id) } # rubocop:enable Layout/LineLength let(:migration) do diff --git a/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb b/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb index 6ef474ad7f9..5f93424faf6 100644 --- a/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_work_item_type_id_for_issues_spec.rb @@ -45,7 +45,7 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillWorkItemTypeIdForIssues, :mi it 'sets work_item_type_id only for the given type' do expect(all_issues).to all(have_attributes(work_item_type_id: nil)) - expect { migrate }.to make_queries_matching(/UPDATE \"issues\" SET "work_item_type_id"/, 2) + expect { migrate }.to make_queries_matching(/UPDATE "issues" SET "work_item_type_id"/, 2) all_issues.each(&:reload) expect([issue1, issue2, issue3]).to all(have_attributes(work_item_type_id: issue_type.id)) diff --git a/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb b/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb index 95be14cefb1..7280ca0b58e 100644 --- a/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb +++ b/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb @@ -158,6 +158,28 @@ RSpec.describe Gitlab::BackgroundMigration::BatchedMigrationJob do end end + describe '.feature_category' do + context 'when jobs does not have feature_category attribute set' do + let(:job_class) { Class.new(described_class) } + + it 'returns :database as default' do + expect(job_class.feature_category).to eq(:database) + end + end + + context 'when jobs have feature_category attribute set' do + let(:job_class) do + Class.new(described_class) do + feature_category :delivery + end + end + + it 'returns the provided value' do + expect(job_class.feature_category).to eq(:delivery) + end + end + end + describe 'descendants', :eager_load do it 'have the same method signature for #perform' do expected_arity = described_class.instance_method(:perform).arity diff --git a/spec/lib/gitlab/background_migration/batching_strategies/loose_index_scan_batching_strategy_spec.rb b/spec/lib/gitlab/background_migration/batching_strategies/loose_index_scan_batching_strategy_spec.rb index 1a00fd7c8b3..72958700ca2 100644 --- a/spec/lib/gitlab/background_migration/batching_strategies/loose_index_scan_batching_strategy_spec.rb +++ b/spec/lib/gitlab/background_migration/batching_strategies/loose_index_scan_batching_strategy_spec.rb @@ -7,6 +7,8 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::LooseIndexScanBa let(:namespaces) { table(:namespaces) } let(:projects) { table(:projects) } let(:issues) { table(:issues) } + let(:issue_base_type_enum_value) { 0 } + let(:issue_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_base_type_enum_value) } let!(:namespace1) { namespaces.create!(name: 'ns1', path: 'ns1') } let!(:namespace2) { namespaces.create!(name: 'ns2', path: 'ns2') } @@ -19,13 +21,15 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::LooseIndexScanBa let!(:project4) { projects.create!(name: 'p4', namespace_id: namespace4.id, project_namespace_id: namespace4.id) } let!(:project5) { projects.create!(name: 'p5', namespace_id: namespace5.id, project_namespace_id: namespace5.id) } - let!(:issue1) { issues.create!(title: 'title', description: 'description', project_id: project2.id) } - let!(:issue2) { issues.create!(title: 'title', description: 'description', project_id: project1.id) } - let!(:issue3) { issues.create!(title: 'title', description: 'description', project_id: project2.id) } - let!(:issue4) { issues.create!(title: 'title', description: 'description', project_id: project3.id) } - let!(:issue5) { issues.create!(title: 'title', description: 'description', project_id: project2.id) } - let!(:issue6) { issues.create!(title: 'title', description: 'description', project_id: project4.id) } - let!(:issue7) { issues.create!(title: 'title', description: 'description', project_id: project5.id) } + # rubocop:disable Layout/LineLength + let!(:issue1) { issues.create!(title: 'title', description: 'description', project_id: project2.id, namespace_id: project2.project_namespace_id, work_item_type_id: issue_type.id) } + let!(:issue2) { issues.create!(title: 'title', description: 'description', project_id: project1.id, namespace_id: project1.project_namespace_id, work_item_type_id: issue_type.id) } + let!(:issue3) { issues.create!(title: 'title', description: 'description', project_id: project2.id, namespace_id: project2.project_namespace_id, work_item_type_id: issue_type.id) } + let!(:issue4) { issues.create!(title: 'title', description: 'description', project_id: project3.id, namespace_id: project3.project_namespace_id, work_item_type_id: issue_type.id) } + let!(:issue5) { issues.create!(title: 'title', description: 'description', project_id: project2.id, namespace_id: project2.project_namespace_id, work_item_type_id: issue_type.id) } + let!(:issue6) { issues.create!(title: 'title', description: 'description', project_id: project4.id, namespace_id: project4.project_namespace_id, work_item_type_id: issue_type.id) } + let!(:issue7) { issues.create!(title: 'title', description: 'description', project_id: project5.id, namespace_id: project5.project_namespace_id, work_item_type_id: issue_type.id) } + # rubocop:enable Layout/LineLength it { expect(described_class).to be < Gitlab::BackgroundMigration::BatchingStrategies::BaseStrategy } diff --git a/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb index afa955a6056..c03962c8d21 100644 --- a/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb +++ b/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabilities, :migration do include MigrationHelpers::VulnerabilitiesHelper - let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } - let_it_be(:users) { table(:users) } - let_it_be(:user) do + let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } + let!(:users) { table(:users) } + let!(:user) do users.create!( name: "Example User", email: "user@example.com", @@ -17,7 +17,7 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabili ) end - let_it_be(:project) do + let!(:project) do table(:projects).create!( id: 123, namespace_id: namespace.id, @@ -25,9 +25,9 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabili ) end - let_it_be(:scanners) { table(:vulnerability_scanners) } - let_it_be(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') } - let_it_be(:different_scanner) do + let!(:scanners) { table(:vulnerability_scanners) } + let!(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') } + let!(:different_scanner) do scanners.create!( project_id: project.id, external_id: 'test 2', @@ -35,22 +35,22 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabili ) end - let_it_be(:vulnerabilities) { table(:vulnerabilities) } - let_it_be(:vulnerability_with_finding) do + let!(:vulnerabilities) { table(:vulnerabilities) } + let!(:vulnerability_with_finding) do create_vulnerability!( project_id: project.id, author_id: user.id ) end - let_it_be(:vulnerability_without_finding) do + let!(:vulnerability_without_finding) do create_vulnerability!( project_id: project.id, author_id: user.id ) end - let_it_be(:cis_vulnerability_without_finding) do + let!(:cis_vulnerability_without_finding) do create_vulnerability!( project_id: project.id, author_id: user.id, @@ -58,7 +58,7 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabili ) end - let_it_be(:custom_vulnerability_without_finding) do + let!(:custom_vulnerability_without_finding) do create_vulnerability!( project_id: project.id, author_id: user.id, @@ -66,8 +66,8 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabili ) end - let_it_be(:vulnerability_identifiers) { table(:vulnerability_identifiers) } - let_it_be(:primary_identifier) do + let!(:vulnerability_identifiers) { table(:vulnerability_identifiers) } + let!(:primary_identifier) do vulnerability_identifiers.create!( project_id: project.id, external_type: 'uuid-v5', @@ -76,8 +76,8 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabili name: 'Identifier for UUIDv5') end - let_it_be(:vulnerabilities_findings) { table(:vulnerability_occurrences) } - let_it_be(:finding) do + let!(:vulnerabilities_findings) { table(:vulnerability_occurrences) } + let!(:finding) do create_finding!( vulnerability_id: vulnerability_with_finding.id, project_id: project.id, diff --git a/spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb b/spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb new file mode 100644 index 00000000000..c5b46d3f57c --- /dev/null +++ b/spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::DeleteOrphansApprovalMergeRequestRules do + describe '#perform' do + let(:batch_table) { :approval_merge_request_rules } + let(:batch_column) { :id } + let(:sub_batch_size) { 1 } + let(:pause_ms) { 0 } + let(:connection) { ApplicationRecord.connection } + + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:approval_merge_request_rules) { table(:approval_merge_request_rules) } + let(:security_orchestration_policy_configurations) { table(:security_orchestration_policy_configurations) } + let(:namespace) { namespaces.create!(name: 'name', path: 'path') } + let(:project) do + projects + .create!(name: "project", path: "project", namespace_id: namespace.id, project_namespace_id: namespace.id) + end + + let(:namespace_2) { namespaces.create!(name: 'name_2', path: 'path_2') } + let(:security_project) do + projects + .create!(name: "security_project", path: "security_project", namespace_id: namespace_2.id, + project_namespace_id: namespace_2.id) + end + + let!(:security_orchestration_policy_configuration) do + security_orchestration_policy_configurations + .create!(project_id: project.id, security_policy_management_project_id: security_project.id) + end + + let(:merge_request) do + table(:merge_requests).create!(target_project_id: project.id, target_branch: 'main', source_branch: 'feature') + end + + let!(:approval_rule) do + approval_merge_request_rules.create!( + name: 'rule', + merge_request_id: merge_request.id, + report_type: 4, + security_orchestration_policy_configuration_id: security_orchestration_policy_configuration.id) + end + + let!(:approval_rule_other_report_type) do + approval_merge_request_rules.create!( + name: 'rule 2', + merge_request_id: merge_request.id, + report_type: 1, + security_orchestration_policy_configuration_id: security_orchestration_policy_configuration.id) + end + + let!(:approval_rule_last) do + approval_merge_request_rules.create!(name: 'rule 3', merge_request_id: merge_request.id, report_type: 4) + end + + subject do + described_class.new( + start_id: approval_rule.id, + end_id: approval_rule_last.id, + batch_table: batch_table, + batch_column: batch_column, + sub_batch_size: sub_batch_size, + pause_ms: pause_ms, + connection: connection + ).perform + end + + it 'delete only approval rules without association with the security project and report_type equals to 4' do + expect { subject }.to change { approval_merge_request_rules.count }.from(3).to(2) + end + end +end diff --git a/spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb b/spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb new file mode 100644 index 00000000000..16253255764 --- /dev/null +++ b/spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::DeleteOrphansApprovalProjectRules do + describe '#perform' do + let(:batch_table) { :approval_project_rules } + let(:batch_column) { :id } + let(:sub_batch_size) { 1 } + let(:pause_ms) { 0 } + let(:connection) { ApplicationRecord.connection } + + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:approval_project_rules) { table(:approval_project_rules) } + let(:security_orchestration_policy_configurations) { table(:security_orchestration_policy_configurations) } + let(:namespace) { namespaces.create!(name: 'name', path: 'path') } + let(:project) do + projects + .create!(name: "project", path: "project", namespace_id: namespace.id, project_namespace_id: namespace.id) + end + + let(:namespace_2) { namespaces.create!(name: 'name_2', path: 'path_2') } + let(:security_project) do + projects + .create!(name: "security_project", path: "security_project", namespace_id: namespace_2.id, + project_namespace_id: namespace_2.id) + end + + let!(:security_orchestration_policy_configuration) do + security_orchestration_policy_configurations + .create!(project_id: project.id, security_policy_management_project_id: security_project.id) + end + + let!(:project_rule) do + approval_project_rules.create!( + name: 'rule', + project_id: project.id, + report_type: 4, + security_orchestration_policy_configuration_id: security_orchestration_policy_configuration.id) + end + + let!(:project_rule_other_report_type) do + approval_project_rules.create!( + name: 'rule 2', + project_id: project.id, + report_type: 1, + security_orchestration_policy_configuration_id: security_orchestration_policy_configuration.id) + end + + let!(:project_rule_last) do + approval_project_rules.create!(name: 'rule 3', project_id: project.id, report_type: 4) + end + + subject do + described_class.new( + start_id: project_rule.id, + end_id: project_rule_last.id, + batch_table: batch_table, + batch_column: batch_column, + sub_batch_size: sub_batch_size, + pause_ms: pause_ms, + connection: connection + ).perform + end + + it 'delete only approval rules without association with the security project and report_type equals to 4' do + expect { subject }.to change { approval_project_rules.count }.from(3).to(2) + end + end +end diff --git a/spec/lib/gitlab/background_migration/disable_expiration_policies_linked_to_no_container_images_spec.rb b/spec/lib/gitlab/background_migration/disable_expiration_policies_linked_to_no_container_images_spec.rb index 8a63673bf38..e7b0471810d 100644 --- a/spec/lib/gitlab/background_migration/disable_expiration_policies_linked_to_no_container_images_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_expiration_policies_linked_to_no_container_images_spec.rb @@ -3,10 +3,10 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableExpirationPoliciesLinkedToNoContainerImages, :migration, schema: 20220326161803 do # rubocop:disable Layout/LineLength - let_it_be(:projects) { table(:projects) } - let_it_be(:container_expiration_policies) { table(:container_expiration_policies) } - let_it_be(:container_repositories) { table(:container_repositories) } - let_it_be(:namespaces) { table(:namespaces) } + 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') } diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb index d20eaef3650..d60874c3159 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb @@ -50,7 +50,7 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForNoI ) project_statistics_table.create!(project_id: project.id, namespace_id: namespace.id, repository_size: repo_size) - issues_table.create!(project_id: project.id) if with_issue + issues_table.create!(project_id: project.id, namespace_id: project.project_namespace_id) if with_issue project_settings_table.create!(project_id: project.id, legacy_open_source_license_available: true) project diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb new file mode 100644 index 00000000000..b92f1a74551 --- /dev/null +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForProjectsLessThanFiveMb, + :migration, + schema: 20221018095434, + feature_category: :projects do + let(:namespaces_table) { table(:namespaces) } + let(:projects_table) { table(:projects) } + let(:project_settings_table) { table(:project_settings) } + let(:project_statistics_table) { table(:project_statistics) } + + subject(:perform_migration) do + described_class.new(start_id: project_settings_table.minimum(:project_id), + end_id: project_settings_table.maximum(:project_id), + batch_table: :project_settings, + batch_column: :project_id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection) + .perform + end + + it 'sets `legacy_open_source_license_available` to false only for projects less than 5 MB', :aggregate_failures do + project_setting_2_mb = create_legacy_license_project_setting(repo_size: 2) + project_setting_4_mb = create_legacy_license_project_setting(repo_size: 4) + project_setting_5_mb = create_legacy_license_project_setting(repo_size: 5) + project_setting_6_mb = create_legacy_license_project_setting(repo_size: 6) + + record = ActiveRecord::QueryRecorder.new do + expect { perform_migration } + .to change { migrated_attribute(project_setting_2_mb) }.from(true).to(false) + .and change { migrated_attribute(project_setting_4_mb) }.from(true).to(false) + .and not_change { migrated_attribute(project_setting_5_mb) }.from(true) + .and not_change { migrated_attribute(project_setting_6_mb) }.from(true) + end + + expect(record.count).to eq(15) + end + + private + + # @param repo_size: Repo size in MB + def create_legacy_license_project_setting(repo_size:) + path = "path-for-repo-size-#{repo_size}" + namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}") + project_namespace = + namespaces_table.create!(name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project') + project = projects_table + .create!(name: path, path: path, namespace_id: namespace.id, project_namespace_id: project_namespace.id) + + size_in_bytes = 1.megabyte * repo_size + project_statistics_table.create!(project_id: project.id, namespace_id: namespace.id, repository_size: size_in_bytes) + project_settings_table.create!(project_id: project.id, legacy_open_source_license_available: true) + end + + def migrated_attribute(project_setting) + project_settings_table.find(project_setting.project_id).legacy_open_source_license_available + end +end diff --git a/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb index 5b6722a3384..ba04f2d20a7 100644 --- a/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb +++ b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb @@ -3,33 +3,33 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: 20210301200959 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) } - let_it_be(:user) { create_user! } - let_it_be(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) } - - let_it_be(:scanners) { table(:vulnerability_scanners) } - let_it_be(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') } - let_it_be(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') } - - let_it_be(:vulnerabilities) { table(:vulnerabilities) } - let_it_be(:vulnerability_with_finding) do + let!(:background_migration_jobs) { table(:background_migration_jobs) } + let!(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') } + let!(:users) { table(:users) } + let!(:user) { create_user! } + let!(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) } + + let!(:scanners) { table(:vulnerability_scanners) } + let!(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') } + let!(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') } + + let!(:vulnerabilities) { table(:vulnerabilities) } + let!(:vulnerability_with_finding) do create_vulnerability!( project_id: project.id, author_id: user.id ) end - let_it_be(:vulnerability_without_finding) do + let!(:vulnerability_without_finding) do create_vulnerability!( project_id: project.id, author_id: user.id ) end - let_it_be(:vulnerability_identifiers) { table(:vulnerability_identifiers) } - let_it_be(:primary_identifier) do + let!(:vulnerability_identifiers) { table(:vulnerability_identifiers) } + let!(:primary_identifier) do vulnerability_identifiers.create!( project_id: project.id, external_type: 'uuid-v5', @@ -38,8 +38,8 @@ RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: name: 'Identifier for UUIDv5') end - let_it_be(:vulnerabilities_findings) { table(:vulnerability_occurrences) } - let_it_be(:finding) do + let!(:vulnerabilities_findings) { table(:vulnerability_occurrences) } + let!(:finding) do create_finding!( vulnerability_id: vulnerability_with_finding.id, project_id: project.id, @@ -94,7 +94,7 @@ RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, name: "test", severity: 7, confidence: 7, report_type: 0, project_fingerprint: '123qweasdzxc', location_fingerprint: 'test', - metadata_version: 'test', raw_metadata: 'test', uuid: 'test') + metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid) vulnerabilities_findings.create!( vulnerability_id: vulnerability_id, project_id: project_id, diff --git a/spec/lib/gitlab/background_migration/populate_container_repository_migration_plan_spec.rb b/spec/lib/gitlab/background_migration/populate_container_repository_migration_plan_spec.rb index 0463f5a0c0d..477167c9074 100644 --- a/spec/lib/gitlab/background_migration/populate_container_repository_migration_plan_spec.rb +++ b/spec/lib/gitlab/background_migration/populate_container_repository_migration_plan_spec.rb @@ -3,12 +3,12 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::PopulateContainerRepositoryMigrationPlan, schema: 20220316202640 do - let_it_be(:container_repositories) { table(:container_repositories) } - let_it_be(:projects) { table(:projects) } - let_it_be(:namespaces) { table(:namespaces) } - let_it_be(:gitlab_subscriptions) { table(:gitlab_subscriptions) } - let_it_be(:plans) { table(:plans) } - let_it_be(:namespace_statistics) { table(:namespace_statistics) } + let!(:container_repositories) { table(:container_repositories) } + let!(:projects) { table(:projects) } + let!(:namespaces) { table(:namespaces) } + let!(:gitlab_subscriptions) { table(:gitlab_subscriptions) } + let!(:plans) { table(:plans) } + let!(:namespace_statistics) { table(:namespace_statistics) } let!(:namepace1) { namespaces.create!(id: 1, type: 'Group', name: 'group1', path: 'group1', traversal_ids: [1]) } let!(:namepace2) { namespaces.create!(id: 2, type: 'Group', name: 'group2', path: 'group2', traversal_ids: [2]) } diff --git a/spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb b/spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb index 98b2bc437f3..4a7d52ee784 100644 --- a/spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb +++ b/spec/lib/gitlab/background_migration/populate_namespace_statistics_spec.rb @@ -3,10 +3,10 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::PopulateNamespaceStatistics do - let_it_be(:namespaces) { table(:namespaces) } - let_it_be(:namespace_statistics) { table(:namespace_statistics) } - let_it_be(:dependency_proxy_manifests) { table(:dependency_proxy_manifests) } - let_it_be(:dependency_proxy_blobs) { table(:dependency_proxy_blobs) } + let!(:namespaces) { table(:namespaces) } + let!(:namespace_statistics) { table(:namespace_statistics) } + let!(:dependency_proxy_manifests) { table(:dependency_proxy_manifests) } + let!(:dependency_proxy_blobs) { table(:dependency_proxy_blobs) } let!(:group1) { namespaces.create!(id: 10, type: 'Group', name: 'group1', path: 'group1') } let!(:group2) { namespaces.create!(id: 20, type: 'Group', name: 'group2', path: 'group2') } diff --git a/spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb b/spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb index fc06012ed20..c0470f26d9e 100644 --- a/spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb +++ b/spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb @@ -68,7 +68,7 @@ RSpec.describe Gitlab::BackgroundMigration::PopulateVulnerabilityReads, :migrati # rubocop:disable Metrics/ParameterLists def create_finding!( - vulnerability_id: nil, project_id:, scanner_id:, primary_identifier_id:, + project_id:, scanner_id:, primary_identifier_id:, vulnerability_id: nil, name: "test", severity: 7, confidence: 7, report_type: 0, project_fingerprint: '123qweasdzxc', location: { "image" => "alpine:3.4" }, location_fingerprint: 'test', metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid) diff --git a/spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb b/spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb new file mode 100644 index 00000000000..5150d0ea4b0 --- /dev/null +++ b/spec/lib/gitlab/background_migration/prune_stale_project_export_jobs_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::PruneStaleProjectExportJobs, feature_category: :importers do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:project_export_jobs) { table(:project_export_jobs) } + let(:project_relation_exports) { table(:project_relation_exports) } + let(:uploads) { table(:project_relation_export_uploads) } + + subject(:perform_migration) do + described_class.new(start_id: 1, + end_id: 300, + batch_table: :project_export_jobs, + batch_column: :id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection) + .perform + end + + it 'removes export jobs and associated relations older than 7 days' do + namespaces.create!(id: 1000, name: "Sally", path: 'sally') + projects.create!(id: 1, namespace_id: 1000, project_namespace_id: 1000) + + project = Project.find 1 + + project_export_jobs.create!(id: 10, project_id: project.id, jid: SecureRandom.hex(10), updated_at: 37.months.ago) + project_export_jobs.create!(id: 20, project_id: project.id, jid: SecureRandom.hex(10), updated_at: 12.months.ago) + project_export_jobs.create!(id: 30, project_id: project.id, jid: SecureRandom.hex(10), updated_at: 8.days.ago) + project_export_jobs.create!(id: 40, project_id: project.id, jid: SecureRandom.hex(10), updated_at: 1.day.ago) + project_export_jobs.create!(id: 50, project_id: project.id, jid: SecureRandom.hex(10), updated_at: 2.days.ago) + project_export_jobs.create!(id: 60, project_id: project.id, jid: SecureRandom.hex(10), updated_at: 6.days.ago) + + project_relation_exports.create!(id: 100, project_export_job_id: 10, relation: 'Project') + project_relation_exports.create!(id: 200, project_export_job_id: 20, relation: 'Project') + project_relation_exports.create!(id: 300, project_export_job_id: 30, relation: 'Project') + project_relation_exports.create!(id: 400, project_export_job_id: 40, relation: 'Project') + project_relation_exports.create!(id: 500, project_export_job_id: 50, relation: 'Project') + project_relation_exports.create!(id: 600, project_export_job_id: 60, relation: 'Project') + + uploads.create!(project_relation_export_id: 100, export_file: "#{SecureRandom.alphanumeric(5)}_export.tar.gz") + uploads.create!(project_relation_export_id: 200, export_file: "#{SecureRandom.alphanumeric(5)}_export.tar.gz") + uploads.create!(project_relation_export_id: 300, export_file: "#{SecureRandom.alphanumeric(5)}_export.tar.gz") + uploads.create!(project_relation_export_id: 400, export_file: "#{SecureRandom.alphanumeric(5)}_export.tar.gz") + uploads.create!(project_relation_export_id: 500, export_file: "#{SecureRandom.alphanumeric(5)}_export.tar.gz") + uploads.create!(project_relation_export_id: 600, export_file: "#{SecureRandom.alphanumeric(5)}_export.tar.gz") + + expect(project_export_jobs.all.size).to eq(6) + expect(project_relation_exports.all.size).to eq(6) + expect(uploads.all.size).to eq(6) + + expect { perform_migration } + .to change { project_export_jobs.count }.by(-3) + .and change { project_relation_exports.count }.by(-3) + .and change { uploads.count }.by(-3) + + expect(project_export_jobs.all.size).to eq(3) + expect(project_relation_exports.all.size).to eq(3) + expect(uploads.all.size).to eq(3) + end +end diff --git a/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb index 29cc4f34f6d..2271bbfb2f3 100644 --- a/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb +++ b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb @@ -488,11 +488,10 @@ RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrence # rubocop:disable Metrics/ParameterLists def create_finding!( - id: nil, - vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, + vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, id: nil, name: "test", severity: 7, confidence: 7, report_type: 0, project_fingerprint: '123qweasdzxc', location_fingerprint: 'test', - metadata_version: 'test', raw_metadata: 'test', uuid: 'test') + metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid) vulnerability_findings.create!({ id: id, vulnerability_id: vulnerability_id, diff --git a/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb b/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb index 10597e65910..5fede892463 100644 --- a/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb +++ b/spec/lib/gitlab/background_migration/remove_backfilled_job_artifacts_expire_at_spec.rb @@ -20,8 +20,8 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveBackfilledJobArtifactsExpireAt ) end - let_it_be(:namespace) { table(:namespaces).create!(id: 1, name: 'user', path: 'user') } - let_it_be(:project) do + let!(:namespace) { table(:namespaces).create!(id: 1, name: 'user', path: 'user') } + let!(:project) do table(:projects).create!( id: 1, name: 'gitlab1', diff --git a/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb b/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb index 8003159f59e..ed08ae22245 100644 --- a/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb +++ b/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb @@ -134,11 +134,10 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin # rubocop:disable Metrics/ParameterLists def create_finding!( - id: nil, - vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, + vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, id: nil, name: "test", severity: 7, confidence: 7, report_type: 0, project_fingerprint: '123qweasdzxc', location_fingerprint: 'test', - metadata_version: 'test', raw_metadata: 'test', uuid: 'test') + metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid) params = { vulnerability_id: vulnerability_id, project_id: project_id, diff --git a/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb b/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb index 33ad74fbee8..1844347f4a9 100644 --- a/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb +++ b/spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb @@ -89,7 +89,6 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveOccurrencePipelinesAndDuplicat let!(:unrelated_finding) do create_finding!( id: 9999999, - uuid: "unreleated_finding", vulnerability_id: nil, report_type: 1, location_fingerprint: 'random_location_fingerprint', @@ -133,11 +132,10 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveOccurrencePipelinesAndDuplicat # rubocop:disable Metrics/ParameterLists def create_finding!( - id: nil, - vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, + vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:, id: nil, name: "test", severity: 7, confidence: 7, report_type: 0, project_fingerprint: '123qweasdzxc', location_fingerprint: 'test', - metadata_version: 'test', raw_metadata: 'test', uuid: 'test') + metadata_version: 'test', raw_metadata: 'test', uuid: SecureRandom.uuid) params = { vulnerability_id: vulnerability_id, project_id: project_id, diff --git a/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb b/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb index ccf96e036ae..918df8f4442 100644 --- a/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb +++ b/spec/lib/gitlab/background_migration/remove_vulnerability_finding_links_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveVulnerabilityFindingLinks, :mi location_fingerprint: "location_fingerprint_#{id}", metadata_version: 'metadata_version', raw_metadata: 'raw_metadata', - uuid: "uuid_#{id}" + uuid: SecureRandom.uuid ) end end diff --git a/spec/lib/gitlab/background_migration/rename_task_system_note_to_checklist_item_spec.rb b/spec/lib/gitlab/background_migration/rename_task_system_note_to_checklist_item_spec.rb index 45932defaf9..580465df4d9 100644 --- a/spec/lib/gitlab/background_migration/rename_task_system_note_to_checklist_item_spec.rb +++ b/spec/lib/gitlab/background_migration/rename_task_system_note_to_checklist_item_spec.rb @@ -5,10 +5,22 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::RenameTaskSystemNoteToChecklistItem do let(:notes) { table(:notes) } let(:projects) { table(:projects) } - let(:namespace) { table(:namespaces).create!(name: 'batchtest1', type: 'Group', path: 'space1') } - let(:project) { table(:projects).create!(name: 'proj1', path: 'proj1', namespace_id: namespace.id) } - let(:issue) { table(:issues).create!(title: 'Test issue') } + let(:issue_base_type_enum_value) { 0 } + let(:issue_type) { table(:work_item_types).find_by!(namespace_id: nil, base_type: issue_base_type_enum_value) } + + let(:project) do + table(:projects).create!( + name: 'proj1', path: 'proj1', namespace_id: namespace.id, project_namespace_id: namespace.id + ) + end + + let(:issue) do + table(:issues).create!( + title: 'Test issue', project_id: project.id, + namespace_id: project.project_namespace_id, work_item_type_id: issue_type.id + ) + end let!(:note1) do notes.create!( diff --git a/spec/lib/gitlab/background_migration/reset_status_on_container_repositories_spec.rb b/spec/lib/gitlab/background_migration/reset_status_on_container_repositories_spec.rb new file mode 100644 index 00000000000..d50b04857d6 --- /dev/null +++ b/spec/lib/gitlab/background_migration/reset_status_on_container_repositories_spec.rb @@ -0,0 +1,261 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::ResetStatusOnContainerRepositories, feature_category: :container_registry do + let(:projects_table) { table(:projects) } + let(:namespaces_table) { table(:namespaces) } + let(:container_repositories_table) { table(:container_repositories) } + let(:routes_table) { table(:routes) } + + let!(:root_group) do + namespaces_table.create!(name: 'root_group', path: 'root_group', type: 'Group') do |new_group| + new_group.update!(traversal_ids: [new_group.id]) + end + end + + let!(:group1) do + namespaces_table.create!(name: 'group1', path: 'group1', parent_id: root_group.id, type: 'Group') do |new_group| + new_group.update!(traversal_ids: [root_group.id, new_group.id]) + end + end + + let!(:subgroup1) do + namespaces_table.create!(name: 'subgroup1', path: 'subgroup1', parent_id: group1.id, type: 'Group') do |new_group| + new_group.update!(traversal_ids: [root_group.id, group1.id, new_group.id]) + end + end + + let!(:group2) do + namespaces_table.create!(name: 'group2', path: 'group2', parent_id: root_group.id, type: 'Group') do |new_group| + new_group.update!(traversal_ids: [root_group.id, new_group.id]) + end + end + + let!(:group1_project_namespace) do + namespaces_table.create!(name: 'group1_project', path: 'group1_project', type: 'Project', parent_id: group1.id) + end + + let!(:subgroup1_project_namespace) do + namespaces_table.create!( + name: 'subgroup1_project', + path: 'subgroup1_project', + type: 'Project', + parent_id: subgroup1.id + ) + end + + let!(:group2_project_namespace) do + namespaces_table.create!( + name: 'group2_project', + path: 'group2_project', + type: 'Project', + parent_id: group2.id + ) + end + + let!(:group1_project) do + projects_table.create!( + name: 'group1_project', + path: 'group1_project', + namespace_id: group1.id, + project_namespace_id: group1_project_namespace.id + ) + end + + let!(:subgroup1_project) do + projects_table.create!( + name: 'subgroup1_project', + path: 'subgroup1_project', + namespace_id: subgroup1.id, + project_namespace_id: subgroup1_project_namespace.id + ) + end + + let!(:group2_project) do + projects_table.create!( + name: 'group2_project', + path: 'group2_project', + namespace_id: group2.id, + project_namespace_id: group2_project_namespace.id + ) + end + + let!(:route2) do + routes_table.create!( + source_id: group2_project.id, + source_type: 'Project', + path: 'root_group/group2/group2_project', + namespace_id: group2_project_namespace.id + ) + end + + let!(:delete_scheduled_container_repository1) do + container_repositories_table.create!(project_id: group1_project.id, status: 0, name: 'container_repository1') + end + + let!(:delete_scheduled_container_repository2) do + container_repositories_table.create!(project_id: subgroup1_project.id, status: 0, name: 'container_repository2') + end + + let!(:delete_scheduled_container_repository3) do + container_repositories_table.create!(project_id: group2_project.id, status: 0, name: 'container_repository3') + end + + let!(:delete_ongoing_container_repository4) do + container_repositories_table.create!(project_id: group2_project.id, status: 2, name: 'container_repository4') + end + + let(:migration) do + described_class.new( + start_id: container_repositories_table.minimum(:id), + end_id: container_repositories_table.maximum(:id), + batch_table: :container_repositories, + batch_column: :id, + sub_batch_size: 50, + pause_ms: 0, + connection: ApplicationRecord.connection + ) + end + + describe '#filter_batch' do + it 'scopes the relation to delete scheduled container repositories' do + expected = container_repositories_table.where(status: 0).pluck(:id) + actual = migration.filter_batch(container_repositories_table).pluck(:id) + + expect(actual).to match_array(expected) + end + end + + describe '#perform' do + let(:registry_api_url) { 'http://example.com' } + + subject(:perform) { migration.perform } + + before do + stub_container_registry_config( + enabled: true, + api_url: registry_api_url, + key: 'spec/fixtures/x509_certificate_pk.key' + ) + stub_tags_list(path: 'root_group/group1/group1_project/container_repository1') + stub_tags_list(path: 'root_group/group1/subgroup1/subgroup1_project/container_repository2', tags: []) + stub_tags_list(path: 'root_group/group2/group2_project/container_repository3') + end + + shared_examples 'resetting status of all container repositories scheduled for deletion' do + it 'resets all statuses' do + expect_logging_on( + path: 'root_group/group1/group1_project/container_repository1', + id: delete_scheduled_container_repository1.id, + has_tags: true + ) + expect_logging_on( + path: 'root_group/group1/subgroup1/subgroup1_project/container_repository2', + id: delete_scheduled_container_repository2.id, + has_tags: true + ) + expect_logging_on( + path: 'root_group/group2/group2_project/container_repository3', + id: delete_scheduled_container_repository3.id, + has_tags: true + ) + + expect { perform } + .to change { delete_scheduled_container_repository1.reload.status }.from(0).to(nil) + .and change { delete_scheduled_container_repository3.reload.status }.from(0).to(nil) + .and change { delete_scheduled_container_repository2.reload.status }.from(0).to(nil) + end + end + + it 'resets status of container repositories with tags' do + expect_pull_access_token_on(path: 'root_group/group1/group1_project/container_repository1') + expect_pull_access_token_on(path: 'root_group/group1/subgroup1/subgroup1_project/container_repository2') + expect_pull_access_token_on(path: 'root_group/group2/group2_project/container_repository3') + + expect_logging_on( + path: 'root_group/group1/group1_project/container_repository1', + id: delete_scheduled_container_repository1.id, + has_tags: true + ) + expect_logging_on( + path: 'root_group/group1/subgroup1/subgroup1_project/container_repository2', + id: delete_scheduled_container_repository2.id, + has_tags: false + ) + expect_logging_on( + path: 'root_group/group2/group2_project/container_repository3', + id: delete_scheduled_container_repository3.id, + has_tags: true + ) + + expect { perform } + .to change { delete_scheduled_container_repository1.reload.status }.from(0).to(nil) + .and change { delete_scheduled_container_repository3.reload.status }.from(0).to(nil) + .and not_change { delete_scheduled_container_repository2.reload.status } + end + + context 'with the registry disabled' do + before do + allow(::Gitlab.config.registry).to receive(:enabled).and_return(false) + end + + it_behaves_like 'resetting status of all container repositories scheduled for deletion' + end + + context 'with the registry api url not defined' do + before do + allow(::Gitlab.config.registry).to receive(:api_url).and_return('') + end + + it_behaves_like 'resetting status of all container repositories scheduled for deletion' + end + + context 'with a faraday error' do + before do + client_double = instance_double('::ContainerRegistry::Client') + allow(::ContainerRegistry::Client).to receive(:new).and_return(client_double) + allow(client_double).to receive(:repository_tags).and_raise(Faraday::TimeoutError) + + expect_pull_access_token_on(path: 'root_group/group1/group1_project/container_repository1') + expect_pull_access_token_on(path: 'root_group/group1/subgroup1/subgroup1_project/container_repository2') + expect_pull_access_token_on(path: 'root_group/group2/group2_project/container_repository3') + end + + it_behaves_like 'resetting status of all container repositories scheduled for deletion' + end + + def stub_tags_list(path:, tags: %w[tag1]) + url = "#{registry_api_url}/v2/#{path}/tags/list?n=1" + + stub_request(:get, url) + .with( + headers: { + 'Accept' => ContainerRegistry::Client::ACCEPTED_TYPES.join(', '), + 'Authorization' => /bearer .+/, + 'User-Agent' => "GitLab/#{Gitlab::VERSION}" + } + ) + .to_return( + status: 200, + body: Gitlab::Json.dump(tags: tags), + headers: { 'Content-Type' => 'application/json' } + ) + end + + def expect_pull_access_token_on(path:) + expect(Auth::ContainerRegistryAuthenticationService) + .to receive(:pull_access_token).with(path).and_call_original + end + + def expect_logging_on(path:, id:, has_tags:) + expect(::Gitlab::BackgroundMigration::Logger) + .to receive(:info).with( + migrator: described_class::MIGRATOR, + has_tags: has_tags, + container_repository_id: id, + container_repository_path: path + ) + end + end +end diff --git a/spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb b/spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb index 2c5c47e39c9..c58f2060001 100644 --- a/spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb +++ b/spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb @@ -27,8 +27,15 @@ RSpec.describe Gitlab::BackgroundMigration::SanitizeConfidentialTodos, :migratio project_namespace_id: project_namespace2.id) end - let(:issue1) { issues.create!(project_id: project1.id, issue_type: 1, title: 'issue1', author_id: user.id) } - let(:issue2) { issues.create!(project_id: project2.id, issue_type: 1, title: 'issue2') } + let(:issue1) do + issues.create!( + project_id: project1.id, namespace_id: project_namespace1.id, issue_type: 1, title: 'issue1', author_id: user.id + ) + end + + let(:issue2) do + issues.create!(project_id: project2.id, namespace_id: project_namespace2.id, issue_type: 1, title: 'issue2') + end let(:public_note) { notes.create!(note: 'text', project_id: project1.id) } diff --git a/spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb b/spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb index 982e3319063..908f11aabc3 100644 --- a/spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb +++ b/spec/lib/gitlab/background_migration/update_timelogs_null_spent_at_spec.rb @@ -3,19 +3,19 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::UpdateTimelogsNullSpentAt, schema: 20211215090620 do - let_it_be(:previous_time) { 10.days.ago } - let_it_be(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') } - let_it_be(:project) { table(:projects).create!(namespace_id: namespace.id) } - let_it_be(:issue) { table(:issues).create!(project_id: project.id) } - let_it_be(:merge_request) { table(:merge_requests).create!(target_project_id: project.id, source_branch: 'master', target_branch: 'feature') } - let_it_be(:timelog1) { create_timelog!(issue_id: issue.id) } - let_it_be(:timelog2) { create_timelog!(merge_request_id: merge_request.id) } - let_it_be(:timelog3) { create_timelog!(issue_id: issue.id, spent_at: previous_time) } - let_it_be(:timelog4) { create_timelog!(merge_request_id: merge_request.id, spent_at: previous_time) } + let!(:previous_time) { 10.days.ago } + let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') } + let!(:project) { table(:projects).create!(namespace_id: namespace.id) } + let!(:issue) { table(:issues).create!(project_id: project.id) } + let!(:merge_request) { table(:merge_requests).create!(target_project_id: project.id, source_branch: 'master', target_branch: 'feature') } + let!(:timelog1) { create_timelog!(issue_id: issue.id) } + let!(:timelog2) { create_timelog!(merge_request_id: merge_request.id) } + let!(:timelog3) { create_timelog!(issue_id: issue.id, spent_at: previous_time) } + let!(:timelog4) { create_timelog!(merge_request_id: merge_request.id, spent_at: previous_time) } subject(:background_migration) { described_class.new } - before_all do + before do table(:timelogs).where.not(id: [timelog3.id, timelog4.id]).update_all(spent_at: nil) end |