Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20201112130710_schedule_remove_duplicate_vulnerabilities_findings_spec.rb140
-rw-r--r--spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb30
-rw-r--r--spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb28
-rw-r--r--spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb47
-rw-r--r--spec/migrations/add_has_external_issue_tracker_trigger_spec.rb164
-rw-r--r--spec/migrations/add_new_post_eoa_plans_spec.rb32
-rw-r--r--spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb89
-rw-r--r--spec/migrations/drop_alerts_service_data_spec.rb21
-rw-r--r--spec/migrations/encrypt_feature_flags_clients_tokens_spec.rb2
-rw-r--r--spec/migrations/remove_alerts_service_records_again_spec.rb23
-rw-r--r--spec/migrations/schedule_migrate_security_scans_spec.rb11
-rw-r--r--spec/migrations/schedule_populate_issue_email_participants_spec.rb33
12 files changed, 613 insertions, 7 deletions
diff --git a/spec/migrations/20201112130710_schedule_remove_duplicate_vulnerabilities_findings_spec.rb b/spec/migrations/20201112130710_schedule_remove_duplicate_vulnerabilities_findings_spec.rb
new file mode 100644
index 00000000000..ff27bdcf12d
--- /dev/null
+++ b/spec/migrations/20201112130710_schedule_remove_duplicate_vulnerabilities_findings_spec.rb
@@ -0,0 +1,140 @@
+# frozen_string_literal: true
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20201112130710_schedule_remove_duplicate_vulnerabilities_findings.rb')
+
+RSpec.describe ScheduleRemoveDuplicateVulnerabilitiesFindings, :migration do
+ 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!(:scanner2) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
+ let!(:scanner3) { scanners.create!(project_id: project.id, external_id: 'test 3', name: 'test scanner 3') }
+ let!(:unrelated_scanner) { scanners.create!(project_id: project.id, external_id: 'unreleated_scanner', name: 'unrelated scanner') }
+ let(:vulnerabilities) { table(:vulnerabilities) }
+ let(:vulnerability_findings) { table(:vulnerability_occurrences) }
+ let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
+ let(:vulnerability_identifier) do
+ vulnerability_identifiers.create!(
+ project_id: project.id,
+ external_type: 'vulnerability-identifier',
+ external_id: 'vulnerability-identifier',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'vulnerability identifier')
+ end
+
+ let!(:first_finding) do
+ create_finding!(
+ uuid: "test1",
+ vulnerability_id: nil,
+ report_type: 0,
+ location_fingerprint: '2bda3014914481791847d8eca38d1a8d13b6ad76',
+ primary_identifier_id: vulnerability_identifier.id,
+ scanner_id: scanner.id,
+ project_id: project.id
+ )
+ end
+
+ let!(:first_duplicate) do
+ create_finding!(
+ uuid: "test2",
+ vulnerability_id: nil,
+ report_type: 0,
+ location_fingerprint: '2bda3014914481791847d8eca38d1a8d13b6ad76',
+ primary_identifier_id: vulnerability_identifier.id,
+ scanner_id: scanner2.id,
+ project_id: project.id
+ )
+ end
+
+ let!(:second_duplicate) do
+ create_finding!(
+ uuid: "test3",
+ vulnerability_id: nil,
+ report_type: 0,
+ location_fingerprint: '2bda3014914481791847d8eca38d1a8d13b6ad76',
+ primary_identifier_id: vulnerability_identifier.id,
+ scanner_id: scanner3.id,
+ project_id: project.id
+ )
+ end
+
+ let!(:unrelated_finding) do
+ create_finding!(
+ uuid: "unreleated_finding",
+ vulnerability_id: nil,
+ report_type: 1,
+ location_fingerprint: 'random_location_fingerprint',
+ primary_identifier_id: vulnerability_identifier.id,
+ scanner_id: unrelated_scanner.id,
+ project_id: project.id
+ )
+ end
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 1)
+ end
+
+ around do |example|
+ freeze_time { Sidekiq::Testing.fake! { example.run } }
+ end
+
+ it 'schedules background migration' do
+ migrate!
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(4)
+ expect(described_class::MIGRATION).to be_scheduled_migration(first_finding.id, first_finding.id)
+ expect(described_class::MIGRATION).to be_scheduled_migration(first_duplicate.id, first_duplicate.id)
+ expect(described_class::MIGRATION).to be_scheduled_migration(second_duplicate.id, second_duplicate.id)
+ expect(described_class::MIGRATION).to be_scheduled_migration(unrelated_finding.id, unrelated_finding.id)
+ 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:, 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')
+ vulnerability_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: vulnerability_identifier.id,
+ location_fingerprint: location_fingerprint,
+ metadata_version: metadata_version,
+ raw_metadata: raw_metadata,
+ uuid: uuid
+ )
+ end
+ # rubocop:enable Metrics/ParameterLists
+
+ def create_user!(name: "Example User", email: "user@example.com", user_type: nil, created_at: Time.now, confirmed_at: Time.now)
+ users.create!(
+ name: name,
+ email: email,
+ username: name,
+ projects_limit: 0,
+ user_type: user_type,
+ confirmed_at: confirmed_at
+ )
+ end
+end
diff --git a/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb b/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb
new file mode 100644
index 00000000000..33b2e009c8d
--- /dev/null
+++ b/spec/migrations/20210119122354_alter_vsa_issue_first_mentioned_in_commit_value_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210119122354_alter_vsa_issue_first_mentioned_in_commit_value.rb')
+
+RSpec.describe AlterVsaIssueFirstMentionedInCommitValue, schema: 20210114033715 do
+ let(:group_stages) { table(:analytics_cycle_analytics_group_stages) }
+ let(:value_streams) { table(:analytics_cycle_analytics_group_value_streams) }
+ let(:namespaces) { table(:namespaces) }
+
+ let(:namespace) { namespaces.create!(id: 1, name: 'group', path: 'group') }
+ let(:value_stream) { value_streams.create!(name: 'test', group_id: namespace.id) }
+
+ let!(:stage_1) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 1', start_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_EE, end_event_identifier: 1) }
+ let!(:stage_2) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 2', start_event_identifier: 2, end_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_EE) }
+ let!(:stage_3) { group_stages.create!(group_value_stream_id: value_stream.id, group_id: namespace.id, name: 'stage 3', start_event_identifier: described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS, end_event_identifier: 3) }
+
+ describe '#up' do
+ it 'changes the EE specific identifier values to the FOSS version' do
+ migrate!
+
+ expect(stage_1.reload.start_event_identifier).to eq(described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS)
+ expect(stage_2.reload.end_event_identifier).to eq(described_class::ISSUE_FIRST_MENTIONED_IN_COMMIT_FOSS)
+ end
+
+ it 'does not change irrelevant records' do
+ expect { migrate! }.not_to change { stage_3.reload }
+ end
+ end
+end
diff --git a/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb b/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb
new file mode 100644
index 00000000000..7e351617ea3
--- /dev/null
+++ b/spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210205174154_remove_bad_dependency_proxy_manifests.rb')
+
+RSpec.describe RemoveBadDependencyProxyManifests, schema: 20210128140157 do
+ let_it_be(:namespaces) { table(:namespaces) }
+ let_it_be(:dependency_proxy_manifests) { table(:dependency_proxy_manifests) }
+ let_it_be(:group) { namespaces.create!(type: 'Group', name: 'test', path: 'test') }
+
+ let_it_be(:dependency_proxy_manifest_with_content_type) do
+ dependency_proxy_manifests.create!(group_id: group.id, file: 'foo', file_name: 'foo', digest: 'asdf1234', content_type: 'content-type' )
+ end
+
+ let_it_be(:dependency_proxy_manifest_without_content_type) do
+ dependency_proxy_manifests.create!(group_id: group.id, file: 'bar', file_name: 'bar', digest: 'fdsa6789')
+ end
+
+ it 'removes the dependency_proxy_manifests with a content_type', :aggregate_failures do
+ expect(dependency_proxy_manifest_with_content_type).to be_present
+ expect(dependency_proxy_manifest_without_content_type).to be_present
+
+ expect { migrate! }.to change { dependency_proxy_manifests.count }.from(2).to(1)
+
+ expect(dependency_proxy_manifests.where.not(content_type: nil)).to be_empty
+ expect(dependency_proxy_manifest_without_content_type.reload).to be_present
+ end
+end
diff --git a/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb b/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb
new file mode 100644
index 00000000000..52678111b48
--- /dev/null
+++ b/spec/migrations/20210210093901_backfill_updated_at_after_repository_storage_move_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210210093901_backfill_updated_at_after_repository_storage_move.rb')
+
+RSpec.describe BackfillUpdatedAtAfterRepositoryStorageMove, :sidekiq do
+ let_it_be(:projects) { table(:projects) }
+ let_it_be(:project_repository_storage_moves) { table(:project_repository_storage_moves) }
+ let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
+
+ describe '#up' do
+ it 'schedules background jobs for all distinct projects in batches' do
+ stub_const("#{described_class}::BATCH_SIZE", 3)
+
+ project_1 = projects.create!(id: 1, namespace_id: namespace.id)
+ project_2 = projects.create!(id: 2, namespace_id: namespace.id)
+ project_3 = projects.create!(id: 3, namespace_id: namespace.id)
+ project_4 = projects.create!(id: 4, namespace_id: namespace.id)
+ project_5 = projects.create!(id: 5, namespace_id: namespace.id)
+ project_6 = projects.create!(id: 6, namespace_id: namespace.id)
+ project_7 = projects.create!(id: 7, namespace_id: namespace.id)
+ projects.create!(id: 8, namespace_id: namespace.id)
+
+ project_repository_storage_moves.create!(id: 1, project_id: project_1.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 2, project_id: project_1.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 3, project_id: project_2.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 4, project_id: project_3.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 5, project_id: project_3.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 6, project_id: project_4.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 7, project_id: project_4.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 8, project_id: project_5.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 9, project_id: project_6.id, source_storage_name: 'default', destination_storage_name: 'default')
+ project_repository_storage_moves.create!(id: 10, project_id: project_7.id, source_storage_name: 'default', destination_storage_name: 'default')
+
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(3)
+ expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(2.minutes, 1, 2, 3)
+ expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(4.minutes, 4, 5, 6)
+ expect(described_class::MIGRATION_CLASS).to be_scheduled_delayed_migration(6.minutes, 7)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb b/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb
new file mode 100644
index 00000000000..72983c7cfbf
--- /dev/null
+++ b/spec/migrations/add_has_external_issue_tracker_trigger_spec.rb
@@ -0,0 +1,164 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe AddHasExternalIssueTrackerTrigger do
+ let(:migration) { described_class.new }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:services) { table(:services) }
+
+ before do
+ @namespace = namespaces.create!(name: 'foo', path: 'foo')
+ @project = projects.create!(namespace_id: @namespace.id)
+ end
+
+ describe '#up' do
+ before do
+ migrate!
+ end
+
+ describe 'INSERT trigger' do
+ it 'sets `has_external_issue_tracker` to true when active `issue_tracker` is inserted' do
+ expect do
+ services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+ end.to change { @project.reload.has_external_issue_tracker }.to(true)
+ end
+
+ it 'does not set `has_external_issue_tracker` to true when service is for a different project' do
+ different_project = projects.create!(namespace_id: @namespace.id)
+
+ expect do
+ services.create!(category: 'issue_tracker', active: true, project_id: different_project.id)
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+
+ it 'does not set `has_external_issue_tracker` to true when inactive `issue_tracker` is inserted' do
+ expect do
+ services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+
+ it 'does not set `has_external_issue_tracker` to true when a non-`issue tracker` active service is inserted' do
+ expect do
+ services.create!(category: 'my_type', active: true, project_id: @project.id)
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+ end
+
+ describe 'UPDATE trigger' do
+ it 'sets `has_external_issue_tracker` to true when `issue_tracker` is made active' do
+ service = services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
+
+ expect do
+ service.update!(active: true)
+ end.to change { @project.reload.has_external_issue_tracker }.to(true)
+ end
+
+ it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive' do
+ service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+
+ expect do
+ service.update!(active: false)
+ end.to change { @project.reload.has_external_issue_tracker }.to(false)
+ end
+
+ it 'sets `has_external_issue_tracker` to false when `issue_tracker` is made inactive, and an inactive `issue_tracker` exists' do
+ services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
+ service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+
+ expect do
+ service.update!(active: false)
+ end.to change { @project.reload.has_external_issue_tracker }.to(false)
+ end
+
+ it 'does not change `has_external_issue_tracker` when `issue_tracker` is made inactive, if an active `issue_tracker` exists' do
+ services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+ service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+
+ expect do
+ service.update!(active: false)
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+
+ it 'does not change `has_external_issue_tracker` when service is for a different project' do
+ different_project = projects.create!(namespace_id: @namespace.id)
+ service = services.create!(category: 'issue_tracker', active: false, project_id: different_project.id)
+
+ expect do
+ service.update!(active: true)
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+ end
+
+ describe 'DELETE trigger' do
+ it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted' do
+ service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+
+ expect do
+ service.delete
+ end.to change { @project.reload.has_external_issue_tracker }.to(false)
+ end
+
+ it 'sets `has_external_issue_tracker` to false when `issue_tracker` is deleted, if an inactive `issue_tracker` still exists' do
+ services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
+ service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+
+ expect do
+ service.delete
+ end.to change { @project.reload.has_external_issue_tracker }.to(false)
+ end
+
+ it 'does not change `has_external_issue_tracker` when `issue_tracker` is deleted, if an active `issue_tracker` still exists' do
+ services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+ service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+
+ expect do
+ service.delete
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+
+ it 'does not change `has_external_issue_tracker` when service is for a different project' do
+ different_project = projects.create!(namespace_id: @namespace.id)
+ service = services.create!(category: 'issue_tracker', active: true, project_id: different_project.id)
+
+ expect do
+ service.delete
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+ end
+ end
+
+ describe '#down' do
+ before do
+ migration.up
+ migration.down
+ end
+
+ it 'drops the INSERT trigger' do
+ expect do
+ services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+
+ it 'drops the UPDATE trigger' do
+ service = services.create!(category: 'issue_tracker', active: false, project_id: @project.id)
+ @project.update!(has_external_issue_tracker: false)
+
+ expect do
+ service.update!(active: true)
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+
+ it 'drops the DELETE trigger' do
+ service = services.create!(category: 'issue_tracker', active: true, project_id: @project.id)
+ @project.update!(has_external_issue_tracker: true)
+
+ expect do
+ service.delete
+ end.not_to change { @project.reload.has_external_issue_tracker }
+ end
+ end
+end
diff --git a/spec/migrations/add_new_post_eoa_plans_spec.rb b/spec/migrations/add_new_post_eoa_plans_spec.rb
new file mode 100644
index 00000000000..5ae227a6617
--- /dev/null
+++ b/spec/migrations/add_new_post_eoa_plans_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require Rails.root.join('db', 'post_migrate', '20210205104425_add_new_post_eoa_plans.rb')
+
+RSpec.describe AddNewPostEoaPlans do
+ let(:plans) { table(:plans) }
+
+ subject(:migration) { described_class.new }
+
+ describe '#up' do
+ it 'creates the two new records' do
+ expect { migration.up }.to change { plans.count }.by(2)
+
+ new_plans = plans.last(2)
+ expect(new_plans.map(&:name)).to contain_exactly('premium', 'ultimate')
+ end
+ end
+
+ describe '#down' do
+ it 'removes these two new records' do
+ plans.create!(name: 'premium', title: 'Premium (Formerly Silver)')
+ plans.create!(name: 'ultimate', title: 'Ultimate (Formerly Gold)')
+
+ expect { migration.down }.to change { plans.count }.by(-2)
+
+ expect(plans.find_by(name: 'premium')).to be_nil
+ expect(plans.find_by(name: 'ultimate')).to be_nil
+ end
+ end
+end
diff --git a/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb b/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb
new file mode 100644
index 00000000000..ee1f718849f
--- /dev/null
+++ b/spec/migrations/cleanup_projects_with_bad_has_external_wiki_data_spec.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe CleanupProjectsWithBadHasExternalWikiData, :migration do
+ let(:namespace) { table(:namespaces).create!(name: 'foo', path: 'bar') }
+ let(:projects) { table(:projects) }
+ let(:services) { table(:services) }
+
+ def create_projects!(num)
+ Array.new(num) do
+ projects.create!(namespace_id: namespace.id)
+ end
+ end
+
+ def create_active_external_wiki_integrations!(*projects)
+ projects.each do |project|
+ services.create!(type: 'ExternalWikiService', project_id: project.id, active: true)
+ end
+ end
+
+ def create_disabled_external_wiki_integrations!(*projects)
+ projects.each do |project|
+ services.create!(type: 'ExternalWikiService', project_id: project.id, active: false)
+ end
+ end
+
+ def create_active_other_integrations!(*projects)
+ projects.each do |project|
+ services.create!(type: 'NotAnExternalWikiService', project_id: project.id, active: true)
+ end
+ end
+
+ it 'sets `projects.has_external_wiki` correctly' do
+ allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
+
+ project_with_external_wiki_1,
+ project_with_external_wiki_2,
+ project_with_disabled_external_wiki_1,
+ project_with_disabled_external_wiki_2,
+ project_without_external_wiki_1,
+ project_without_external_wiki_2 = create_projects!(6)
+
+ create_active_external_wiki_integrations!(
+ project_with_external_wiki_1,
+ project_with_external_wiki_2
+ )
+
+ create_disabled_external_wiki_integrations!(
+ project_with_disabled_external_wiki_1,
+ project_with_disabled_external_wiki_2
+ )
+
+ create_active_other_integrations!(
+ project_without_external_wiki_1,
+ project_without_external_wiki_2
+ )
+
+ # PG triggers on the services table added in a previous migration
+ # will have set the `has_external_wiki` columns to correct data when
+ # the services records were created above.
+ #
+ # We set the `has_external_wiki` columns for projects to incorrect
+ # data manually below to emulate projects in a state before the PG
+ # triggers were added.
+ project_with_external_wiki_2.update!(has_external_wiki: false)
+ project_with_disabled_external_wiki_2.update!(has_external_wiki: true)
+ project_without_external_wiki_2.update!(has_external_wiki: true)
+
+ migrate!
+
+ expected_true = [
+ project_with_external_wiki_1,
+ project_with_external_wiki_2
+ ].each(&:reload).map(&:has_external_wiki)
+
+ expected_not_true = [
+ project_without_external_wiki_1,
+ project_without_external_wiki_2,
+ project_with_disabled_external_wiki_1,
+ project_with_disabled_external_wiki_2
+ ].each(&:reload).map(&:has_external_wiki)
+
+ expect(expected_true).to all(eq(true))
+ expect(expected_not_true).to all(be_falsey)
+ end
+end
diff --git a/spec/migrations/drop_alerts_service_data_spec.rb b/spec/migrations/drop_alerts_service_data_spec.rb
new file mode 100644
index 00000000000..b2128da938f
--- /dev/null
+++ b/spec/migrations/drop_alerts_service_data_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210205213933_drop_alerts_service_data.rb')
+
+RSpec.describe DropAlertsServiceData do
+ let_it_be(:alerts_service_data) { table(:alerts_service_data) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(alerts_service_data.create!(service_id: 1)).to be_a alerts_service_data
+ }
+
+ migration.after -> {
+ expect { alerts_service_data.create!(service_id: 1) }
+ .to raise_error(ActiveRecord::StatementInvalid, /UndefinedTable/)
+ }
+ end
+ end
+end
diff --git a/spec/migrations/encrypt_feature_flags_clients_tokens_spec.rb b/spec/migrations/encrypt_feature_flags_clients_tokens_spec.rb
index ad83119f324..c705515ce98 100644
--- a/spec/migrations/encrypt_feature_flags_clients_tokens_spec.rb
+++ b/spec/migrations/encrypt_feature_flags_clients_tokens_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe EncryptFeatureFlagsClientsTokens do
let(:feature_flags_clients) { table(:operations_feature_flags_clients) }
let(:projects) { table(:projects) }
let(:plaintext) { "secret-token" }
- let(:ciphertext) { Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext) }
+ let(:ciphertext) { Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext, nonce: Gitlab::CryptoHelper::AES256_GCM_IV_STATIC) }
describe '#up' do
it 'keeps plaintext token the same and populates token_encrypted if not present' do
diff --git a/spec/migrations/remove_alerts_service_records_again_spec.rb b/spec/migrations/remove_alerts_service_records_again_spec.rb
new file mode 100644
index 00000000000..963b54848f9
--- /dev/null
+++ b/spec/migrations/remove_alerts_service_records_again_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210205214003_remove_alerts_service_records_again.rb')
+
+RSpec.describe RemoveAlertsServiceRecordsAgain do
+ let(:services) { table(:services) }
+
+ before do
+ 5.times { services.create!(type: 'AlertsService') }
+ services.create!(type: 'SomeOtherType')
+ end
+
+ it 'removes services records of type AlertsService and corresponding data', :aggregate_failures do
+ expect(services.count).to eq(6)
+
+ migrate!
+
+ expect(services.count).to eq(1)
+ expect(services.first.type).to eq('SomeOtherType')
+ expect(services.where(type: 'AlertsService')).to be_empty
+ end
+end
diff --git a/spec/migrations/schedule_migrate_security_scans_spec.rb b/spec/migrations/schedule_migrate_security_scans_spec.rb
index 61b14f239ae..eb86a910611 100644
--- a/spec/migrations/schedule_migrate_security_scans_spec.rb
+++ b/spec/migrations/schedule_migrate_security_scans_spec.rb
@@ -3,7 +3,6 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20200217225719_schedule_migrate_security_scans.rb')
-# rubocop: disable RSpec/FactoriesInMigrationSpecs
RSpec.describe ScheduleMigrateSecurityScans, :sidekiq do
let(:migration) { described_class.new }
let(:namespaces) { table(:namespaces) }
@@ -13,7 +12,7 @@ RSpec.describe ScheduleMigrateSecurityScans, :sidekiq do
let(:namespace) { namespaces.create!(name: "foo", path: "bar") }
let(:project) { projects.create!(namespace_id: namespace.id) }
- let(:build) { builds.create! }
+ let(:job) { builds.create! }
before do
stub_const("#{described_class.name}::BATCH_SIZE", 1)
@@ -35,8 +34,8 @@ RSpec.describe ScheduleMigrateSecurityScans, :sidekiq do
end
context 'has security job artifacts' do
- let!(:job_artifact_1) { job_artifacts.create!(project_id: project.id, job_id: build.id, file_type: 5) }
- let!(:job_artifact_2) { job_artifacts.create!(project_id: project.id, job_id: build.id, file_type: 8) }
+ let!(:job_artifact_1) { job_artifacts.create!(project_id: project.id, job_id: job.id, file_type: 5) }
+ let!(:job_artifact_2) { job_artifacts.create!(project_id: project.id, job_id: job.id, file_type: 8) }
it 'schedules migration of security scans' do
Sidekiq::Testing.fake! do
@@ -52,8 +51,8 @@ RSpec.describe ScheduleMigrateSecurityScans, :sidekiq do
end
context 'has non-security job artifacts' do
- let!(:job_artifact_1) { job_artifacts.create!(project_id: project.id, job_id: build.id, file_type: 4) }
- let!(:job_artifact_2) { job_artifacts.create!(project_id: project.id, job_id: build.id, file_type: 9) }
+ let!(:job_artifact_1) { job_artifacts.create!(project_id: project.id, job_id: job.id, file_type: 4) }
+ let!(:job_artifact_2) { job_artifacts.create!(project_id: project.id, job_id: job.id, file_type: 9) }
it 'schedules migration of security scans' do
Sidekiq::Testing.fake! do
diff --git a/spec/migrations/schedule_populate_issue_email_participants_spec.rb b/spec/migrations/schedule_populate_issue_email_participants_spec.rb
new file mode 100644
index 00000000000..a3f18617b70
--- /dev/null
+++ b/spec/migrations/schedule_populate_issue_email_participants_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20201128210234_schedule_populate_issue_email_participants.rb')
+
+RSpec.describe SchedulePopulateIssueEmailParticipants do
+ let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
+ let!(:project) { table(:projects).create!(id: 1, namespace_id: namespace.id) }
+ let!(:issue1) { table(:issues).create!(id: 1, project_id: project.id, service_desk_reply_to: "a@gitlab.com") }
+ let!(:issue2) { table(:issues).create!(id: 2, project_id: project.id) }
+ let!(:issue3) { table(:issues).create!(id: 3, project_id: project.id, service_desk_reply_to: "b@gitlab.com") }
+ let!(:issue4) { table(:issues).create!(id: 4, project_id: project.id, service_desk_reply_to: "c@gitlab.com") }
+ let!(:issue5) { table(:issues).create!(id: 5, project_id: project.id, service_desk_reply_to: "d@gitlab.com") }
+ let(:issue_email_participants) { table(:issue_email_participants) }
+
+ it 'correctly schedules background migrations' do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(2.minutes, 1, 3)
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(4.minutes, 4, 5)
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ end
+ end
+ end
+end