diff --git a/db/post_migrate/20230501165244_remove_software_license_policies_without_scan_result_policy_id.rb b/db/post_migrate/20230501165244_remove_software_license_policies_without_scan_result_policy_id.rb new file mode 100644 index 0000000000000000000000000000000000000000..0e3b15a933c573e99cd0342c8d9022dde3663bbc --- /dev/null +++ b/db/post_migrate/20230501165244_remove_software_license_policies_without_scan_result_policy_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveSoftwareLicensePoliciesWithoutScanResultPolicyId < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + restrict_gitlab_migration gitlab_schema: :gitlab_main + + BATCH_SIZE = 1000 + + def up + each_batch_range('software_license_policies', + scope: ->(table) { table.where(scan_result_policy_id: nil) }, + of: BATCH_SIZE) do |min, max| + execute("DELETE FROM software_license_policies WHERE id BETWEEN #{min} AND #{max}") + end + end + + def down + # NO-OP + end +end diff --git a/db/schema_migrations/20230501165244 b/db/schema_migrations/20230501165244 new file mode 100644 index 0000000000000000000000000000000000000000..df068bbd3fd0a2d8a982e410588651f9dca94c06 --- /dev/null +++ b/db/schema_migrations/20230501165244 @@ -0,0 +1 @@ +8d1f891b30ff45432ae9dff5d97d6d241dd98c168f4b5fe6db6637bf93dd18e3 \ No newline at end of file diff --git a/ee/spec/migrations/20230501165244_remove_software_license_policies_without_scan_result_policy_id_spec.rb b/ee/spec/migrations/20230501165244_remove_software_license_policies_without_scan_result_policy_id_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..d54167b5e4de34f2913312795847283e3f4c571d --- /dev/null +++ b/ee/spec/migrations/20230501165244_remove_software_license_policies_without_scan_result_policy_id_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RemoveSoftwareLicensePoliciesWithoutScanResultPolicyId, feature_category: :security_policy_management do + let(:migration) { described_class.new } + + let(:software_license_policies) { table(:software_license_policies) } + let(:projects) { table(:projects) } + let(:namespace) { table(:namespaces).create!(name: 'name', path: 'path') } + let(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id) } + let(:scan_result_policies) { table(:scan_result_policies) } + let(:security_orchestration_policy_configurations) { table(:security_orchestration_policy_configurations) } + let(:software_licenses) { table(:software_licenses) } + + let!(:security_orchestration_policy_configuration) do + security_orchestration_policy_configurations.create!(namespace_id: namespace.id, + security_policy_management_project_id: project.id) + end + + let!(:scan_result_policy) do + scan_result_policies.create!( + security_orchestration_policy_configuration_id: security_orchestration_policy_configuration.id, + orchestration_policy_idx: 1) + end + + let!(:spdx_identifier_license) { software_licenses.create!(name: 'spdx license') } + + let!(:license_policy_with_scan_result_policy_id) do + software_license_policies.create!(project_id: project.id, software_license_id: spdx_identifier_license.id, + scan_result_policy_id: scan_result_policy.id) + end + + describe '#up' do + context 'with orphan software licenses' do + let!(:license_policy_without_scan_result_policy_id) do + software_license_policies.create!(project_id: project.id, software_license_id: spdx_identifier_license.id) + end + + it 'deletes only orphan software licenses' do + expect { migrate! }.to change { SoftwareLicensePolicy.count }.from(2).to(1) + end + end + + context 'without orphan licenses' do + it 'does not delete any software license' do + expect { migrate! }.not_to change { SoftwareLicensePolicy.count } + end + end + end +end