From 4555e1b21c365ed8303ffb7a3325d773c9b8bf31 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 19 May 2021 15:44:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-12-stable-ee --- ...7_schedule_drop_invalid_vulnerabilities_spec.rb | 114 ++++++++++++++++++++ ...134202_copy_adoption_snapshot_namespace_spec.rb | 47 ++++++++ ...135954_copy_adoption_segments_namespace_spec.rb | 25 +++++ ...oject_value_stream_id_to_project_stages_spec.rb | 41 +++++++ ..._schedule_drop_invalid_vulnerabilities2_spec.rb | 120 +++++++++++++++++++++ ...temporary_packages_to_processing_status_spec.rb | 34 ++++++ .../change_web_hook_events_default_spec.rb | 36 +++++++ ...cleanup_projects_with_missing_namespace_spec.rb | 12 +-- .../migrations/generate_ci_jwt_signing_key_spec.rb | 2 +- ...r_registry_enabled_to_project_features2_spec.rb | 47 -------- ...r_registry_enabled_to_project_features3_spec.rb | 59 ++++++++++ .../remove_hipchat_service_records_spec.rb | 23 ++++ .../schedule_update_timelogs_project_id_spec.rb | 33 ++++++ spec/migrations/update_invalid_web_hooks_spec.rb | 30 ++++++ 14 files changed, 569 insertions(+), 54 deletions(-) create mode 100644 spec/migrations/20210423160427_schedule_drop_invalid_vulnerabilities_spec.rb create mode 100644 spec/migrations/20210430134202_copy_adoption_snapshot_namespace_spec.rb create mode 100644 spec/migrations/20210430135954_copy_adoption_segments_namespace_spec.rb create mode 100644 spec/migrations/20210503105845_add_project_value_stream_id_to_project_stages_spec.rb create mode 100644 spec/migrations/20210511142748_schedule_drop_invalid_vulnerabilities2_spec.rb create mode 100644 spec/migrations/backfill_nuget_temporary_packages_to_processing_status_spec.rb create mode 100644 spec/migrations/change_web_hook_events_default_spec.rb delete mode 100644 spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb create mode 100644 spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb create mode 100644 spec/migrations/remove_hipchat_service_records_spec.rb create mode 100644 spec/migrations/schedule_update_timelogs_project_id_spec.rb create mode 100644 spec/migrations/update_invalid_web_hooks_spec.rb (limited to 'spec/migrations') 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_features2_spec.rb deleted file mode 100644 index 11d43a36bc9..00000000000 --- a/spec/migrations/move_container_registry_enabled_to_project_features2_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20210401131948_move_container_registry_enabled_to_project_features2.rb') - -RSpec.describe MoveContainerRegistryEnabledToProjectFeatures2, :migration do - let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') } - - let!(:projects) do - [ - table(:projects).create!(namespace_id: namespace.id, name: 'project 1'), - table(:projects).create!(namespace_id: namespace.id, name: 'project 2'), - table(:projects).create!(namespace_id: namespace.id, name: 'project 3'), - table(:projects).create!(namespace_id: namespace.id, name: 'project 4') - ] - end - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 3) - end - - around do |example| - Sidekiq::Testing.fake! do - freeze_time do - example.call - end - end - end - - it 'schedules jobs for ranges of projects' do - 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(described_class::MIGRATION) - .to be_scheduled_delayed_migration(2.minutes, projects[0].id, projects[2].id) - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(4.minutes, projects[3].id, projects[3].id) - end - - it 'schedules jobs according to the configured batch size' do - expect { migrate! }.to change { BackgroundMigrationWorker.jobs.size }.by(2) - end -end diff --git a/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb b/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb new file mode 100644 index 00000000000..4c50aa2dd10 --- /dev/null +++ b/spec/migrations/move_container_registry_enabled_to_project_features3_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20210415155043_move_container_registry_enabled_to_project_features3.rb') + +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'), + table(:projects).create!(namespace_id: namespace.id, name: 'project 2'), + table(:projects).create!(namespace_id: namespace.id, name: 'project 3'), + table(:projects).create!(namespace_id: namespace.id, name: 'project 4') + ] + end + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 3) + end + + around do |example| + Sidekiq::Testing.fake! do + freeze_time do + example.call + end + end + 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) + + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(4.minutes, projects[3].id, projects[3].id) + end + + it 'schedules jobs according to the configured batch size' do + expect { migrate! }.to change { BackgroundMigrationWorker.jobs.size }.by(2) + end +end 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 -- cgit v1.2.3