summaryrefslogtreecommitdiff
path: root/spec/migrations
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 15:44:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 15:44:42 +0000
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /spec/migrations
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
downloadgitlab-ce-4555e1b21c365ed8303ffb7a3325d773c9b8bf31.tar.gz
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'spec/migrations')
-rw-r--r--spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb114
-rw-r--r--spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb47
-rw-r--r--spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb25
-rw-r--r--spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb41
-rw-r--r--spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb120
-rw-r--r--spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb34
-rw-r--r--spec/migrations/change_web_hook_events_default_spec.rb36
-rw-r--r--spec/migrations/cleanup_projects_with_missing_namespace_spec.rb12
-rw-r--r--spec/migrations/generate_ci_jwt_signing_key_spec.rb2
-rw-r--r--spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb (renamed from spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb)16
-rw-r--r--spec/migrations/remove_hipchat_service_records_spec.rb23
-rw-r--r--spec/migrations/schedule_update_timelogs_project_id_spec.rb33
-rw-r--r--spec/migrations/update_invalid_web_hooks_spec.rb30
13 files changed, 524 insertions, 9 deletions
diff --git a/spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb b/spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb
new file mode 100644
index 00000000000..1588cec0258
--- /dev/null
+++ b/spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb
@@ -0,0 +1,114 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210423160427_schedule_drop_invalid_vulnerabilities.rb')
+
+RSpec.describe ScheduleDropInvalidVulnerabilities, :migration do
+ 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
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let_it_be(: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
+ vulnerability_identifiers.create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'Identifier for UUIDv5')
+ end
+
+ let_it_be(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+ let_it_be(:finding) do
+ create_finding!(
+ vulnerability_id: vulnerability_with_finding.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: primary_identifier.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 migrations' do
+ migrate!
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ expect(described_class::MIGRATION).to be_scheduled_migration(vulnerability_with_finding.id, vulnerability_with_finding.id)
+ expect(described_class::MIGRATION).to be_scheduled_migration(vulnerability_without_finding.id, vulnerability_without_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')
+ 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_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)
+ users.create!(
+ name: name,
+ email: email,
+ username: name,
+ projects_limit: 0,
+ user_type: user_type,
+ confirmed_at: Time.current
+ )
+ end
+end
diff --git a/spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb b/spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb
new file mode 100644
index 00000000000..3e57ffb4729
--- /dev/null
+++ b/spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require Rails.root.join('db', 'post_migrate', '20210430134202_copy_adoption_snapshot_namespace.rb')
+
+RSpec.describe CopyAdoptionSnapshotNamespace, :migration do
+ let(:namespaces_table) { table(:namespaces) }
+ let(:segments_table) { table(:analytics_devops_adoption_segments) }
+ let(:snapshots_table) { table(:analytics_devops_adoption_snapshots) }
+
+ before do
+ namespaces_table.create!(id: 123, name: 'group1', path: 'group1')
+ namespaces_table.create!(id: 124, name: 'group2', path: 'group2')
+
+ segments_table.create!(id: 1, namespace_id: 123)
+ segments_table.create!(id: 2, namespace_id: 124)
+
+ create_snapshot(id: 1, segment_id: 1)
+ create_snapshot(id: 2, segment_id: 2)
+ create_snapshot(id: 3, segment_id: 2, namespace_id: 123)
+ end
+
+ it 'updates all snapshots without namespace set' do
+ migrate!
+
+ expect(snapshots_table.find(1).namespace_id).to eq 123
+ expect(snapshots_table.find(2).namespace_id).to eq 124
+ expect(snapshots_table.find(3).namespace_id).to eq 123
+ end
+
+ def create_snapshot(**additional_params)
+ defaults = {
+ recorded_at: Time.zone.now,
+ issue_opened: true,
+ merge_request_opened: true,
+ merge_request_approved: true,
+ runner_configured: true,
+ pipeline_succeeded: true,
+ deploy_succeeded: true,
+ security_scan_succeeded: true,
+ end_time: Time.zone.now.end_of_month
+ }
+
+ snapshots_table.create!(defaults.merge(additional_params))
+ end
+end
diff --git a/spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb b/spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb
new file mode 100644
index 00000000000..a37772db28c
--- /dev/null
+++ b/spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require Rails.root.join('db', 'post_migrate', '20210430135954_copy_adoption_segments_namespace.rb')
+
+RSpec.describe CopyAdoptionSegmentsNamespace, :migration do
+ let(:namespaces_table) { table(:namespaces) }
+ let(:segments_table) { table(:analytics_devops_adoption_segments) }
+
+ before do
+ namespaces_table.create!(id: 123, name: 'group1', path: 'group1')
+ namespaces_table.create!(id: 124, name: 'group2', path: 'group2')
+
+ segments_table.create!(id: 1, namespace_id: 123, display_namespace_id: nil)
+ segments_table.create!(id: 2, namespace_id: 124, display_namespace_id: 123)
+ end
+
+ it 'updates all segments without display namespace' do
+ migrate!
+
+ expect(segments_table.find(1).display_namespace_id).to eq 123
+ expect(segments_table.find(2).display_namespace_id).to eq 123
+ end
+end
diff --git a/spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb b/spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb
new file mode 100644
index 00000000000..6e1cc63e42a
--- /dev/null
+++ b/spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require Rails.root.join('db', 'migrate', '20210503105845_add_project_value_stream_id_to_project_stages.rb')
+
+RSpec.describe AddProjectValueStreamIdToProjectStages, schema: 20210503105022 do
+ let(:stages) { table(:analytics_cycle_analytics_project_stages) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ let(:namespace) { table(:namespaces).create!(name: 'ns1', path: 'nsq1') }
+
+ before do
+ project = projects.create!(name: 'p1', namespace_id: namespace.id)
+
+ stages.create!(
+ project_id: project.id,
+ created_at: Time.now,
+ updated_at: Time.now,
+ start_event_identifier: 1,
+ end_event_identifier: 2,
+ name: 'stage 1'
+ )
+
+ stages.create!(
+ project_id: project.id,
+ created_at: Time.now,
+ updated_at: Time.now,
+ start_event_identifier: 3,
+ end_event_identifier: 4,
+ name: 'stage 2'
+ )
+ end
+
+ it 'deletes the existing rows' do
+ migrate!
+
+ expect(stages.count).to eq(0)
+ end
+end
diff --git a/spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb b/spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb
new file mode 100644
index 00000000000..6ffaa26f923
--- /dev/null
+++ b/spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210511142748_schedule_drop_invalid_vulnerabilities2.rb')
+
+RSpec.describe ScheduleDropInvalidVulnerabilities2, :migration 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
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let_it_be(: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
+ vulnerability_identifiers.create!(
+ project_id: project.id,
+ external_type: 'uuid-v5',
+ external_id: 'uuid-v5',
+ fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ name: 'Identifier for UUIDv5')
+ end
+
+ let_it_be(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
+ let_it_be(:finding) do
+ create_finding!(
+ vulnerability_id: vulnerability_with_finding.id,
+ project_id: project.id,
+ scanner_id: scanner.id,
+ primary_identifier_id: primary_identifier.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 migrations' do
+ migrate!
+
+ expect(background_migration_jobs.count).to eq(2)
+ expect(background_migration_jobs.first.arguments).to eq([vulnerability_with_finding.id, vulnerability_with_finding.id])
+ expect(background_migration_jobs.second.arguments).to eq([vulnerability_without_finding.id, vulnerability_without_finding.id])
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, vulnerability_with_finding.id, vulnerability_with_finding.id)
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, vulnerability_without_finding.id, vulnerability_without_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')
+ 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_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)
+ users.create!(
+ name: name,
+ email: email,
+ username: name,
+ projects_limit: 0,
+ user_type: user_type,
+ confirmed_at: Time.current
+ )
+ end
+end
diff --git a/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb b/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb
new file mode 100644
index 00000000000..574020e52d5
--- /dev/null
+++ b/spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe BackfillNugetTemporaryPackagesToProcessingStatus, :migration do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:packages) { table(:packages_packages) }
+
+ before do
+ namespace = namespaces.create!(id: 123, name: 'test_namespace', path: 'test_namespace')
+ project = projects.create!(id: 111, name: 'sample_project', path: 'sample_project', namespace_id: namespace.id)
+
+ packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 4, status: 0, project_id: project.id)
+ packages.create!(name: 'foo', version: '0.1.1', package_type: 4, status: 0, project_id: project.id)
+ packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 4, status: 2, project_id: project.id)
+ packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 1, status: 2, project_id: project.id)
+ packages.create!(name: 'NuGet.Temporary.Package', version: '0.1.1', package_type: 1, status: 0, project_id: project.id)
+ end
+
+ it 'updates the applicable packages to processing status', :aggregate_failures do
+ expect(packages.where(status: 0).count).to eq(3)
+ expect(packages.where(status: 2).count).to eq(2)
+ expect(packages.where(name: 'NuGet.Temporary.Package', package_type: 4, status: 0).count).to eq(1)
+
+ migrate!
+
+ expect(packages.where(status: 0).count).to eq(2)
+ expect(packages.where(status: 2).count).to eq(3)
+ expect(packages.where(name: 'NuGet.Temporary.Package', package_type: 4, status: 0).count).to eq(0)
+ end
+end
diff --git a/spec/migrations/change_web_hook_events_default_spec.rb b/spec/migrations/change_web_hook_events_default_spec.rb
new file mode 100644
index 00000000000..3b1a65ece17
--- /dev/null
+++ b/spec/migrations/change_web_hook_events_default_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20210420012444_change_web_hook_events_default.rb')
+
+RSpec.describe ChangeWebHookEventsDefault do
+ let(:web_hooks) { table(:web_hooks) }
+ let(:projects) { table(:projects) }
+ let(:groups) { table(:namespaces) }
+
+ let(:group) { groups.create!(name: 'gitlab', path: 'gitlab-org') }
+ let(:project) { projects.create!(name: 'gitlab', path: 'gitlab', namespace_id: group.id) }
+ let(:hook) { web_hooks.create!(project_id: project.id, type: 'ProjectHook') }
+ let(:group_hook) { web_hooks.create!(group_id: group.id, type: 'GroupHook') }
+
+ before do
+ # Simulate the wrong schema
+ %w(push_events issues_events merge_requests_events tag_push_events).each do |column|
+ ActiveRecord::Base.connection.execute "ALTER TABLE web_hooks ALTER COLUMN #{column} DROP DEFAULT"
+ end
+ end
+
+ it 'sets default values' do
+ migrate!
+
+ expect(hook.push_events).to be true
+ expect(hook.issues_events).to be false
+ expect(hook.merge_requests_events).to be false
+ expect(hook.tag_push_events).to be false
+
+ expect(group_hook.push_events).to be true
+ expect(group_hook.issues_events).to be false
+ expect(group_hook.merge_requests_events).to be false
+ expect(group_hook.tag_push_events).to be false
+ end
+end
diff --git a/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb b/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb
index cef6e0f470f..a50e98faf48 100644
--- a/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb
+++ b/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb
@@ -95,12 +95,12 @@ RSpec.describe CleanupProjectsWithMissingNamespace, :migration, schema: SchemaVe
expect(
described_class::Group
.joins('INNER JOIN members ON namespaces.id = members.source_id')
- .where('namespaces.type = ?', 'Group')
- .where('members.type = ?', 'GroupMember')
- .where('members.source_type = ?', 'Namespace')
- .where('members.user_id = ?', ghost_user.id)
- .where('members.requested_at IS NULL')
- .where('members.access_level = ?', described_class::ACCESS_LEVEL_OWNER)
+ .where(namespaces: { type: 'Group' })
+ .where(members: { type: 'GroupMember' })
+ .where(members: { source_type: 'Namespace' })
+ .where(members: { user_id: ghost_user.id })
+ .where(members: { requested_at: nil })
+ .where(members: { access_level: described_class::ACCESS_LEVEL_OWNER })
.where(
described_class::Group
.arel_table[:name]
diff --git a/spec/migrations/generate_ci_jwt_signing_key_spec.rb b/spec/migrations/generate_ci_jwt_signing_key_spec.rb
index 4cfaa8701aa..249af3bcb50 100644
--- a/spec/migrations/generate_ci_jwt_signing_key_spec.rb
+++ b/spec/migrations/generate_ci_jwt_signing_key_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe GenerateCiJwtSigningKey do
attr_encrypted :ci_jwt_signing_key, {
mode: :per_attribute_iv,
- key: Rails.application.secrets.db_key_base[0..31],
+ key: Gitlab::Utils.ensure_utf8_size(Rails.application.secrets.db_key_base, bytes: 32.bytes),
algorithm: 'aes-256-gcm',
encode: true
}
diff --git a/spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb b/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb
index 11d43a36bc9..4c50aa2dd10 100644
--- a/spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb
+++ b/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb
@@ -1,11 +1,16 @@
# frozen_string_literal: true
require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20210401131948_move_container_registry_enabled_to_project_features2.rb')
+require Rails.root.join('db', 'post_migrate', '20210415155043_move_container_registry_enabled_to_project_features3.rb')
-RSpec.describe MoveContainerRegistryEnabledToProjectFeatures2, :migration do
+RSpec.describe MoveContainerRegistryEnabledToProjectFeatures3, :migration do
let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') }
+ let!(:background_jobs) do
+ table(:background_migration_jobs).create!(class_name: described_class::MIGRATION, arguments: [-1, -2])
+ table(:background_migration_jobs).create!(class_name: described_class::MIGRATION, arguments: [-3, -4])
+ end
+
let!(:projects) do
[
table(:projects).create!(namespace_id: namespace.id, name: 'project 1'),
@@ -28,11 +33,18 @@ RSpec.describe MoveContainerRegistryEnabledToProjectFeatures2, :migration do
end
it 'schedules jobs for ranges of projects' do
+ # old entries in background_migration_jobs should be deleted.
+ expect(table(:background_migration_jobs).count).to eq(2)
+ expect(table(:background_migration_jobs).first.arguments).to eq([-1, -2])
+ expect(table(:background_migration_jobs).second.arguments).to eq([-3, -4])
+
migrate!
# Since track_jobs is true, each job should have an entry in the background_migration_jobs
# table.
expect(table(:background_migration_jobs).count).to eq(2)
+ expect(table(:background_migration_jobs).first.arguments).to eq([projects[0].id, projects[2].id])
+ expect(table(:background_migration_jobs).second.arguments).to eq([projects[3].id, projects[3].id])
expect(described_class::MIGRATION)
.to be_scheduled_delayed_migration(2.minutes, projects[0].id, projects[2].id)
diff --git a/spec/migrations/remove_hipchat_service_records_spec.rb b/spec/migrations/remove_hipchat_service_records_spec.rb
new file mode 100644
index 00000000000..bc76d7933d8
--- /dev/null
+++ b/spec/migrations/remove_hipchat_service_records_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210420103955_remove_hipchat_service_records.rb')
+
+RSpec.describe RemoveHipchatServiceRecords do
+ let(:services) { table(:services) }
+
+ before do
+ services.create!(type: 'HipchatService')
+ services.create!(type: 'SomeOtherType')
+ end
+
+ it 'removes services records of type HipchatService' do
+ expect(services.count).to eq(2)
+
+ migrate!
+
+ expect(services.count).to eq(1)
+ expect(services.first.type).to eq('SomeOtherType')
+ expect(services.where(type: 'HipchatService')).to be_empty
+ end
+end
diff --git a/spec/migrations/schedule_update_timelogs_project_id_spec.rb b/spec/migrations/schedule_update_timelogs_project_id_spec.rb
new file mode 100644
index 00000000000..e2972d2fd08
--- /dev/null
+++ b/spec/migrations/schedule_update_timelogs_project_id_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20210427212034_schedule_update_timelogs_project_id.rb')
+
+RSpec.describe ScheduleUpdateTimelogsProjectId do
+ 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) { table(:timelogs).create!(issue_id: issue.id, time_spent: 60) }
+ let!(:timelog2) { table(:timelogs).create!(merge_request_id: merge_request.id, time_spent: 600) }
+ let!(:timelog3) { table(:timelogs).create!(merge_request_id: merge_request.id, time_spent: 60) }
+ let!(:timelog4) { table(:timelogs).create!(issue_id: issue.id, time_spent: 600) }
+
+ it 'correctly schedules background migrations' do
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(2.minutes, timelog1.id, timelog2.id)
+
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(4.minutes, timelog3.id, timelog4.id)
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/update_invalid_web_hooks_spec.rb b/spec/migrations/update_invalid_web_hooks_spec.rb
new file mode 100644
index 00000000000..a65f82d7082
--- /dev/null
+++ b/spec/migrations/update_invalid_web_hooks_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe UpdateInvalidWebHooks do
+ let(:web_hooks) { table(:web_hooks) }
+ let(:groups) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ before do
+ group = groups.create!(name: 'gitlab', path: 'gitlab-org')
+ project = projects.create!(namespace_id: group.id)
+
+ web_hooks.create!(group_id: group.id, type: 'GroupHook')
+ web_hooks.create!(project_id: project.id, type: 'ProjectHook')
+ web_hooks.create!(group_id: group.id, project_id: project.id, type: 'ProjectHook')
+ end
+
+ it 'clears group_id when ProjectHook type and project_id are present', :aggregate_failures do
+ expect(web_hooks.where.not(group_id: nil).where.not(project_id: nil).count).to eq(1)
+
+ migrate!
+
+ expect(web_hooks.where.not(group_id: nil).where.not(project_id: nil).count).to eq(0)
+ expect(web_hooks.where(type: 'GroupHook').count).to eq(1)
+ expect(web_hooks.where(type: 'ProjectHook').count).to eq(2)
+ end
+end