summaryrefslogtreecommitdiff
path: root/spec/migrations
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-18 09:45:46 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-18 09:45:46 +0000
commita7b3560714b4d9cc4ab32dffcd1f74a284b93580 (patch)
tree7452bd5c3545c2fa67a28aa013835fb4fa071baf /spec/migrations
parentee9173579ae56a3dbfe5afe9f9410c65bb327ca7 (diff)
downloadgitlab-ce-a7b3560714b4d9cc4ab32dffcd1f74a284b93580.tar.gz
Add latest changes from gitlab-org/gitlab@14-8-stable-eev14.8.0-rc42
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb151
-rw-r--r--spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb128
-rw-r--r--spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb136
-rw-r--r--spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb134
-rw-r--r--spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb107
-rw-r--r--spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb21
-rw-r--r--spec/migrations/20220124130028_dedup_runner_projects_spec.rb65
-rw-r--r--spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb52
-rw-r--r--spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb33
-rw-r--r--spec/migrations/20220202105733_delete_service_template_records_spec.rb42
-rw-r--r--spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb37
-rw-r--r--spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb29
-rw-r--r--spec/migrations/backfill_project_namespaces_for_group_spec.rb43
-rw-r--r--spec/migrations/populate_audit_event_streaming_verification_token_spec.rb22
-rw-r--r--spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb34
-rw-r--r--spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb26
-rw-r--r--spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb9
-rw-r--r--spec/migrations/start_backfill_ci_queuing_tables_spec.rb48
-rw-r--r--spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb32
19 files changed, 1145 insertions, 4 deletions
diff --git a/spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb b/spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb
new file mode 100644
index 00000000000..3e450546315
--- /dev/null
+++ b/spec/migrations/20220106111958_add_insert_or_update_vulnerability_reads_trigger_spec.rb
@@ -0,0 +1,151 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddInsertOrUpdateVulnerabilityReadsTrigger do
+ let(:migration) { described_class.new }
+ let(:vulnerabilities) { table(:vulnerabilities) }
+ let(:vulnerability_reads) { table(:vulnerability_reads) }
+ let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+ let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+ let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+ let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+ let(:vulnerability) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let(:vulnerability2) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let(:identifier) do
+ table(:vulnerability_identifiers).create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'Identifier for UUIDv5')
+ end
+
+ let(:finding) do
+ create_finding!(
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: identifier.id
+ )
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ end
+
+ describe 'UPDATE trigger' do
+ context 'when vulnerability_id is updated' do
+ it 'creates a new vulnerability_reads row' do
+ expect do
+ finding.update!(vulnerability_id: vulnerability.id)
+ end.to change { vulnerability_reads.count }.from(0).to(1)
+ end
+ end
+
+ context 'when vulnerability_id is not updated' do
+ it 'does not create a new vulnerability_reads row' do
+ finding.update!(vulnerability_id: nil)
+
+ expect do
+ finding.update!(location: '')
+ end.not_to change { vulnerability_reads.count }
+ end
+ end
+ end
+
+ describe 'INSERT trigger' do
+ context 'when vulnerability_id is set' do
+ it 'creates a new vulnerability_reads row' do
+ expect do
+ create_finding!(
+ vulnerability_id: vulnerability2.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: identifier.id
+ )
+ end.to change { vulnerability_reads.count }.from(0).to(1)
+ end
+ end
+
+ context 'when vulnerability_id is not set' do
+ it 'does not create a new vulnerability_reads row' do
+ expect do
+ create_finding!(
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: identifier.id
+ )
+ end.not_to change { vulnerability_reads.count }
+ end
+ end
+ end
+ end
+
+ describe '#down' do
+ before do
+ migration.up
+ migration.down
+ end
+
+ it 'drops the trigger' do
+ expect do
+ finding.update!(vulnerability_id: vulnerability.id)
+ end.not_to change { vulnerability_reads.count }
+ end
+ end
+
+ private
+
+ def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+ vulnerabilities.create!(
+ project_id: project_id,
+ author_id: author_id,
+ title: title,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type
+ )
+ end
+
+ # rubocop:disable Metrics/ParameterLists
+ def create_finding!(
+ vulnerability_id: nil, project_id:, scanner_id:, primary_identifier_id:,
+ 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)
+ vulnerabilities_findings.create!(
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: name,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type,
+ project_fingerprint: project_fingerprint,
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location: location,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ )
+ end
+ # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb b/spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb
new file mode 100644
index 00000000000..d988b1e42b9
--- /dev/null
+++ b/spec/migrations/20220106112043_add_update_vulnerability_reads_trigger_spec.rb
@@ -0,0 +1,128 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddUpdateVulnerabilityReadsTrigger do
+ let(:migration) { described_class.new }
+ let(:vulnerability_reads) { table(:vulnerability_reads) }
+ let(:issue_links) { table(:vulnerability_issue_links) }
+ let(:vulnerabilities) { table(:vulnerabilities) }
+ let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+
+ let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+ let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+ let(:issue) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+ let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+ let(:vulnerability) do
+ create_vulnerability!(
+ project_id: project.id,
+ report_type: 7,
+ author_id: user.id
+ )
+ end
+
+ let(:identifier) do
+ table(:vulnerability_identifiers).create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'Identifier for UUIDv5')
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ end
+
+ describe 'UPDATE trigger' do
+ before do
+ create_finding!(
+ vulnerability_id: vulnerability.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ report_type: 7,
+ primary_identifier_id: identifier.id
+ )
+ end
+
+ context 'when vulnerability attributes are updated' do
+ it 'updates vulnerability attributes in vulnerability_reads' do
+ expect do
+ vulnerability.update!(severity: 6)
+ end.to change { vulnerability_reads.first.severity }.from(7).to(6)
+ end
+ end
+
+ context 'when vulnerability attributes are not updated' do
+ it 'does not update vulnerability attributes in vulnerability_reads' do
+ expect do
+ vulnerability.update!(title: "New vulnerability")
+ end.not_to change { vulnerability_reads.first }
+ end
+ end
+ end
+ end
+
+ describe '#down' do
+ before do
+ migration.up
+ migration.down
+ create_finding!(
+ vulnerability_id: vulnerability.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ report_type: 7,
+ primary_identifier_id: identifier.id
+ )
+ end
+
+ it 'drops the trigger' do
+ expect do
+ vulnerability.update!(severity: 6)
+ end.not_to change { vulnerability_reads.first.severity }
+ end
+ end
+
+ private
+
+ def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+ vulnerabilities.create!(
+ project_id: project_id,
+ author_id: author_id,
+ title: title,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type
+ )
+ end
+
+ # rubocop:disable Metrics/ParameterLists
+ def create_finding!(
+ vulnerability_id: nil, project_id:, scanner_id:, primary_identifier_id:,
+ 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)
+ vulnerabilities_findings.create!(
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: name,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type,
+ project_fingerprint: project_fingerprint,
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location: location,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ )
+ end
+ # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb b/spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb
new file mode 100644
index 00000000000..901f1cf6041
--- /dev/null
+++ b/spec/migrations/20220106112085_add_update_vulnerability_reads_location_trigger_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddUpdateVulnerabilityReadsLocationTrigger do
+ let(:migration) { described_class.new }
+ let(:vulnerability_reads) { table(:vulnerability_reads) }
+ let(:issue_links) { table(:vulnerability_issue_links) }
+ let(:vulnerabilities) { table(:vulnerabilities) }
+ let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+
+ let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+ let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+ let(:issue) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+ let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+ let(:vulnerability) do
+ create_vulnerability!(
+ project_id: project.id,
+ report_type: 7,
+ author_id: user.id
+ )
+ end
+
+ let(:identifier) do
+ table(:vulnerability_identifiers).create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'Identifier for UUIDv5')
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ end
+
+ describe 'UPDATE trigger' do
+ context 'when image is updated' do
+ it 'updates location_image in vulnerability_reads' do
+ finding = create_finding!(
+ vulnerability_id: vulnerability.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ report_type: 7,
+ location: { "image" => "alpine:3.4" },
+ primary_identifier_id: identifier.id
+ )
+
+ expect do
+ finding.update!(location: { "image" => "alpine:4", "kubernetes_resource" => { "agent_id" => "1234" } })
+ end.to change { vulnerability_reads.first.location_image }.from("alpine:3.4").to("alpine:4")
+ end
+ end
+
+ context 'when image is not updated' do
+ it 'updates location_image in vulnerability_reads' do
+ finding = create_finding!(
+ vulnerability_id: vulnerability.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ report_type: 7,
+ location: { "image" => "alpine:3.4", "kubernetes_resource" => { "agent_id" => "1234" } },
+ primary_identifier_id: identifier.id
+ )
+
+ expect do
+ finding.update!(project_fingerprint: "123qweasdzx")
+ end.not_to change { vulnerability_reads.first.location_image }
+ end
+ end
+ end
+ end
+
+ describe '#down' do
+ before do
+ migration.up
+ migration.down
+ end
+
+ it 'drops the trigger' do
+ finding = create_finding!(
+ vulnerability_id: vulnerability.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: identifier.id
+ )
+
+ expect do
+ finding.update!(location: '{"image":"alpine:4"}')
+ end.not_to change { vulnerability_reads.first.location_image }
+ end
+ end
+
+ private
+
+ def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+ vulnerabilities.create!(
+ project_id: project_id,
+ author_id: author_id,
+ title: title,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type
+ )
+ end
+
+ # rubocop:disable Metrics/ParameterLists
+ def create_finding!(
+ vulnerability_id: nil, project_id:, scanner_id:, primary_identifier_id:,
+ 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)
+ vulnerabilities_findings.create!(
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: name,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type,
+ project_fingerprint: project_fingerprint,
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location: location,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ )
+ end
+ # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb b/spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb
new file mode 100644
index 00000000000..8e50b74eb9c
--- /dev/null
+++ b/spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddHasIssuesOnVulnerabilityReadsTrigger do
+ let(:migration) { described_class.new }
+ let(:vulnerability_reads) { table(:vulnerability_reads) }
+ let(:issue_links) { table(:vulnerability_issue_links) }
+ let(:vulnerabilities) { table(:vulnerabilities) }
+ let(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+
+ let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:user) { table(:users).create!(id: 13, email: 'author@example.com', username: 'author', projects_limit: 10) }
+ let(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
+ let(:issue) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+ let(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+
+ let(:vulnerability) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let(:identifier) do
+ table(:vulnerability_identifiers).create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'Identifier for UUIDv5')
+ end
+
+ before do
+ create_finding!(
+ vulnerability_id: vulnerability.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: identifier.id
+ )
+
+ @vulnerability_read = vulnerability_reads.first
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ end
+
+ describe 'INSERT trigger' do
+ it 'updates has_issues in vulnerability_reads' do
+ expect do
+ issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+ end.to change { @vulnerability_read.reload.has_issues }.from(false).to(true)
+ end
+ end
+
+ describe 'DELETE trigger' do
+ let(:issue2) { table(:issues).create!(description: '1234', state_id: 1, project_id: project.id) }
+
+ it 'does not change has_issues when there exists another issue' do
+ issue_link1 = issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+ issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue2.id)
+
+ expect do
+ issue_link1.delete
+ end.not_to change { @vulnerability_read.reload.has_issues }
+ end
+
+ it 'unsets has_issues when all issues are deleted' do
+ issue_link1 = issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+ issue_link2 = issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue2.id)
+
+ expect do
+ issue_link1.delete
+ issue_link2.delete
+ end.to change { @vulnerability_read.reload.has_issues }.from(true).to(false)
+ end
+ end
+ end
+
+ describe '#down' do
+ before do
+ migration.up
+ migration.down
+ end
+
+ it 'drops the trigger' do
+ expect do
+ issue_links.create!(vulnerability_id: vulnerability.id, issue_id: issue.id)
+ end.not_to change { @vulnerability_read.has_issues }
+ end
+ end
+
+ private
+
+ def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+ vulnerabilities.create!(
+ project_id: project_id,
+ author_id: author_id,
+ title: title,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type
+ )
+ end
+
+ # rubocop:disable Metrics/ParameterLists
+ def create_finding!(
+ vulnerability_id: nil, project_id:, scanner_id:, primary_identifier_id:,
+ 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)
+ vulnerabilities_findings.create!(
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: name,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type,
+ project_fingerprint: project_fingerprint,
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location: location,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ )
+ end
+ # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb b/spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb
new file mode 100644
index 00000000000..ece971a50c9
--- /dev/null
+++ b/spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe PopulateVulnerabilityReads, :migration do
+ let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let_it_be(:user) { table(:users).create!(email: 'author@example.com', username: 'author', projects_limit: 10) }
+ let_it_be(:project) { table(:projects).create!(namespace_id: namespace.id) }
+ let_it_be(:scanner) { table(:vulnerability_scanners).create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
+ let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
+ let_it_be(:vulnerabilities) { table(:vulnerabilities) }
+ let_it_be(:vulnerability_reads) { table(:vulnerability_reads) }
+ let_it_be(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+ let_it_be(:vulnerability_issue_links) { table(:vulnerability_issue_links) }
+ let_it_be(:vulnerability_ids) { [] }
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 1)
+ stub_const("#{described_class}::SUB_BATCH_SIZE", 1)
+
+ 5.times.each do |x|
+ vulnerability = create_vulnerability!(
+ project_id: project.id,
+ report_type: 7,
+ author_id: user.id
+ )
+ identifier = table(:vulnerability_identifiers).create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: Digest::SHA1.hexdigest("#{vulnerability.id}"),
+ name: 'Identifier for UUIDv5')
+
+ create_finding!(
+ vulnerability_id: vulnerability.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: identifier.id
+ )
+
+ vulnerability_ids << vulnerability.id
+ end
+ end
+
+ around do |example|
+ freeze_time { Sidekiq::Testing.fake! { example.run } }
+ end
+
+ it 'schedules background migrations' do
+ migrate!
+
+ expect(background_migration_jobs.count).to eq(5)
+ expect(background_migration_jobs.first.arguments).to match_array([vulnerability_ids.first, vulnerability_ids.first, 1])
+ expect(background_migration_jobs.second.arguments).to match_array([vulnerability_ids.second, vulnerability_ids.second, 1])
+ expect(background_migration_jobs.third.arguments).to match_array([vulnerability_ids.third, vulnerability_ids.third, 1])
+ expect(background_migration_jobs.fourth.arguments).to match_array([vulnerability_ids.fourth, vulnerability_ids.fourth, 1])
+ expect(background_migration_jobs.fifth.arguments).to match_array([vulnerability_ids.fifth, vulnerability_ids.fifth, 1])
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(5)
+ expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(2.minutes, vulnerability_ids.first, vulnerability_ids.first, 1)
+ expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(4.minutes, vulnerability_ids.second, vulnerability_ids.second, 1)
+ expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(6.minutes, vulnerability_ids.third, vulnerability_ids.third, 1)
+ expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(8.minutes, vulnerability_ids.fourth, vulnerability_ids.fourth, 1)
+ expect(described_class::MIGRATION_NAME).to be_scheduled_delayed_migration(10.minutes, vulnerability_ids.fifth, vulnerability_ids.fifth, 1)
+ end
+
+ private
+
+ def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
+ vulnerabilities.create!(
+ project_id: project_id,
+ author_id: author_id,
+ title: title,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type
+ )
+ end
+
+ # rubocop:disable Metrics/ParameterLists
+ def create_finding!(
+ id: nil,
+ 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: SecureRandom.uuid)
+ params = {
+ vulnerability_id: vulnerability_id,
+ project_id: project_id,
+ name: name,
+ severity: severity,
+ confidence: confidence,
+ report_type: report_type,
+ project_fingerprint: project_fingerprint,
+ scanner_id: scanner_id,
+ primary_identifier_id: primary_identifier_id,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ }
+ params[:id] = id unless id.nil?
+ vulnerabilities_findings.create!(params)
+ end
+ # rubocop:enable Metrics/ParameterLists
+end
diff --git a/spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb b/spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb
new file mode 100644
index 00000000000..2ad9a8220c3
--- /dev/null
+++ b/spec/migrations/20220120094340_drop_position_from_security_findings_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('drop_position_from_security_findings')
+
+RSpec.describe DropPositionFromSecurityFindings do
+ let(:events) { table(:security_findings) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(events.column_names).to include('position')
+ }
+
+ migration.after -> {
+ events.reset_column_information
+ expect(events.column_names).not_to include('position')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20220124130028_dedup_runner_projects_spec.rb b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb
new file mode 100644
index 00000000000..2698af6f6f5
--- /dev/null
+++ b/spec/migrations/20220124130028_dedup_runner_projects_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20220124130028_dedup_runner_projects.rb')
+
+RSpec.describe DedupRunnerProjects, :migration, schema: 20220120085655 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:runners) { table(:ci_runners) }
+ let(:runner_projects) { table(:ci_runner_projects) }
+
+ let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
+ let!(:project) { projects.create!(namespace_id: namespace.id) }
+ let!(:project_2) { projects.create!(namespace_id: namespace.id) }
+ let!(:runner) { runners.create!(runner_type: 'project_type') }
+ let!(:runner_2) { runners.create!(runner_type: 'project_type') }
+ let!(:runner_3) { runners.create!(runner_type: 'project_type') }
+
+ let!(:duplicated_runner_project_1) { runner_projects.create!(runner_id: runner.id, project_id: project.id) }
+ let!(:duplicated_runner_project_2) { runner_projects.create!(runner_id: runner.id, project_id: project.id) }
+ let!(:duplicated_runner_project_3) { runner_projects.create!(runner_id: runner_2.id, project_id: project_2.id) }
+ let!(:duplicated_runner_project_4) { runner_projects.create!(runner_id: runner_2.id, project_id: project_2.id) }
+
+ let!(:non_duplicated_runner_project) { runner_projects.create!(runner_id: runner_3.id, project_id: project.id) }
+
+ it 'deduplicates ci_runner_projects table' do
+ expect { migrate! }.to change { runner_projects.count }.from(5).to(3)
+ end
+
+ it 'merges `duplicated_runner_project_1` with `duplicated_runner_project_2`', :aggregate_failures do
+ migrate!
+
+ expect(runner_projects.where(id: duplicated_runner_project_1.id)).not_to(exist)
+
+ merged_runner_projects = runner_projects.find_by(id: duplicated_runner_project_2.id)
+
+ expect(merged_runner_projects).to be_present
+ expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_1.created_at)
+ expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_2.created_at)
+ end
+
+ it 'merges `duplicated_runner_project_3` with `duplicated_runner_project_4`', :aggregate_failures do
+ migrate!
+
+ expect(runner_projects.where(id: duplicated_runner_project_3.id)).not_to(exist)
+
+ merged_runner_projects = runner_projects.find_by(id: duplicated_runner_project_4.id)
+
+ expect(merged_runner_projects).to be_present
+ expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_3.created_at)
+ expect(merged_runner_projects.created_at).to be_like_time(duplicated_runner_project_4.created_at)
+ end
+
+ it 'does not change non duplicated records' do
+ expect { migrate! }.not_to change { non_duplicated_runner_project.reload.attributes }
+ end
+
+ it 'does nothing when there are no runner projects' do
+ runner_projects.delete_all
+
+ migrate!
+
+ expect(runner_projects.count).to eq(0)
+ end
+end
diff --git a/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
new file mode 100644
index 00000000000..a48464befdf
--- /dev/null
+++ b/spec/migrations/20220128155251_remove_dangling_running_builds_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('remove_dangling_running_builds')
+
+RSpec.describe RemoveDanglingRunningBuilds do
+ let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+ let(:project) { table(:projects).create!(namespace_id: namespace.id) }
+ let(:runner) { table(:ci_runners).create!(runner_type: 1) }
+ let(:builds) { table(:ci_builds) }
+ let(:running_builds) { table(:ci_running_builds) }
+
+ let(:running_build) do
+ builds.create!(
+ name: 'test 1',
+ status: 'running',
+ project_id: project.id,
+ type: 'Ci::Build')
+ end
+
+ let(:failed_build) do
+ builds.create!(
+ name: 'test 2',
+ status: 'failed',
+ project_id: project.id,
+ type: 'Ci::Build')
+ end
+
+ let!(:running_metadata) do
+ running_builds.create!(
+ build_id: running_build.id,
+ project_id: project.id,
+ runner_id: runner.id,
+ runner_type:
+ runner.runner_type)
+ end
+
+ let!(:failed_metadata) do
+ running_builds.create!(
+ build_id: failed_build.id,
+ project_id: project.id,
+ runner_id: runner.id,
+ runner_type: runner.runner_type)
+ end
+
+ it 'removes failed builds' do
+ migrate!
+
+ expect(running_metadata.reload).to be_present
+ expect { failed_metadata.reload } .to raise_error(ActiveRecord::RecordNotFound)
+ end
+end
diff --git a/spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb b/spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb
new file mode 100644
index 00000000000..1558facdf96
--- /dev/null
+++ b/spec/migrations/20220128155814_fix_approval_rules_code_owners_rule_type_index_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('fix_approval_rules_code_owners_rule_type_index')
+
+RSpec.describe FixApprovalRulesCodeOwnersRuleTypeIndex, :migration do
+ let(:table_name) { :approval_merge_request_rules }
+ let(:index_name) { 'index_approval_rules_code_owners_rule_type' }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy
+ }
+
+ migration.after -> {
+ expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy
+ }
+ end
+ end
+
+ context 'when the index already exists' do
+ before do
+ subject.add_concurrent_index table_name, :merge_request_id, where: 'rule_type = 2', name: index_name
+ end
+
+ it 'keeps the index' do
+ migrate!
+
+ expect(subject.index_exists_by_name?(table_name, index_name)).to be_truthy
+ end
+ end
+end
diff --git a/spec/migrations/20220202105733_delete_service_template_records_spec.rb b/spec/migrations/20220202105733_delete_service_template_records_spec.rb
new file mode 100644
index 00000000000..c9f6b5cbe66
--- /dev/null
+++ b/spec/migrations/20220202105733_delete_service_template_records_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe DeleteServiceTemplateRecords do
+ let(:integrations) { table(:integrations) }
+ let(:chat_names) { table(:chat_names) }
+ let(:web_hooks) { table(:web_hooks) }
+ let(:slack_integrations) { table(:slack_integrations) }
+ let(:zentao_tracker_data) { table(:zentao_tracker_data) }
+ let(:jira_tracker_data) { table(:jira_tracker_data) }
+ let(:issue_tracker_data) { table(:issue_tracker_data) }
+
+ before do
+ template = integrations.create!(template: true)
+ chat_names.create!(service_id: template.id, user_id: 1, team_id: 1, chat_id: 1)
+ web_hooks.create!(service_id: template.id)
+ slack_integrations.create!(service_id: template.id, team_id: 1, team_name: 'team', alias: 'alias', user_id: 1)
+ zentao_tracker_data.create!(integration_id: template.id)
+ jira_tracker_data.create!(service_id: template.id)
+ issue_tracker_data.create!(service_id: template.id)
+
+ integrations.create!(template: false)
+ end
+
+ it 'deletes template records and associated data' do
+ expect { migrate! }
+ .to change { integrations.where(template: true).count }.from(1).to(0)
+ .and change { chat_names.count }.from(1).to(0)
+ .and change { web_hooks.count }.from(1).to(0)
+ .and change { slack_integrations.count }.from(1).to(0)
+ .and change { zentao_tracker_data.count }.from(1).to(0)
+ .and change { jira_tracker_data.count }.from(1).to(0)
+ .and change { issue_tracker_data.count }.from(1).to(0)
+ end
+
+ it 'does not delete non template records' do
+ expect { migrate! }
+ .not_to change { integrations.where(template: false).count }
+ end
+end
diff --git a/spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb b/spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb
new file mode 100644
index 00000000000..bf79ee02ff1
--- /dev/null
+++ b/spec/migrations/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe UpdateIntegrationsTriggerTypeNewOnInsertNullSafe, :migration do
+ let(:integrations) { table(:integrations) }
+
+ before do
+ migrate!
+ end
+
+ it 'leaves defined values alone' do
+ record = integrations.create!(type: 'XService', type_new: 'Integrations::Y')
+
+ expect(integrations.find(record.id)).to have_attributes(type: 'XService', type_new: 'Integrations::Y')
+ end
+
+ it 'keeps type_new synchronized with type' do
+ record = integrations.create!(type: 'AbcService', type_new: nil)
+
+ expect(integrations.find(record.id)).to have_attributes(
+ type: 'AbcService',
+ type_new: 'Integrations::Abc'
+ )
+ end
+
+ it 'keeps type synchronized with type_new' do
+ record = integrations.create!(type: nil, type_new: 'Integrations::Abc')
+
+ expect(integrations.find(record.id)).to have_attributes(
+ type: 'AbcService',
+ type_new: 'Integrations::Abc'
+ )
+ end
+end
diff --git a/spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb b/spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb
new file mode 100644
index 00000000000..913ec404795
--- /dev/null
+++ b/spec/migrations/backfill_namespace_id_for_namespace_routes_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillNamespaceIdForNamespaceRoutes do
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of routes' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :routes,
+ column_name: :id,
+ interval: described_class::INTERVAL
+ )
+ end
+ end
+
+ describe '#down' do
+ it 'deletes all batched migration records' do
+ migrate!
+ schema_migrate_down!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/backfill_project_namespaces_for_group_spec.rb b/spec/migrations/backfill_project_namespaces_for_group_spec.rb
new file mode 100644
index 00000000000..0d34d19d42a
--- /dev/null
+++ b/spec/migrations/backfill_project_namespaces_for_group_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillProjectNamespacesForGroup do
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:parent_group1) { namespaces.create!(name: 'parent_group1', path: 'parent_group1', visibility_level: 20, type: 'Group') }
+ let!(:parent_group1_project) { projects.create!(name: 'parent_group1_project', path: 'parent_group1_project', namespace_id: parent_group1.id, visibility_level: 20) }
+
+ before do
+ allow(Gitlab).to receive(:com?).and_return(true)
+ end
+
+ describe '#up' do
+ before do
+ stub_const("BackfillProjectNamespacesForGroup::GROUP_ID", parent_group1.id)
+ end
+
+ it 'schedules background jobs for each batch of namespaces' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :projects,
+ column_name: :id,
+ job_arguments: [described_class::GROUP_ID, 'up'],
+ interval: described_class::DELAY_INTERVAL
+ )
+ end
+ end
+
+ describe '#down' do
+ it 'deletes all batched migration records' do
+ migrate!
+ schema_migrate_down!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/populate_audit_event_streaming_verification_token_spec.rb b/spec/migrations/populate_audit_event_streaming_verification_token_spec.rb
new file mode 100644
index 00000000000..b3fe1776183
--- /dev/null
+++ b/spec/migrations/populate_audit_event_streaming_verification_token_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe PopulateAuditEventStreamingVerificationToken do
+ let(:groups) { table(:namespaces) }
+ let(:destinations) { table(:audit_events_external_audit_event_destinations) }
+ let(:migration) { described_class.new }
+
+ let!(:group) { groups.create!(name: 'test-group', path: 'test-group') }
+ let!(:destination) { destinations.create!(namespace_id: group.id, destination_url: 'https://example.com/destination', verification_token: nil) }
+
+ describe '#up' do
+ it 'adds verification tokens to records created before the migration' do
+ expect do
+ migrate!
+ destination.reload
+ end.to change { destination.verification_token }.from(nil).to(a_string_matching(/\w{24}/))
+ end
+ end
+end
diff --git a/spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb b/spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb
new file mode 100644
index 00000000000..3720be6cf3e
--- /dev/null
+++ b/spec/migrations/schedule_fix_incorrect_max_seats_used2_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleFixIncorrectMaxSeatsUsed2, :migration do
+ let(:migration_name) { described_class::MIGRATION.to_s.demodulize }
+
+ describe '#up' do
+ it 'schedules a job on Gitlab.com' do
+ allow(Gitlab).to receive(:com?).and_return(true)
+
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(migration_name).to be_scheduled_delayed_migration(1.hour, 'batch_2_for_start_date_before_02_aug_2021')
+ expect(BackgroundMigrationWorker.jobs.size).to eq(1)
+ end
+ end
+ end
+
+ it 'does not schedule any jobs when not Gitlab.com' do
+ allow(Gitlab).to receive(:com?).and_return(false)
+
+ Sidekiq::Testing.fake! do
+ migrate!
+
+ expect(migration_name).not_to be_scheduled_delayed_migration
+ expect(BackgroundMigrationWorker.jobs.size).to eq(0)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb b/spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb
new file mode 100644
index 00000000000..74258f03630
--- /dev/null
+++ b/spec/migrations/schedule_fix_incorrect_max_seats_used_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleFixIncorrectMaxSeatsUsed, :migration do
+ let(:migration) { described_class.new }
+
+ describe '#up' do
+ it 'schedules a job on Gitlab.com' do
+ allow(Gitlab).to receive(:com?).and_return(true)
+
+ expect(migration).to receive(:migrate_in).with(1.hour, 'FixIncorrectMaxSeatsUsed')
+
+ migration.up
+ end
+
+ it 'does not schedule any jobs when not Gitlab.com' do
+ allow(Gitlab::CurrentSettings).to receive(:com?).and_return(false)
+
+ expect(migration).not_to receive(:migrate_in)
+
+ migration.up
+ end
+ end
+end
diff --git a/spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb b/spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb
index 2545bb4a66c..9b62dd79e08 100644
--- a/spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb
+++ b/spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb
@@ -51,16 +51,17 @@ RSpec.describe ScheduleRecalculateVulnerabilityFindingSignaturesForFindings, :mi
let_it_be(:finding3) { findings.create!(finding_params) }
let_it_be(:signature3) { vulnerability_finding_signatures.create!(finding_id: finding3.id, algorithm_type: 0, signature_sha: ::Digest::SHA1.digest(SecureRandom.hex(50))) }
- it 'schedules the background jobs', :aggregate_failure do
+ # this migration is now a no-op
+ it 'does not schedule the background jobs', :aggregate_failure do
Sidekiq::Testing.fake! do
freeze_time do
migrate!
- expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ expect(BackgroundMigrationWorker.jobs.size).to eq(0)
expect(described_class::MIGRATION)
- .to be_scheduled_migration_with_multiple_args(signature1.id, signature2.id)
+ .not_to be_scheduled_migration_with_multiple_args(signature1.id, signature2.id)
expect(described_class::MIGRATION)
- .to be_scheduled_migration_with_multiple_args(signature3.id, signature3.id)
+ .not_to be_scheduled_migration_with_multiple_args(signature3.id, signature3.id)
end
end
end
diff --git a/spec/migrations/start_backfill_ci_queuing_tables_spec.rb b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb
new file mode 100644
index 00000000000..a1e4179efb6
--- /dev/null
+++ b/spec/migrations/start_backfill_ci_queuing_tables_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe StartBackfillCiQueuingTables do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:builds) { table(:ci_builds) }
+
+ let!(:namespace) do
+ namespaces.create!(name: 'namespace1', path: 'namespace1')
+ end
+
+ let!(:project) do
+ projects.create!(namespace_id: namespace.id, name: 'test1', path: 'test1')
+ end
+
+ let!(:pending_build_1) do
+ builds.create!(status: :pending, name: 'test1', type: 'Ci::Build', project_id: project.id)
+ end
+
+ let!(:running_build) do
+ builds.create!(status: :running, name: 'test2', type: 'Ci::Build', project_id: project.id)
+ end
+
+ let!(:pending_build_2) do
+ builds.create!(status: :pending, name: 'test3', type: 'Ci::Build', project_id: project.id)
+ end
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 1)
+ end
+
+ it 'schedules jobs for builds that are pending' do
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
+ 2.minutes, pending_build_1.id, pending_build_1.id)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(
+ 4.minutes, pending_build_2.id, pending_build_2.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb b/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
new file mode 100644
index 00000000000..b73aa7016a1
--- /dev/null
+++ b/spec/migrations/update_default_scan_method_of_dast_site_profile_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe UpdateDefaultScanMethodOfDastSiteProfile do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:dast_sites) { table(:dast_sites) }
+ let(:dast_site_profiles) { table(:dast_site_profiles) }
+
+ before do
+ namespace = namespaces.create!(name: 'test', path: 'test')
+ project = projects.create!(id: 12, namespace_id: namespace.id, name: 'gitlab', path: 'gitlab')
+ dast_site = dast_sites.create!(id: 1, url: 'https://www.gitlab.com', project_id: project.id)
+
+ dast_site_profiles.create!(id: 1, project_id: project.id, dast_site_id: dast_site.id,
+ name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 0",
+ scan_method: 0, target_type: 0)
+
+ dast_site_profiles.create!(id: 2, project_id: project.id, dast_site_id: dast_site.id,
+ name: "#{FFaker::Product.product_name.truncate(192)} #{SecureRandom.hex(4)} - 1",
+ scan_method: 0, target_type: 1)
+ end
+
+ it 'updates the scan_method to 1 for profiles with target_type 1' do
+ migrate!
+
+ expect(dast_site_profiles.where(scan_method: 1).count).to eq 1
+ expect(dast_site_profiles.where(scan_method: 0).count).to eq 1
+ end
+end