summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/background_migration
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/background_migration')
-rw-r--r--spec/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/add_primary_email_to_emails_if_user_confirmed_spec.rb49
-rw-r--r--spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_design_internal_ids_spec.rb69
-rw-r--r--spec/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_namespace_settings_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/backfill_user_namespace_spec.rb39
-rw-r--r--spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/copy_merge_request_target_project_to_merge_request_metrics_spec.rb39
-rw-r--r--spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/fix_merge_request_diff_commit_users_spec.rb316
-rw-r--r--spec/lib/gitlab/background_migration/fix_projects_without_project_feature_spec.rb75
-rw-r--r--spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb234
-rw-r--r--spec/lib/gitlab/background_migration/job_coordinator_spec.rb344
-rw-r--r--spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb327
-rw-r--r--spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb85
-rw-r--r--spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_has_vulnerabilities_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_personal_snippet_statistics_spec.rb4
-rw-r--r--spec/lib/gitlab/background_migration/populate_project_snippet_statistics_spec.rb4
-rw-r--r--spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb71
-rw-r--r--spec/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces_spec.rb254
-rw-r--r--spec/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb77
-rw-r--r--spec/lib/gitlab/background_migration/replace_blocked_by_links_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/set_default_iteration_cadences_spec.rb80
-rw-r--r--spec/lib/gitlab/background_migration/set_merge_request_diff_files_count_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/set_null_external_diff_store_to_local_value_spec.rb33
-rw-r--r--spec/lib/gitlab/background_migration/set_null_package_files_file_store_to_local_value_spec.rb33
-rw-r--r--spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb114
-rw-r--r--spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb2
50 files changed, 1095 insertions, 1214 deletions
diff --git a/spec/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule_spec.rb b/spec/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule_spec.rb
index 81b8b5dde08..0b29163671c 100644
--- a/spec/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule_spec.rb
+++ b/spec/lib/gitlab/background_migration/add_modified_to_approval_merge_request_rule_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::AddModifiedToApprovalMergeRequestRule, schema: 20200817195628 do
+RSpec.describe Gitlab::BackgroundMigration::AddModifiedToApprovalMergeRequestRule, schema: 20181228175414 do
let(:determine_if_rules_are_modified) { described_class.new }
let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab') }
diff --git a/spec/lib/gitlab/background_migration/add_primary_email_to_emails_if_user_confirmed_spec.rb b/spec/lib/gitlab/background_migration/add_primary_email_to_emails_if_user_confirmed_spec.rb
new file mode 100644
index 00000000000..b50a55a9e41
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/add_primary_email_to_emails_if_user_confirmed_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::AddPrimaryEmailToEmailsIfUserConfirmed do
+ let(:users) { table(:users) }
+ let(:emails) { table(:emails) }
+
+ let!(:unconfirmed_user) { users.create!(name: 'unconfirmed', email: 'unconfirmed@example.com', confirmed_at: nil, projects_limit: 100) }
+ let!(:confirmed_user_1) { users.create!(name: 'confirmed-1', email: 'confirmed-1@example.com', confirmed_at: 1.day.ago, projects_limit: 100) }
+ let!(:confirmed_user_2) { users.create!(name: 'confirmed-2', email: 'confirmed-2@example.com', confirmed_at: 1.day.ago, projects_limit: 100) }
+ let!(:email) { emails.create!(user_id: confirmed_user_1.id, email: 'confirmed-1@example.com', confirmed_at: 1.day.ago) }
+
+ let(:perform) { described_class.new.perform(users.first.id, users.last.id) }
+
+ it 'adds the primary email of confirmed users to Emails, unless already added', :aggregate_failures do
+ expect(emails.where(email: [unconfirmed_user.email, confirmed_user_2.email])).to be_empty
+
+ expect { perform }.not_to raise_error
+
+ expect(emails.where(email: unconfirmed_user.email).count).to eq(0)
+ expect(emails.where(email: confirmed_user_1.email, user_id: confirmed_user_1.id).count).to eq(1)
+ expect(emails.where(email: confirmed_user_2.email, user_id: confirmed_user_2.id).count).to eq(1)
+
+ email_2 = emails.find_by(email: confirmed_user_2.email, user_id: confirmed_user_2.id)
+ expect(email_2.confirmed_at).to eq(confirmed_user_2.reload.confirmed_at)
+ end
+
+ it 'sets timestamps on the created Emails' do
+ perform
+
+ email_2 = emails.find_by(email: confirmed_user_2.email, user_id: confirmed_user_2.id)
+
+ expect(email_2.created_at).not_to be_nil
+ expect(email_2.updated_at).not_to be_nil
+ end
+
+ context 'when a range of IDs is specified' do
+ let!(:confirmed_user_3) { users.create!(name: 'confirmed-3', email: 'confirmed-3@example.com', confirmed_at: 1.hour.ago, projects_limit: 100) }
+ let!(:confirmed_user_4) { users.create!(name: 'confirmed-4', email: 'confirmed-4@example.com', confirmed_at: 1.hour.ago, projects_limit: 100) }
+
+ it 'only acts on the specified range of IDs', :aggregate_failures do
+ expect do
+ described_class.new.perform(confirmed_user_2.id, confirmed_user_3.id)
+ end.to change { Email.count }.by(2)
+ expect(emails.where(email: confirmed_user_4.email).count).to eq(0)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb b/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb
index 49fa7b41916..6ab1e3ecd70 100644
--- a/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_artifact_expiry_date_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillArtifactExpiryDate, :migration, schema: 20201111152859 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillArtifactExpiryDate, :migration, schema: 20181228175414 do
subject(:perform) { migration.perform(1, 99) }
let(:migration) { described_class.new }
diff --git a/spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb b/spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb
index 54c14e7a4b8..1404ada3647 100644
--- a/spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillDeploymentClustersFromDeployments, :migration, schema: 20200227140242 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillDeploymentClustersFromDeployments, :migration, schema: 20181228175414 do
subject { described_class.new }
describe '#perform' do
diff --git a/spec/lib/gitlab/background_migration/backfill_design_internal_ids_spec.rb b/spec/lib/gitlab/background_migration/backfill_design_internal_ids_spec.rb
deleted file mode 100644
index 4bf59a02a31..00000000000
--- a/spec/lib/gitlab/background_migration/backfill_design_internal_ids_spec.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::BackfillDesignInternalIds, :migration, schema: 20201030203854 do
- subject { described_class.new(designs) }
-
- let_it_be(:namespaces) { table(:namespaces) }
- let_it_be(:projects) { table(:projects) }
- let_it_be(:designs) { table(:design_management_designs) }
-
- 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) }
-
- def create_design!(proj = project)
- designs.create!(project_id: proj.id, filename: generate(:filename))
- end
-
- def migrate!
- relation = designs.where(project_id: [project.id, project_2.id]).select(:project_id).distinct
-
- subject.perform(relation)
- end
-
- it 'backfills the iid for designs' do
- 3.times { create_design! }
-
- expect do
- migrate!
- end.to change { designs.pluck(:iid) }.from(contain_exactly(nil, nil, nil)).to(contain_exactly(1, 2, 3))
- end
-
- it 'scopes IIDs and handles range and starting-point correctly' do
- create_design!.update!(iid: 10)
- create_design!.update!(iid: 12)
- create_design!(project_2).update!(iid: 7)
- project_3 = projects.create!(namespace_id: namespace.id)
-
- 2.times { create_design! }
- 2.times { create_design!(project_2) }
- 2.times { create_design!(project_3) }
-
- migrate!
-
- expect(designs.where(project_id: project.id).pluck(:iid)).to contain_exactly(10, 12, 13, 14)
- expect(designs.where(project_id: project_2.id).pluck(:iid)).to contain_exactly(7, 8, 9)
- expect(designs.where(project_id: project_3.id).pluck(:iid)).to contain_exactly(nil, nil)
- end
-
- it 'updates the internal ID records' do
- design = create_design!
- 2.times { create_design! }
- design.update!(iid: 10)
- scope = { project_id: project.id }
- usage = :design_management_designs
- init = ->(_d, _s) { 0 }
-
- ::InternalId.track_greatest(design, scope, usage, 10, init)
-
- migrate!
-
- next_iid = ::InternalId.generate_next(design, scope, usage, init)
-
- expect(designs.pluck(:iid)).to contain_exactly(10, 11, 12)
- expect(design.reload.iid).to eq(10)
- expect(next_iid).to eq(13)
- end
-end
diff --git a/spec/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests_spec.rb b/spec/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests_spec.rb
index 550bdc484c9..9194525e713 100644
--- a/spec/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_environment_id_deployment_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillEnvironmentIdDeploymentMergeRequests, schema: 20200312134637 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillEnvironmentIdDeploymentMergeRequests, schema: 20181228175414 do
let(:environments) { table(:environments) }
let(:merge_requests) { table(:merge_requests) }
let(:deployments) { table(:deployments) }
diff --git a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb
index 58864aac084..446d62bbd2a 100644
--- a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillJiraTrackerDeploymentType2, :migration, schema: 20201028182809 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillJiraTrackerDeploymentType2, :migration, schema: 20181228175414 do
let_it_be(:jira_integration_temp) { described_class::JiraServiceTemp }
let_it_be(:jira_tracker_data_temp) { described_class::JiraTrackerDataTemp }
let_it_be(:atlassian_host) { 'https://api.atlassian.net' }
diff --git a/spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb b/spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb
index c2daa35703d..d33f52514da 100644
--- a/spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillMergeRequestCleanupSchedules, schema: 20201103110018 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillMergeRequestCleanupSchedules, schema: 20181228175414 do
let(:merge_requests) { table(:merge_requests) }
let(:cleanup_schedules) { table(:merge_request_cleanup_schedules) }
let(:metrics) { table(:merge_request_metrics) }
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_settings_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_settings_spec.rb
index 43e76a2952e..0f8adca2ca4 100644
--- a/spec/lib/gitlab/background_migration/backfill_namespace_settings_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceSettings, schema: 20200703125016 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceSettings, schema: 20181228175414 do
let(:namespaces) { table(:namespaces) }
let(:namespace_settings) { table(:namespace_settings) }
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
diff --git a/spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb
index 48c5674822a..e6b0db2ab73 100644
--- a/spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillProjectSettings, schema: 20200114113341 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillProjectSettings, schema: 20181228175414 do
let(:projects) { table(:projects) }
let(:project_settings) { table(:project_settings) }
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
diff --git a/spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb b/spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb
index 9ce6a3227b5..3468df3dccd 100644
--- a/spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::BackfillPushRulesIdInProjects, :migration, schema: 2020_03_25_162730 do
+RSpec.describe Gitlab::BackgroundMigration::BackfillPushRulesIdInProjects, :migration, schema: 20181228175414 do
let(:push_rules) { table(:push_rules) }
let(:projects) { table(:projects) }
let(:project_settings) { table(:project_settings) }
diff --git a/spec/lib/gitlab/background_migration/backfill_user_namespace_spec.rb b/spec/lib/gitlab/background_migration/backfill_user_namespace_spec.rb
new file mode 100644
index 00000000000..395248b786d
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_user_namespace_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillUserNamespace, :migration, schema: 20210930211936 do
+ let(:migration) { described_class.new }
+ let(:namespaces_table) { table(:namespaces) }
+
+ let(:table_name) { 'namespaces' }
+ let(:batch_column) { :id }
+ let(:sub_batch_size) { 100 }
+ let(:pause_ms) { 0 }
+
+ subject(:perform_migration) { migration.perform(1, 10, table_name, batch_column, sub_batch_size, pause_ms) }
+
+ before do
+ namespaces_table.create!(id: 1, name: 'test1', path: 'test1', type: nil)
+ namespaces_table.create!(id: 2, name: 'test2', path: 'test2', type: 'User')
+ namespaces_table.create!(id: 3, name: 'test3', path: 'test3', type: 'Group')
+ namespaces_table.create!(id: 4, name: 'test4', path: 'test4', type: nil)
+ namespaces_table.create!(id: 11, name: 'test11', path: 'test11', type: nil)
+ end
+
+ it 'backfills `type` for the selected records', :aggregate_failures do
+ queries = ActiveRecord::QueryRecorder.new do
+ perform_migration
+ end
+
+ expect(queries.count).to eq(3)
+ expect(namespaces_table.where(type: 'User').count).to eq 3
+ expect(namespaces_table.where(type: 'User').pluck(:id)).to match_array([1, 2, 4])
+ end
+
+ it 'tracks timings of queries' do
+ expect(migration.batch_metrics.timings).to be_empty
+
+ expect { perform_migration }.to change { migration.batch_metrics.timings }
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb b/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb
index 3e378db04d4..d4fc24d0559 100644
--- a/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb
+++ b/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJob do
- let(:table_name) { :copy_primary_key_test }
+ let(:table_name) { :_test_copy_primary_key_test }
let(:test_table) { table(table_name) }
let(:sub_batch_size) { 1000 }
let(:pause_ms) { 0 }
diff --git a/spec/lib/gitlab/background_migration/copy_merge_request_target_project_to_merge_request_metrics_spec.rb b/spec/lib/gitlab/background_migration/copy_merge_request_target_project_to_merge_request_metrics_spec.rb
deleted file mode 100644
index 71bb794d539..00000000000
--- a/spec/lib/gitlab/background_migration/copy_merge_request_target_project_to_merge_request_metrics_spec.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::CopyMergeRequestTargetProjectToMergeRequestMetrics, :migration, schema: 20200723125205 do
- let(:migration) { described_class.new }
-
- let_it_be(:namespaces) { table(:namespaces) }
- let_it_be(:projects) { table(:projects) }
- let_it_be(:merge_requests) { table(:merge_requests) }
- let_it_be(:metrics) { table(:merge_request_metrics) }
-
- let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace') }
- let!(:project_1) { projects.create!(namespace_id: namespace.id) }
- let!(:project_2) { projects.create!(namespace_id: namespace.id) }
- let!(:merge_request_to_migrate_1) { merge_requests.create!(source_branch: 'a', target_branch: 'b', target_project_id: project_1.id) }
- let!(:merge_request_to_migrate_2) { merge_requests.create!(source_branch: 'c', target_branch: 'd', target_project_id: project_2.id) }
- let!(:merge_request_without_metrics) { merge_requests.create!(source_branch: 'e', target_branch: 'f', target_project_id: project_2.id) }
-
- let!(:metrics_1) { metrics.create!(merge_request_id: merge_request_to_migrate_1.id) }
- let!(:metrics_2) { metrics.create!(merge_request_id: merge_request_to_migrate_2.id) }
-
- let(:merge_request_ids) { [merge_request_to_migrate_1.id, merge_request_to_migrate_2.id, merge_request_without_metrics.id] }
-
- subject { migration.perform(merge_request_ids.min, merge_request_ids.max) }
-
- it 'copies `target_project_id` to the associated `merge_request_metrics` record' do
- subject
-
- expect(metrics_1.reload.target_project_id).to eq(project_1.id)
- expect(metrics_2.reload.target_project_id).to eq(project_2.id)
- end
-
- it 'does not create metrics record when it is missing' do
- subject
-
- expect(metrics.find_by_merge_request_id(merge_request_without_metrics.id)).to be_nil
- end
-end
diff --git a/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
index c4beb719e1e..b83dc6fff7a 100644
--- a/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
+++ b/spec/lib/gitlab/background_migration/drop_invalid_vulnerabilities_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: 20201110110454 do
+RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: 20181228175414 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) }
diff --git a/spec/lib/gitlab/background_migration/fix_merge_request_diff_commit_users_spec.rb b/spec/lib/gitlab/background_migration/fix_merge_request_diff_commit_users_spec.rb
new file mode 100644
index 00000000000..c343ee438b8
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/fix_merge_request_diff_commit_users_spec.rb
@@ -0,0 +1,316 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# The underlying migration relies on the global models (e.g. Project). This
+# means we also need to use FactoryBot factories to ensure everything is
+# operating using the same types. If we use `table()` and similar methods we
+# would have to duplicate a lot of logic just for these tests.
+#
+# rubocop: disable RSpec/FactoriesInMigrationSpecs
+RSpec.describe Gitlab::BackgroundMigration::FixMergeRequestDiffCommitUsers do
+ let(:migration) { described_class.new }
+
+ describe '#perform' do
+ context 'when the project exists' do
+ it 'processes the project' do
+ project = create(:project)
+
+ expect(migration).to receive(:process).with(project)
+ expect(migration).to receive(:schedule_next_job)
+
+ migration.perform(project.id)
+ end
+
+ it 'marks the background job as finished' do
+ project = create(:project)
+
+ Gitlab::Database::BackgroundMigrationJob.create!(
+ class_name: 'FixMergeRequestDiffCommitUsers',
+ arguments: [project.id]
+ )
+
+ migration.perform(project.id)
+
+ job = Gitlab::Database::BackgroundMigrationJob
+ .find_by(class_name: 'FixMergeRequestDiffCommitUsers')
+
+ expect(job.status).to eq('succeeded')
+ end
+ end
+
+ context 'when the project does not exist' do
+ it 'does nothing' do
+ expect(migration).not_to receive(:process)
+ expect(migration).to receive(:schedule_next_job)
+
+ migration.perform(-1)
+ end
+ end
+ end
+
+ describe '#process' do
+ it 'processes the merge requests of the project' do
+ project = create(:project, :repository)
+ commit = project.commit
+ mr = create(
+ :merge_request_with_diffs,
+ source_project: project,
+ target_project: project
+ )
+
+ diff = mr.merge_request_diffs.first
+
+ create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: commit.sha,
+ relative_order: 9000
+ )
+
+ migration.process(project)
+
+ updated = diff
+ .merge_request_diff_commits
+ .find_by(sha: commit.sha, relative_order: 9000)
+
+ expect(updated.commit_author_id).not_to be_nil
+ expect(updated.committer_id).not_to be_nil
+ end
+ end
+
+ describe '#update_commit' do
+ let(:project) { create(:project, :repository) }
+ let(:mr) do
+ create(
+ :merge_request_with_diffs,
+ source_project: project,
+ target_project: project
+ )
+ end
+
+ let(:diff) { mr.merge_request_diffs.first }
+ let(:commit) { project.commit }
+
+ def update_row(migration, project, diff, row)
+ migration.update_commit(project, row)
+
+ diff
+ .merge_request_diff_commits
+ .find_by(sha: row.sha, relative_order: row.relative_order)
+ end
+
+ it 'populates missing commit authors' do
+ commit_row = create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: commit.sha,
+ relative_order: 9000
+ )
+
+ updated = update_row(migration, project, diff, commit_row)
+
+ expect(updated.commit_author.name).to eq(commit.to_hash[:author_name])
+ expect(updated.commit_author.email).to eq(commit.to_hash[:author_email])
+ end
+
+ it 'populates missing committers' do
+ commit_row = create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: commit.sha,
+ relative_order: 9000
+ )
+
+ updated = update_row(migration, project, diff, commit_row)
+
+ expect(updated.committer.name).to eq(commit.to_hash[:committer_name])
+ expect(updated.committer.email).to eq(commit.to_hash[:committer_email])
+ end
+
+ it 'leaves existing commit authors as-is' do
+ user = create(:merge_request_diff_commit_user)
+ commit_row = create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: commit.sha,
+ relative_order: 9000,
+ commit_author: user
+ )
+
+ updated = update_row(migration, project, diff, commit_row)
+
+ expect(updated.commit_author).to eq(user)
+ end
+
+ it 'leaves existing committers as-is' do
+ user = create(:merge_request_diff_commit_user)
+ commit_row = create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: commit.sha,
+ relative_order: 9000,
+ committer: user
+ )
+
+ updated = update_row(migration, project, diff, commit_row)
+
+ expect(updated.committer).to eq(user)
+ end
+
+ it 'does nothing when both the author and committer are present' do
+ user = create(:merge_request_diff_commit_user)
+ commit_row = create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: commit.sha,
+ relative_order: 9000,
+ committer: user,
+ commit_author: user
+ )
+
+ recorder = ActiveRecord::QueryRecorder.new do
+ migration.update_commit(project, commit_row)
+ end
+
+ expect(recorder.count).to be_zero
+ end
+
+ it 'does nothing if the commit does not exist in Git' do
+ user = create(:merge_request_diff_commit_user)
+ commit_row = create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: 'kittens',
+ relative_order: 9000,
+ committer: user,
+ commit_author: user
+ )
+
+ recorder = ActiveRecord::QueryRecorder.new do
+ migration.update_commit(project, commit_row)
+ end
+
+ expect(recorder.count).to be_zero
+ end
+
+ it 'does nothing when the committer/author are missing in the Git commit' do
+ user = create(:merge_request_diff_commit_user)
+ commit_row = create(
+ :merge_request_diff_commit,
+ merge_request_diff: diff,
+ sha: commit.sha,
+ relative_order: 9000,
+ committer: user,
+ commit_author: user
+ )
+
+ allow(migration).to receive(:find_or_create_user).and_return(nil)
+
+ recorder = ActiveRecord::QueryRecorder.new do
+ migration.update_commit(project, commit_row)
+ end
+
+ expect(recorder.count).to be_zero
+ end
+ end
+
+ describe '#schedule_next_job' do
+ it 'schedules the next background migration' do
+ Gitlab::Database::BackgroundMigrationJob
+ .create!(class_name: 'FixMergeRequestDiffCommitUsers', arguments: [42])
+
+ expect(BackgroundMigrationWorker)
+ .to receive(:perform_in)
+ .with(2.minutes, 'FixMergeRequestDiffCommitUsers', [42])
+
+ migration.schedule_next_job
+ end
+
+ it 'does nothing when there are no jobs' do
+ expect(BackgroundMigrationWorker)
+ .not_to receive(:perform_in)
+
+ migration.schedule_next_job
+ end
+ end
+
+ describe '#find_commit' do
+ let(:project) { create(:project, :repository) }
+
+ it 'finds a commit using Git' do
+ commit = project.commit
+ found = migration.find_commit(project, commit.sha)
+
+ expect(found).to eq(commit.to_hash)
+ end
+
+ it 'caches the results' do
+ commit = project.commit
+
+ migration.find_commit(project, commit.sha)
+
+ expect { migration.find_commit(project, commit.sha) }
+ .not_to change { Gitlab::GitalyClient.get_request_count }
+ end
+
+ it 'returns an empty hash if the commit does not exist' do
+ expect(migration.find_commit(project, 'kittens')).to eq({})
+ end
+ end
+
+ describe '#find_or_create_user' do
+ let(:project) { create(:project, :repository) }
+
+ it 'creates missing users' do
+ commit = project.commit.to_hash
+ id = migration.find_or_create_user(commit, :author_name, :author_email)
+
+ expect(MergeRequest::DiffCommitUser.count).to eq(1)
+
+ created = MergeRequest::DiffCommitUser.first
+
+ expect(created.name).to eq(commit[:author_name])
+ expect(created.email).to eq(commit[:author_email])
+ expect(created.id).to eq(id)
+ end
+
+ it 'returns users that already exist' do
+ commit = project.commit.to_hash
+ user1 = migration.find_or_create_user(commit, :author_name, :author_email)
+ user2 = migration.find_or_create_user(commit, :author_name, :author_email)
+
+ expect(user1).to eq(user2)
+ end
+
+ it 'caches the results' do
+ commit = project.commit.to_hash
+
+ migration.find_or_create_user(commit, :author_name, :author_email)
+
+ recorder = ActiveRecord::QueryRecorder.new do
+ migration.find_or_create_user(commit, :author_name, :author_email)
+ end
+
+ expect(recorder.count).to be_zero
+ end
+
+ it 'returns nil if the commit details are missing' do
+ id = migration.find_or_create_user({}, :author_name, :author_email)
+
+ expect(id).to be_nil
+ end
+ end
+
+ describe '#matches_row' do
+ it 'returns the query matches for the composite primary key' do
+ row = double(:commit, merge_request_diff_id: 4, relative_order: 5)
+ arel = migration.matches_row(row)
+
+ expect(arel.to_sql).to eq(
+ '("merge_request_diff_commits"."merge_request_diff_id", "merge_request_diff_commits"."relative_order") = (4, 5)'
+ )
+ end
+ end
+end
+# rubocop: enable RSpec/FactoriesInMigrationSpecs
diff --git a/spec/lib/gitlab/background_migration/fix_projects_without_project_feature_spec.rb b/spec/lib/gitlab/background_migration/fix_projects_without_project_feature_spec.rb
deleted file mode 100644
index d503824041b..00000000000
--- a/spec/lib/gitlab/background_migration/fix_projects_without_project_feature_spec.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::FixProjectsWithoutProjectFeature, schema: 2020_01_27_111840 do
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:project_features) { table(:project_features) }
-
- let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
-
- let!(:project) { projects.create!(namespace_id: namespace.id) }
- let(:private_project_without_feature) { projects.create!(namespace_id: namespace.id, visibility_level: 0) }
- let(:public_project_without_feature) { projects.create!(namespace_id: namespace.id, visibility_level: 20) }
- let!(:projects_without_feature) { [private_project_without_feature, public_project_without_feature] }
-
- before do
- project_features.create!({ project_id: project.id, pages_access_level: 20 })
- end
-
- subject { described_class.new.perform(Project.minimum(:id), Project.maximum(:id)) }
-
- def project_feature_records
- project_features.order(:project_id).pluck(:project_id)
- end
-
- def features(project)
- project_features.find_by(project_id: project.id)&.attributes
- end
-
- it 'creates a ProjectFeature for projects without it' do
- expect { subject }.to change { project_feature_records }.from([project.id]).to([project.id, *projects_without_feature.map(&:id)])
- end
-
- it 'creates ProjectFeature records with default values for a public project' do
- subject
-
- expect(features(public_project_without_feature)).to include(
- {
- "merge_requests_access_level" => 20,
- "issues_access_level" => 20,
- "wiki_access_level" => 20,
- "snippets_access_level" => 20,
- "builds_access_level" => 20,
- "repository_access_level" => 20,
- "pages_access_level" => 20,
- "forking_access_level" => 20
- }
- )
- end
-
- it 'creates ProjectFeature records with default values for a private project' do
- subject
-
- expect(features(private_project_without_feature)).to include("pages_access_level" => 10)
- end
-
- context 'when access control to pages is forced' do
- before do
- allow(::Gitlab::Pages).to receive(:access_control_is_forced?).and_return(true)
- end
-
- it 'creates ProjectFeature records with default values for a public project' do
- subject
-
- expect(features(public_project_without_feature)).to include("pages_access_level" => 10)
- end
- end
-
- it 'sets created_at/updated_at timestamps' do
- subject
-
- expect(project_features.where('created_at IS NULL OR updated_at IS NULL')).to be_empty
- end
-end
diff --git a/spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb b/spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb
deleted file mode 100644
index 9a497a9e01a..00000000000
--- a/spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb
+++ /dev/null
@@ -1,234 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::FixProjectsWithoutPrometheusService, :migration, schema: 2020_02_20_115023 do
- def service_params_for(project_id, params = {})
- {
- project_id: project_id,
- active: false,
- properties: '{}',
- type: 'PrometheusService',
- template: false,
- push_events: true,
- issues_events: true,
- merge_requests_events: true,
- tag_push_events: true,
- note_events: true,
- category: 'monitoring',
- default: false,
- wiki_page_events: true,
- pipeline_events: true,
- confidential_issues_events: true,
- commit_events: true,
- job_events: true,
- confidential_note_events: true,
- deployment_events: false
- }.merge(params)
- end
-
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:services) { table(:services) }
- let(:clusters) { table(:clusters) }
- let(:cluster_groups) { table(:cluster_groups) }
- let(:clusters_applications_prometheus) { table(:clusters_applications_prometheus) }
- let(:namespace) { namespaces.create!(name: 'user', path: 'user') }
- let(:project) { projects.create!(namespace_id: namespace.id) }
-
- let(:application_statuses) do
- {
- errored: -1,
- installed: 3,
- updated: 5
- }
- end
-
- let(:cluster_types) do
- {
- instance_type: 1,
- group_type: 2,
- project_type: 3
- }
- end
-
- let(:columns) do
- %w(project_id active properties type template push_events
- issues_events merge_requests_events tag_push_events
- note_events category default wiki_page_events pipeline_events
- confidential_issues_events commit_events job_events
- confidential_note_events deployment_events)
- end
-
- describe '#perform' do
- shared_examples 'fix services entries state' do
- it 'is idempotent' do
- expect { subject.perform(project.id, project.id + 1) }.to change { services.order(:id).map { |row| row.attributes } }
-
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
-
- context 'non prometheus services' do
- it 'does not change them' do
- other_type = 'SomeOtherService'
- services.create!(service_params_for(project.id, active: true, type: other_type))
-
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.where(type: other_type).order(:id).map { |row| row.attributes } }
- end
- end
-
- context 'prometheus integration services do not exist' do
- it 'creates missing services entries', :aggregate_failures do
- expect { subject.perform(project.id, project.id + 1) }.to change { services.count }.by(1)
- expect([service_params_for(project.id, active: true)]).to eq services.order(:id).map { |row| row.attributes.slice(*columns).symbolize_keys }
- end
-
- context 'template is present for prometheus services' do
- it 'creates missing services entries', :aggregate_failures do
- services.create!(service_params_for(nil, template: true, properties: { 'from_template' => true }.to_json))
-
- expect { subject.perform(project.id, project.id + 1) }.to change { services.count }.by(1)
- updated_rows = services.where(template: false).order(:id).map { |row| row.attributes.slice(*columns).symbolize_keys }
- expect([service_params_for(project.id, active: true, properties: { 'from_template' => true }.to_json)]).to eq updated_rows
- end
- end
- end
-
- context 'prometheus integration services exist' do
- context 'in active state' do
- it 'does not change them' do
- services.create!(service_params_for(project.id, active: true))
-
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
- end
-
- context 'not in active state' do
- it 'sets active attribute to true' do
- service = services.create!(service_params_for(project.id, active: false))
-
- expect { subject.perform(project.id, project.id + 1) }.to change { service.reload.active? }.from(false).to(true)
- end
-
- context 'prometheus services are configured manually ' do
- it 'does not change them' do
- properties = '{"api_url":"http://test.dev","manual_configuration":"1"}'
- services.create!(service_params_for(project.id, properties: properties, active: false))
-
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
- end
- end
- end
- end
-
- context 'k8s cluster shared on instance level' do
- let(:cluster) { clusters.create!(name: 'cluster', cluster_type: cluster_types[:instance_type]) }
-
- context 'with installed prometheus application' do
- before do
- clusters_applications_prometheus.create!(cluster_id: cluster.id, status: application_statuses[:installed], version: '123')
- end
-
- it_behaves_like 'fix services entries state'
- end
-
- context 'with updated prometheus application' do
- before do
- clusters_applications_prometheus.create!(cluster_id: cluster.id, status: application_statuses[:updated], version: '123')
- end
-
- it_behaves_like 'fix services entries state'
- end
-
- context 'with errored prometheus application' do
- before do
- clusters_applications_prometheus.create!(cluster_id: cluster.id, status: application_statuses[:errored], version: '123')
- end
-
- it 'does not change services entries' do
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
- end
- end
-
- context 'k8s cluster shared on group level' do
- let(:cluster) { clusters.create!(name: 'cluster', cluster_type: cluster_types[:group_type]) }
-
- before do
- cluster_groups.create!(cluster_id: cluster.id, group_id: project.namespace_id)
- end
-
- context 'with installed prometheus application' do
- before do
- clusters_applications_prometheus.create!(cluster_id: cluster.id, status: application_statuses[:installed], version: '123')
- end
-
- it_behaves_like 'fix services entries state'
-
- context 'second k8s cluster without application available' do
- let(:namespace_2) { namespaces.create!(name: 'namespace2', path: 'namespace2') }
- let(:project_2) { projects.create!(namespace_id: namespace_2.id) }
-
- before do
- cluster_2 = clusters.create!(name: 'cluster2', cluster_type: cluster_types[:group_type])
- cluster_groups.create!(cluster_id: cluster_2.id, group_id: project_2.namespace_id)
- end
-
- it 'changed only affected services entries' do
- expect { subject.perform(project.id, project_2.id + 1) }.to change { services.count }.by(1)
- expect([service_params_for(project.id, active: true)]).to eq services.order(:id).map { |row| row.attributes.slice(*columns).symbolize_keys }
- end
- end
- end
-
- context 'with updated prometheus application' do
- before do
- clusters_applications_prometheus.create!(cluster_id: cluster.id, status: application_statuses[:updated], version: '123')
- end
-
- it_behaves_like 'fix services entries state'
- end
-
- context 'with errored prometheus application' do
- before do
- clusters_applications_prometheus.create!(cluster_id: cluster.id, status: application_statuses[:errored], version: '123')
- end
-
- it 'does not change services entries' do
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
- end
-
- context 'with missing prometheus application' do
- it 'does not change services entries' do
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
-
- context 'with inactive service' do
- it 'does not change services entries' do
- services.create!(service_params_for(project.id))
-
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
- end
- end
- end
-
- context 'k8s cluster for single project' do
- let(:cluster) { clusters.create!(name: 'cluster', cluster_type: cluster_types[:project_type]) }
- let(:cluster_projects) { table(:cluster_projects) }
-
- context 'with installed prometheus application' do
- before do
- cluster_projects.create!(cluster_id: cluster.id, project_id: project.id)
- clusters_applications_prometheus.create!(cluster_id: cluster.id, status: application_statuses[:installed], version: '123')
- end
-
- it 'does not change services entries' do
- expect { subject.perform(project.id, project.id + 1) }.not_to change { services.order(:id).map { |row| row.attributes } }
- end
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/job_coordinator_spec.rb b/spec/lib/gitlab/background_migration/job_coordinator_spec.rb
new file mode 100644
index 00000000000..a0543ca9958
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/job_coordinator_spec.rb
@@ -0,0 +1,344 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::JobCoordinator do
+ let(:database) { :main }
+ let(:worker_class) { BackgroundMigrationWorker }
+ let(:coordinator) { described_class.new(database, worker_class) }
+
+ describe '.for_database' do
+ it 'returns an executor with the correct worker class and database' do
+ coordinator = described_class.for_database(database)
+
+ expect(coordinator.database).to eq(database)
+ expect(coordinator.worker_class).to eq(worker_class)
+ end
+
+ context 'when passed in as a string' do
+ it 'retruns an executor with the correct worker class and database' do
+ coordinator = described_class.for_database(database.to_s)
+
+ expect(coordinator.database).to eq(database)
+ expect(coordinator.worker_class).to eq(worker_class)
+ end
+ end
+
+ context 'when an invalid value is given' do
+ it 'raises an error' do
+ expect do
+ described_class.for_database('notvalid')
+ end.to raise_error(ArgumentError, "database must be one of [main], got 'notvalid'")
+ end
+ end
+ end
+
+ describe '#queue' do
+ it 'returns background migration worker queue' do
+ expect(coordinator.queue).to eq(worker_class.sidekiq_options['queue'])
+ end
+ end
+
+ describe '#with_shared_connection' do
+ it 'yields to the block after properly configuring SharedModel' do
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection)
+ .with(ActiveRecord::Base.connection).and_yield
+
+ expect { |b| coordinator.with_shared_connection(&b) }.to yield_with_no_args
+ end
+ end
+
+ describe '#steal' do
+ context 'when there are enqueued jobs present' do
+ let(:queue) do
+ [
+ double(args: ['Foo', [10, 20]], klass: worker_class.name),
+ double(args: ['Bar', [20, 30]], klass: worker_class.name),
+ double(args: ['Foo', [20, 30]], klass: 'MergeWorker')
+ ]
+ end
+
+ before do
+ allow(Sidekiq::Queue).to receive(:new)
+ .with(coordinator.queue)
+ .and_return(queue)
+ end
+
+ context 'when queue contains unprocessed jobs' do
+ it 'steals jobs from a queue' do
+ expect(queue[0]).to receive(:delete).and_return(true)
+
+ expect(coordinator).to receive(:perform).with('Foo', [10, 20])
+
+ coordinator.steal('Foo')
+ end
+
+ it 'sets up the shared connection while stealing jobs' do
+ connection = double('connection')
+ allow(coordinator).to receive(:connection).and_return(connection)
+
+ expect(coordinator).to receive(:with_shared_connection).and_call_original
+
+ expect(queue[0]).to receive(:delete).and_return(true)
+
+ expect(coordinator).to receive(:perform).with('Foo', [10, 20]) do
+ expect(Gitlab::Database::SharedModel.connection).to be(connection)
+ end
+
+ coordinator.steal('Foo') do
+ expect(Gitlab::Database::SharedModel.connection).to be(connection)
+
+ true # the job is only performed if the block returns true
+ end
+ end
+
+ it 'does not steal job that has already been taken' do
+ expect(queue[0]).to receive(:delete).and_return(false)
+
+ expect(coordinator).not_to receive(:perform)
+
+ coordinator.steal('Foo')
+ end
+
+ it 'does not steal jobs for a different migration' do
+ expect(coordinator).not_to receive(:perform)
+
+ expect(queue[0]).not_to receive(:delete)
+
+ coordinator.steal('Baz')
+ end
+
+ context 'when a custom predicate is given' do
+ it 'steals jobs that match the predicate' do
+ expect(queue[0]).to receive(:delete).and_return(true)
+
+ expect(coordinator).to receive(:perform).with('Foo', [10, 20])
+
+ coordinator.steal('Foo') { |job| job.args.second.first == 10 && job.args.second.second == 20 }
+ end
+
+ it 'does not steal jobs that do not match the predicate' do
+ expect(described_class).not_to receive(:perform)
+
+ expect(queue[0]).not_to receive(:delete)
+
+ coordinator.steal('Foo') { |(arg1, _)| arg1 == 5 }
+ end
+ end
+ end
+
+ context 'when one of the jobs raises an error' do
+ let(:migration) { spy(:migration) }
+
+ let(:queue) do
+ [double(args: ['Foo', [10, 20]], klass: worker_class.name),
+ double(args: ['Foo', [20, 30]], klass: worker_class.name)]
+ end
+
+ before do
+ stub_const('Gitlab::BackgroundMigration::Foo', migration)
+
+ allow(queue[0]).to receive(:delete).and_return(true)
+ allow(queue[1]).to receive(:delete).and_return(true)
+ end
+
+ it 'enqueues the migration again and re-raises the error' do
+ allow(migration).to receive(:perform).with(10, 20).and_raise(Exception, 'Migration error').once
+
+ expect(worker_class).to receive(:perform_async).with('Foo', [10, 20]).once
+
+ expect { coordinator.steal('Foo') }.to raise_error(Exception)
+ end
+ end
+ end
+
+ context 'when there are scheduled jobs present', :redis do
+ it 'steals all jobs from the scheduled sets' do
+ Sidekiq::Testing.disable! do
+ worker_class.perform_in(10.minutes, 'Object')
+
+ expect(Sidekiq::ScheduledSet.new).to be_one
+ expect(coordinator).to receive(:perform).with('Object', any_args)
+
+ coordinator.steal('Object')
+
+ expect(Sidekiq::ScheduledSet.new).to be_none
+ end
+ end
+ end
+
+ context 'when there are enqueued and scheduled jobs present', :redis do
+ it 'steals from the scheduled sets queue first' do
+ Sidekiq::Testing.disable! do
+ expect(coordinator).to receive(:perform).with('Object', [1]).ordered
+ expect(coordinator).to receive(:perform).with('Object', [2]).ordered
+
+ worker_class.perform_async('Object', [2])
+ worker_class.perform_in(10.minutes, 'Object', [1])
+
+ coordinator.steal('Object')
+ end
+ end
+ end
+
+ context 'when retry_dead_jobs is true', :redis do
+ let(:retry_queue) do
+ [double(args: ['Object', [3]], klass: worker_class.name, delete: true)]
+ end
+
+ let(:dead_queue) do
+ [double(args: ['Object', [4]], klass: worker_class.name, delete: true)]
+ end
+
+ before do
+ allow(Sidekiq::RetrySet).to receive(:new).and_return(retry_queue)
+ allow(Sidekiq::DeadSet).to receive(:new).and_return(dead_queue)
+ end
+
+ it 'steals from the dead and retry queue' do
+ Sidekiq::Testing.disable! do
+ expect(coordinator).to receive(:perform).with('Object', [1]).ordered
+ expect(coordinator).to receive(:perform).with('Object', [2]).ordered
+ expect(coordinator).to receive(:perform).with('Object', [3]).ordered
+ expect(coordinator).to receive(:perform).with('Object', [4]).ordered
+
+ worker_class.perform_async('Object', [2])
+ worker_class.perform_in(10.minutes, 'Object', [1])
+
+ coordinator.steal('Object', retry_dead_jobs: true)
+ end
+ end
+ end
+ end
+
+ describe '#perform' do
+ let(:migration) { spy(:migration) }
+ let(:connection) { double('connection') }
+
+ before do
+ stub_const('Gitlab::BackgroundMigration::Foo', migration)
+
+ allow(coordinator).to receive(:connection).and_return(connection)
+ end
+
+ it 'performs a background migration with the configured shared connection' do
+ expect(coordinator).to receive(:with_shared_connection).and_call_original
+
+ expect(migration).to receive(:perform).with(10, 20).once do
+ expect(Gitlab::Database::SharedModel.connection).to be(connection)
+ end
+
+ coordinator.perform('Foo', [10, 20])
+ end
+ end
+
+ describe '.remaining', :redis do
+ context 'when there are jobs remaining' do
+ before do
+ Sidekiq::Testing.disable! do
+ MergeWorker.perform_async('Foo')
+ MergeWorker.perform_in(10.minutes, 'Foo')
+
+ 5.times do
+ worker_class.perform_async('Foo')
+ end
+ 3.times do
+ worker_class.perform_in(10.minutes, 'Foo')
+ end
+ end
+ end
+
+ it 'returns the enqueued jobs plus the scheduled jobs' do
+ expect(coordinator.remaining).to eq(8)
+ end
+ end
+
+ context 'when there are no jobs remaining' do
+ it 'returns zero' do
+ expect(coordinator.remaining).to be_zero
+ end
+ end
+ end
+
+ describe '.exists?', :redis do
+ context 'when there are enqueued jobs present' do
+ before do
+ Sidekiq::Testing.disable! do
+ MergeWorker.perform_async('Bar')
+ worker_class.perform_async('Foo')
+ end
+ end
+
+ it 'returns true if specific job exists' do
+ expect(coordinator.exists?('Foo')).to eq(true)
+ end
+
+ it 'returns false if specific job does not exist' do
+ expect(coordinator.exists?('Bar')).to eq(false)
+ end
+ end
+
+ context 'when there are scheduled jobs present' do
+ before do
+ Sidekiq::Testing.disable! do
+ MergeWorker.perform_in(10.minutes, 'Bar')
+ worker_class.perform_in(10.minutes, 'Foo')
+ end
+ end
+
+ it 'returns true if specific job exists' do
+ expect(coordinator.exists?('Foo')).to eq(true)
+ end
+
+ it 'returns false if specific job does not exist' do
+ expect(coordinator.exists?('Bar')).to eq(false)
+ end
+ end
+ end
+
+ describe '.dead_jobs?' do
+ let(:queue) do
+ [
+ double(args: ['Foo', [10, 20]], klass: worker_class.name),
+ double(args: ['Bar'], klass: 'MergeWorker')
+ ]
+ end
+
+ context 'when there are dead jobs present' do
+ before do
+ allow(Sidekiq::DeadSet).to receive(:new).and_return(queue)
+ end
+
+ it 'returns true if specific job exists' do
+ expect(coordinator.dead_jobs?('Foo')).to eq(true)
+ end
+
+ it 'returns false if specific job does not exist' do
+ expect(coordinator.dead_jobs?('Bar')).to eq(false)
+ end
+ end
+ end
+
+ describe '.retrying_jobs?' do
+ let(:queue) do
+ [
+ double(args: ['Foo', [10, 20]], klass: worker_class.name),
+ double(args: ['Bar'], klass: 'MergeWorker')
+ ]
+ end
+
+ context 'when there are dead jobs present' do
+ before do
+ allow(Sidekiq::RetrySet).to receive(:new).and_return(queue)
+ end
+
+ it 'returns true if specific job exists' do
+ expect(coordinator.retrying_jobs?('Foo')).to eq(true)
+ end
+
+ it 'returns false if specific job does not exist' do
+ expect(coordinator.retrying_jobs?('Bar')).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb b/spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb
index b7cf101dd8a..64e8afedf52 100644
--- a/spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb
+++ b/spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::LinkLfsObjectsProjects, :migration, schema: 2020_03_10_075115 do
+RSpec.describe Gitlab::BackgroundMigration::LinkLfsObjectsProjects, :migration, schema: 20181228175414 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:fork_networks) { table(:fork_networks) }
diff --git a/spec/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys_spec.rb b/spec/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys_spec.rb
index c58b2d609e9..4287d6723cf 100644
--- a/spec/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_fingerprint_sha256_within_keys_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::MigrateFingerprintSha256WithinKeys, schema: 20200106071113 do
+RSpec.describe Gitlab::BackgroundMigration::MigrateFingerprintSha256WithinKeys, schema: 20181228175414 do
subject(:fingerprint_migrator) { described_class.new }
let(:key_table) { table(:keys) }
diff --git a/spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb b/spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb
deleted file mode 100644
index f2cd2acd4f3..00000000000
--- a/spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb
+++ /dev/null
@@ -1,327 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::MigrateIssueTrackersSensitiveData, schema: 20200130145430 do
- let(:services) { table(:services) }
-
- before do
- # we need to define the classes due to encryption
- issue_tracker_data = Class.new(ApplicationRecord) do
- self.table_name = 'issue_tracker_data'
-
- def self.encryption_options
- {
- key: Settings.attr_encrypted_db_key_base_32,
- encode: true,
- mode: :per_attribute_iv,
- algorithm: 'aes-256-gcm'
- }
- end
-
- attr_encrypted :project_url, encryption_options
- attr_encrypted :issues_url, encryption_options
- attr_encrypted :new_issue_url, encryption_options
- end
-
- jira_tracker_data = Class.new(ApplicationRecord) do
- self.table_name = 'jira_tracker_data'
-
- def self.encryption_options
- {
- key: Settings.attr_encrypted_db_key_base_32,
- encode: true,
- mode: :per_attribute_iv,
- algorithm: 'aes-256-gcm'
- }
- end
-
- attr_encrypted :url, encryption_options
- attr_encrypted :api_url, encryption_options
- attr_encrypted :username, encryption_options
- attr_encrypted :password, encryption_options
- end
-
- stub_const('IssueTrackerData', issue_tracker_data)
- stub_const('JiraTrackerData', jira_tracker_data)
- end
-
- let(:url) { 'http://base-url.tracker.com' }
- let(:new_issue_url) { 'http://base-url.tracker.com/new_issue' }
- let(:issues_url) { 'http://base-url.tracker.com/issues' }
- let(:api_url) { 'http://api.tracker.com' }
- let(:password) { 'passw1234' }
- let(:username) { 'user9' }
- let(:title) { 'Issue tracker' }
- let(:description) { 'Issue tracker description' }
-
- let(:jira_properties) do
- {
- 'api_url' => api_url,
- 'jira_issue_transition_id' => '5',
- 'password' => password,
- 'url' => url,
- 'username' => username,
- 'title' => title,
- 'description' => description,
- 'other_field' => 'something'
- }
- end
-
- let(:tracker_properties) do
- {
- 'project_url' => url,
- 'new_issue_url' => new_issue_url,
- 'issues_url' => issues_url,
- 'title' => title,
- 'description' => description,
- 'other_field' => 'something'
- }
- end
-
- let(:tracker_properties_no_url) do
- {
- 'new_issue_url' => new_issue_url,
- 'issues_url' => issues_url,
- 'title' => title,
- 'description' => description
- }
- end
-
- subject { described_class.new.perform(1, 100) }
-
- shared_examples 'handle properties' do
- it 'does not clear the properties' do
- expect { subject }.not_to change { service.reload.properties}
- end
- end
-
- context 'with Jira service' do
- let!(:service) do
- services.create!(id: 10, type: 'JiraService', title: nil, properties: jira_properties.to_json, category: 'issue_tracker')
- end
-
- it_behaves_like 'handle properties'
-
- it 'migrates data' do
- expect { subject }.to change { JiraTrackerData.count }.by(1)
-
- service.reload
- data = JiraTrackerData.find_by(service_id: service.id)
-
- expect(data.url).to eq(url)
- expect(data.api_url).to eq(api_url)
- expect(data.username).to eq(username)
- expect(data.password).to eq(password)
- expect(service.title).to eq(title)
- expect(service.description).to eq(description)
- end
- end
-
- context 'with bugzilla service' do
- let!(:service) do
- services.create!(id: 11, type: 'BugzillaService', title: nil, properties: tracker_properties.to_json, category: 'issue_tracker')
- end
-
- it_behaves_like 'handle properties'
-
- it 'migrates data' do
- expect { subject }.to change { IssueTrackerData.count }.by(1)
-
- service.reload
- data = IssueTrackerData.find_by(service_id: service.id)
-
- expect(data.project_url).to eq(url)
- expect(data.issues_url).to eq(issues_url)
- expect(data.new_issue_url).to eq(new_issue_url)
- expect(service.title).to eq(title)
- expect(service.description).to eq(description)
- end
- end
-
- context 'with youtrack service' do
- let!(:service) do
- services.create!(id: 12, type: 'YoutrackService', title: nil, properties: tracker_properties_no_url.to_json, category: 'issue_tracker')
- end
-
- it_behaves_like 'handle properties'
-
- it 'migrates data' do
- expect { subject }.to change { IssueTrackerData.count }.by(1)
-
- service.reload
- data = IssueTrackerData.find_by(service_id: service.id)
-
- expect(data.project_url).to be_nil
- expect(data.issues_url).to eq(issues_url)
- expect(data.new_issue_url).to eq(new_issue_url)
- expect(service.title).to eq(title)
- expect(service.description).to eq(description)
- end
- end
-
- context 'with gitlab service with no properties' do
- let!(:service) do
- services.create!(id: 13, type: 'GitlabIssueTrackerService', title: nil, properties: {}, category: 'issue_tracker')
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not migrate data' do
- expect { subject }.not_to change { IssueTrackerData.count }
- end
- end
-
- context 'with redmine service already with data fields' do
- let!(:service) do
- services.create!(id: 14, type: 'RedmineService', title: nil, properties: tracker_properties_no_url.to_json, category: 'issue_tracker').tap do |service|
- IssueTrackerData.create!(service_id: service.id, project_url: url, new_issue_url: new_issue_url, issues_url: issues_url)
- end
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not create new data fields record' do
- expect { subject }.not_to change { IssueTrackerData.count }
- end
- end
-
- context 'with custom issue tracker which has data fields record inconsistent with properties field' do
- let!(:service) do
- services.create!(id: 15, type: 'CustomIssueTrackerService', title: 'Existing title', properties: jira_properties.to_json, category: 'issue_tracker').tap do |service|
- IssueTrackerData.create!(service_id: service.id, project_url: 'http://other_url', new_issue_url: 'http://other_url/new_issue', issues_url: 'http://other_url/issues')
- end
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not update the data fields record' do
- expect { subject }.not_to change { IssueTrackerData.count }
-
- service.reload
- data = IssueTrackerData.find_by(service_id: service.id)
-
- expect(data.project_url).to eq('http://other_url')
- expect(data.issues_url).to eq('http://other_url/issues')
- expect(data.new_issue_url).to eq('http://other_url/new_issue')
- expect(service.title).to eq('Existing title')
- end
- end
-
- context 'with Jira service which has data fields record inconsistent with properties field' do
- let!(:service) do
- services.create!(id: 16, type: 'CustomIssueTrackerService', description: 'Existing description', properties: jira_properties.to_json, category: 'issue_tracker').tap do |service|
- JiraTrackerData.create!(service_id: service.id, url: 'http://other_jira_url')
- end
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not update the data fields record' do
- expect { subject }.not_to change { JiraTrackerData.count }
-
- service.reload
- data = JiraTrackerData.find_by(service_id: service.id)
-
- expect(data.url).to eq('http://other_jira_url')
- expect(data.password).to be_nil
- expect(data.username).to be_nil
- expect(data.api_url).to be_nil
- expect(service.description).to eq('Existing description')
- end
- end
-
- context 'non issue tracker service' do
- let!(:service) do
- services.create!(id: 17, title: nil, description: nil, type: 'OtherService', properties: tracker_properties.to_json)
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not migrate any data' do
- expect { subject }.not_to change { IssueTrackerData.count }
-
- service.reload
- expect(service.title).to be_nil
- expect(service.description).to be_nil
- end
- end
-
- context 'Jira service with empty properties' do
- let!(:service) do
- services.create!(id: 18, type: 'JiraService', properties: '', category: 'issue_tracker')
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not migrate any data' do
- expect { subject }.not_to change { JiraTrackerData.count }
- end
- end
-
- context 'Jira service with nil properties' do
- let!(:service) do
- services.create!(id: 18, type: 'JiraService', properties: nil, category: 'issue_tracker')
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not migrate any data' do
- expect { subject }.not_to change { JiraTrackerData.count }
- end
- end
-
- context 'Jira service with invalid properties' do
- let!(:service) do
- services.create!(id: 18, type: 'JiraService', properties: 'invalid data', category: 'issue_tracker')
- end
-
- it_behaves_like 'handle properties'
-
- it 'does not migrate any data' do
- expect { subject }.not_to change { JiraTrackerData.count }
- end
- end
-
- context 'with Jira service with invalid properties, valid Jira service and valid bugzilla service' do
- let!(:jira_integration_invalid) do
- services.create!(id: 19, title: 'invalid - title', description: 'invalid - description', type: 'JiraService', properties: 'invalid data', category: 'issue_tracker')
- end
-
- let!(:jira_integration_valid) do
- services.create!(id: 20, type: 'JiraService', properties: jira_properties.to_json, category: 'issue_tracker')
- end
-
- let!(:bugzilla_integration_valid) do
- services.create!(id: 11, type: 'BugzillaService', title: nil, properties: tracker_properties.to_json, category: 'issue_tracker')
- end
-
- it 'migrates data for the valid service' do
- subject
-
- jira_integration_invalid.reload
- expect(JiraTrackerData.find_by(service_id: jira_integration_invalid.id)).to be_nil
- expect(jira_integration_invalid.title).to eq('invalid - title')
- expect(jira_integration_invalid.description).to eq('invalid - description')
- expect(jira_integration_invalid.properties).to eq('invalid data')
-
- jira_integration_valid.reload
- data = JiraTrackerData.find_by(service_id: jira_integration_valid.id)
-
- expect(data.url).to eq(url)
- expect(data.api_url).to eq(api_url)
- expect(data.username).to eq(username)
- expect(data.password).to eq(password)
- expect(jira_integration_valid.title).to eq(title)
- expect(jira_integration_valid.description).to eq(description)
-
- bugzilla_integration_valid.reload
- data = IssueTrackerData.find_by(service_id: bugzilla_integration_valid.id)
-
- expect(data.project_url).to eq(url)
- expect(data.issues_url).to eq(issues_url)
- expect(data.new_issue_url).to eq(new_issue_url)
- expect(bugzilla_integration_valid.title).to eq(title)
- expect(bugzilla_integration_valid.description).to eq(description)
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb b/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb
index 91e8dcdf880..31b6ee0c7cd 100644
--- a/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers do
+RSpec.describe Gitlab::BackgroundMigration::MigrateMergeRequestDiffCommitUsers, schema: 20211012134316 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:users) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb b/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb
index 9eda51f6ec4..ab183d01357 100644
--- a/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_u2f_webauthn_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require 'webauthn/u2f_migrator'
-RSpec.describe Gitlab::BackgroundMigration::MigrateU2fWebauthn, :migration, schema: 20200925125321 do
+RSpec.describe Gitlab::BackgroundMigration::MigrateU2fWebauthn, :migration, schema: 20181228175414 do
let(:users) { table(:users) }
let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) }
diff --git a/spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb b/spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb
deleted file mode 100644
index d90a5d30954..00000000000
--- a/spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::MigrateUsersBioToUserDetails, :migration, schema: 20200323074147 do
- let(:users) { table(:users) }
-
- let(:user_details) do
- klass = table(:user_details)
- klass.primary_key = :user_id
- klass
- end
-
- let!(:user_needs_migration) { users.create!(name: 'user1', email: 'test1@test.com', projects_limit: 1, bio: 'bio') }
- let!(:user_needs_no_migration) { users.create!(name: 'user2', email: 'test2@test.com', projects_limit: 1) }
- let!(:user_also_needs_no_migration) { users.create!(name: 'user3', email: 'test3@test.com', projects_limit: 1, bio: '') }
- let!(:user_with_long_bio) { users.create!(name: 'user4', email: 'test4@test.com', projects_limit: 1, bio: 'a' * 256) } # 255 is the max
-
- let!(:user_already_has_details) { users.create!(name: 'user5', email: 'test5@test.com', projects_limit: 1, bio: 'my bio') }
- let!(:existing_user_details) { user_details.find_or_create_by!(user_id: user_already_has_details.id).update!(bio: 'my bio') }
-
- # unlikely scenario since we have triggers
- let!(:user_has_different_details) { users.create!(name: 'user6', email: 'test6@test.com', projects_limit: 1, bio: 'different') }
- let!(:different_existing_user_details) { user_details.find_or_create_by!(user_id: user_has_different_details.id).update!(bio: 'bio') }
-
- let(:user_ids) do
- [
- user_needs_migration,
- user_needs_no_migration,
- user_also_needs_no_migration,
- user_with_long_bio,
- user_already_has_details,
- user_has_different_details
- ].map(&:id)
- end
-
- subject { described_class.new.perform(user_ids.min, user_ids.max) }
-
- it 'migrates all relevant records' do
- subject
-
- all_user_details = user_details.all
- expect(all_user_details.size).to eq(4)
- end
-
- it 'migrates `bio`' do
- subject
-
- user_detail = user_details.find_by!(user_id: user_needs_migration.id)
-
- expect(user_detail.bio).to eq('bio')
- end
-
- it 'migrates long `bio`' do
- subject
-
- user_detail = user_details.find_by!(user_id: user_with_long_bio.id)
-
- expect(user_detail.bio).to eq('a' * 255)
- end
-
- it 'does not change existing user detail' do
- expect { subject }.not_to change { user_details.find_by!(user_id: user_already_has_details.id).attributes }
- end
-
- it 'changes existing user detail when the columns are different' do
- expect { subject }.to change { user_details.find_by!(user_id: user_has_different_details.id).bio }.from('bio').to('different')
- end
-
- it 'does not migrate record' do
- subject
-
- user_detail = user_details.find_by(user_id: user_needs_no_migration.id)
-
- expect(user_detail).to be_nil
- end
-
- it 'does not migrate empty bio' do
- subject
-
- user_detail = user_details.find_by(user_id: user_also_needs_no_migration.id)
-
- expect(user_detail).to be_nil
- end
-end
diff --git a/spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb b/spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb
index 36000dc3ffd..944ee98ed4a 100644
--- a/spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::PopulateCanonicalEmails, :migration, schema: 20200312053852 do
+RSpec.describe Gitlab::BackgroundMigration::PopulateCanonicalEmails, :migration, schema: 20181228175414 do
let(:migration) { described_class.new }
let_it_be(:users_table) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities_spec.rb
index bc55f240a58..dc8c8c75b83 100644
--- a/spec/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_dismissed_state_for_vulnerabilities_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe ::Gitlab::BackgroundMigration::PopulateDismissedStateForVulnerabilities, schema: 2020_11_30_103926 do
+RSpec.describe ::Gitlab::BackgroundMigration::PopulateDismissedStateForVulnerabilities, schema: 20181228175414 do
let(:users) { table(:users) }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb b/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
index 07b1d99d333..25006e663ab 100644
--- a/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_finding_uuid_for_vulnerability_feedback_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::PopulateFindingUuidForVulnerabilityFeedback, schema: 20201211090634 do
+RSpec.describe Gitlab::BackgroundMigration::PopulateFindingUuidForVulnerabilityFeedback, schema: 20181228175414 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:users) { table(:users) }
diff --git a/spec/lib/gitlab/background_migration/populate_has_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/populate_has_vulnerabilities_spec.rb
index c6385340ca3..6722321d5f7 100644
--- a/spec/lib/gitlab/background_migration/populate_has_vulnerabilities_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_has_vulnerabilities_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::PopulateHasVulnerabilities, schema: 20201103192526 do
+RSpec.describe Gitlab::BackgroundMigration::PopulateHasVulnerabilities, schema: 20181228175414 do
let(:users) { table(:users) }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb b/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
index f724b007e01..a03a11489b5 100644
--- a/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_issue_email_participants_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::PopulateIssueEmailParticipants, schema: 20201128210234 do
+RSpec.describe Gitlab::BackgroundMigration::PopulateIssueEmailParticipants, schema: 20181228175414 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") }
diff --git a/spec/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information_spec.rb b/spec/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information_spec.rb
index 44c5f3d1381..1c987d3876f 100644
--- a/spec/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_missing_vulnerability_dismissal_information_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::PopulateMissingVulnerabilityDismissalInformation, schema: 20201028160832 do
+RSpec.describe Gitlab::BackgroundMigration::PopulateMissingVulnerabilityDismissalInformation, schema: 20181228175414 do
let(:users) { table(:users) }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/populate_personal_snippet_statistics_spec.rb b/spec/lib/gitlab/background_migration/populate_personal_snippet_statistics_spec.rb
index e746451b1b9..f9628849dbf 100644
--- a/spec/lib/gitlab/background_migration/populate_personal_snippet_statistics_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_personal_snippet_statistics_spec.rb
@@ -111,11 +111,11 @@ RSpec.describe Gitlab::BackgroundMigration::PopulatePersonalSnippetStatistics do
if with_repo
allow(snippet).to receive(:disk_path).and_return(disk_path(snippet))
+ raw_repository(snippet).create_repository
+
TestEnv.copy_repo(snippet,
bare_repo: TestEnv.factory_repo_path_bare,
refs: TestEnv::BRANCH_SHA)
-
- raw_repository(snippet).create_repository
end
end
end
diff --git a/spec/lib/gitlab/background_migration/populate_project_snippet_statistics_spec.rb b/spec/lib/gitlab/background_migration/populate_project_snippet_statistics_spec.rb
index 897f5e81372..7884e0d97c0 100644
--- a/spec/lib/gitlab/background_migration/populate_project_snippet_statistics_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_project_snippet_statistics_spec.rb
@@ -183,11 +183,11 @@ RSpec.describe Gitlab::BackgroundMigration::PopulateProjectSnippetStatistics do
if with_repo
allow(snippet).to receive(:disk_path).and_return(disk_path(snippet))
+ raw_repository(snippet).create_repository
+
TestEnv.copy_repo(snippet,
bare_repo: TestEnv.factory_repo_path_bare,
refs: TestEnv::BRANCH_SHA)
-
- raw_repository(snippet).create_repository
end
end
end
diff --git a/spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb b/spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb
deleted file mode 100644
index b3cacc60cdc..00000000000
--- a/spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::PopulateUserHighestRolesTable, schema: 20200311130802 do
- let(:members) { table(:members) }
- let(:users) { table(:users) }
- let(:user_highest_roles) { table(:user_highest_roles) }
-
- def create_user(id, params = {})
- user_params = {
- id: id,
- state: 'active',
- user_type: nil,
- bot_type: nil,
- ghost: nil,
- email: "user#{id}@example.com",
- projects_limit: 0
- }.merge(params)
-
- users.create!(user_params)
- end
-
- def create_member(id, access_level, params = {})
- params = {
- user_id: id,
- access_level: access_level,
- source_id: 1,
- source_type: 'Group',
- notification_level: 0
- }.merge(params)
-
- members.create!(params)
- end
-
- before do
- create_user(1)
- create_user(2, state: 'blocked')
- create_user(3, user_type: 2)
- create_user(4)
- create_user(5, bot_type: 1)
- create_user(6, ghost: true)
- create_user(7, ghost: false)
- create_user(8)
-
- create_member(1, 40)
- create_member(7, 30)
- create_member(8, 20, requested_at: Time.current)
-
- user_highest_roles.create!(user_id: 1, highest_access_level: 50)
- end
-
- describe '#perform' do
- it 'creates user_highest_roles rows according to users', :aggregate_failures do
- expect { subject.perform(1, 8) }.to change(UserHighestRole, :count).from(1).to(4)
-
- created_or_updated_rows = [
- { 'user_id' => 1, 'highest_access_level' => 40 },
- { 'user_id' => 4, 'highest_access_level' => nil },
- { 'user_id' => 7, 'highest_access_level' => 30 },
- { 'user_id' => 8, 'highest_access_level' => nil }
- ]
-
- rows = user_highest_roles.order(:user_id).map do |row|
- row.attributes.slice('user_id', 'highest_access_level')
- end
-
- expect(rows).to match_array(created_or_updated_rows)
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces_spec.rb b/spec/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces_spec.rb
new file mode 100644
index 00000000000..24259b06469
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces_spec.rb
@@ -0,0 +1,254 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::ProjectNamespaces::BackfillProjectNamespaces, :migration do
+ include MigrationsHelpers
+
+ context 'when migrating data', :aggregate_failures do
+ 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_group2) { namespaces.create!(name: 'test1', path: 'test1', runners_token: 'my-token1', project_creation_level: 1, 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) }
+ let(:parent_group2_project) { projects.create!(name: 'parent_group2_project', path: 'parent_group2_project', namespace_id: parent_group2.id, visibility_level: 20) }
+
+ let(:child_nodes_count) { 2 }
+ let(:tree_depth) { 3 }
+
+ let(:backfilled_namespace) { nil }
+
+ before do
+ BackfillProjectNamespaces::TreeGenerator.new(namespaces, projects, [parent_group1, parent_group2], child_nodes_count, tree_depth).build_tree
+ end
+
+ describe '#up' do
+ shared_examples 'back-fill project namespaces' do
+ it 'back-fills all project namespaces' do
+ start_id = ::Project.minimum(:id)
+ end_id = ::Project.maximum(:id)
+ projects_count = ::Project.count
+ batches_count = (projects_count / described_class::BATCH_SIZE.to_f).ceil
+ project_namespaces_count = ::Namespace.where(type: 'Project').count
+ migration = described_class.new
+
+ expect(projects_count).not_to eq(project_namespaces_count)
+ expect(migration).to receive(:batch_insert_namespaces).exactly(batches_count).and_call_original
+ expect(migration).to receive(:batch_update_projects).exactly(batches_count).and_call_original
+ expect(migration).to receive(:batch_update_project_namespaces_traversal_ids).exactly(batches_count).and_call_original
+
+ expect { migration.perform(start_id, end_id, nil, 'up') }.to change(Namespace.where(type: 'Project'), :count)
+
+ expect(projects_count).to eq(::Namespace.where(type: 'Project').count)
+ check_projects_in_sync_with(Namespace.where(type: 'Project'))
+ end
+
+ context 'when passing specific group as parameter' do
+ let(:backfilled_namespace) { parent_group1 }
+
+ it 'back-fills project namespaces for the specified group hierarchy' do
+ backfilled_namespace_projects = base_ancestor(backfilled_namespace).first.all_projects
+ start_id = backfilled_namespace_projects.minimum(:id)
+ end_id = backfilled_namespace_projects.maximum(:id)
+ group_projects_count = backfilled_namespace_projects.count
+ batches_count = (group_projects_count / described_class::BATCH_SIZE.to_f).ceil
+ project_namespaces_in_hierarchy = project_namespaces_in_hierarchy(base_ancestor(backfilled_namespace))
+
+ migration = described_class.new
+
+ expect(project_namespaces_in_hierarchy.count).to eq(0)
+ expect(migration).to receive(:batch_insert_namespaces).exactly(batches_count).and_call_original
+ expect(migration).to receive(:batch_update_projects).exactly(batches_count).and_call_original
+ expect(migration).to receive(:batch_update_project_namespaces_traversal_ids).exactly(batches_count).and_call_original
+
+ expect(group_projects_count).to eq(14)
+ expect(project_namespaces_in_hierarchy.count).to eq(0)
+
+ migration.perform(start_id, end_id, backfilled_namespace.id, 'up')
+
+ expect(project_namespaces_in_hierarchy.count).to eq(14)
+ check_projects_in_sync_with(project_namespaces_in_hierarchy)
+ end
+ end
+
+ context 'when projects already have project namespaces' do
+ before do
+ hierarchy1_projects = base_ancestor(parent_group1).first.all_projects
+ start_id = hierarchy1_projects.minimum(:id)
+ end_id = hierarchy1_projects.maximum(:id)
+
+ described_class.new.perform(start_id, end_id, parent_group1.id, 'up')
+ end
+
+ it 'does not duplicate project namespaces' do
+ # check there are already some project namespaces but not for all
+ projects_count = ::Project.count
+ start_id = ::Project.minimum(:id)
+ end_id = ::Project.maximum(:id)
+ batches_count = (projects_count / described_class::BATCH_SIZE.to_f).ceil
+ project_namespaces = ::Namespace.where(type: 'Project')
+ migration = described_class.new
+
+ expect(project_namespaces_in_hierarchy(base_ancestor(parent_group1)).count).to be >= 14
+ expect(project_namespaces_in_hierarchy(base_ancestor(parent_group2)).count).to eq(0)
+ expect(projects_count).not_to eq(project_namespaces.count)
+
+ # run migration again to test we do not generate extra project namespaces
+ expect(migration).to receive(:batch_insert_namespaces).exactly(batches_count).and_call_original
+ expect(migration).to receive(:batch_update_projects).exactly(batches_count).and_call_original
+ expect(migration).to receive(:batch_update_project_namespaces_traversal_ids).exactly(batches_count).and_call_original
+
+ expect { migration.perform(start_id, end_id, nil, 'up') }.to change(project_namespaces, :count).by(14)
+
+ expect(projects_count).to eq(project_namespaces.count)
+ end
+ end
+ end
+
+ it 'checks no project namespaces exist in the defined hierarchies' do
+ hierarchy1_project_namespaces = project_namespaces_in_hierarchy(base_ancestor(parent_group1))
+ hierarchy2_project_namespaces = project_namespaces_in_hierarchy(base_ancestor(parent_group2))
+ hierarchy1_projects_count = base_ancestor(parent_group1).first.all_projects.count
+ hierarchy2_projects_count = base_ancestor(parent_group2).first.all_projects.count
+
+ expect(hierarchy1_project_namespaces).to be_empty
+ expect(hierarchy2_project_namespaces).to be_empty
+ expect(hierarchy1_projects_count).to eq(14)
+ expect(hierarchy2_projects_count).to eq(14)
+ end
+
+ context 'back-fill project namespaces in a single batch' do
+ it_behaves_like 'back-fill project namespaces'
+ end
+
+ context 'back-fill project namespaces in batches' do
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+ end
+
+ it_behaves_like 'back-fill project namespaces'
+ end
+ end
+
+ describe '#down' do
+ before do
+ start_id = ::Project.minimum(:id)
+ end_id = ::Project.maximum(:id)
+ # back-fill first
+ described_class.new.perform(start_id, end_id, nil, 'up')
+ end
+
+ shared_examples 'cleanup project namespaces' do
+ it 'removes project namespaces' do
+ projects_count = ::Project.count
+ start_id = ::Project.minimum(:id)
+ end_id = ::Project.maximum(:id)
+ migration = described_class.new
+ batches_count = (projects_count / described_class::BATCH_SIZE.to_f).ceil
+
+ expect(projects_count).to be > 0
+ expect(projects_count).to eq(::Namespace.where(type: 'Project').count)
+
+ expect(migration).to receive(:nullify_project_namespaces_in_projects).exactly(batches_count).and_call_original
+ expect(migration).to receive(:delete_project_namespace_records).exactly(batches_count).and_call_original
+
+ migration.perform(start_id, end_id, nil, 'down')
+
+ expect(::Project.count).to be > 0
+ expect(::Namespace.where(type: 'Project').count).to eq(0)
+ end
+
+ context 'when passing specific group as parameter' do
+ let(:backfilled_namespace) { parent_group1 }
+
+ it 'removes project namespaces only for the specific group hierarchy' do
+ backfilled_namespace_projects = base_ancestor(backfilled_namespace).first.all_projects
+ start_id = backfilled_namespace_projects.minimum(:id)
+ end_id = backfilled_namespace_projects.maximum(:id)
+ group_projects_count = backfilled_namespace_projects.count
+ batches_count = (group_projects_count / described_class::BATCH_SIZE.to_f).ceil
+ project_namespaces_in_hierarchy = project_namespaces_in_hierarchy(base_ancestor(backfilled_namespace))
+ migration = described_class.new
+
+ expect(project_namespaces_in_hierarchy.count).to eq(14)
+ expect(migration).to receive(:nullify_project_namespaces_in_projects).exactly(batches_count).and_call_original
+ expect(migration).to receive(:delete_project_namespace_records).exactly(batches_count).and_call_original
+
+ migration.perform(start_id, end_id, backfilled_namespace.id, 'down')
+
+ expect(::Namespace.where(type: 'Project').count).to be > 0
+ expect(project_namespaces_in_hierarchy.count).to eq(0)
+ end
+ end
+ end
+
+ context 'cleanup project namespaces in a single batch' do
+ it_behaves_like 'cleanup project namespaces'
+ end
+
+ context 'cleanup project namespaces in batches' do
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+ end
+
+ it_behaves_like 'cleanup project namespaces'
+ end
+ end
+ end
+
+ def base_ancestor(ancestor)
+ ::Namespace.where(id: ancestor.id)
+ end
+
+ def project_namespaces_in_hierarchy(base_node)
+ Gitlab::ObjectHierarchy.new(base_node).base_and_descendants.where(type: 'Project')
+ end
+
+ def check_projects_in_sync_with(namespaces)
+ project_namespaces_attrs = namespaces.order(:id).pluck(:id, :name, :path, :parent_id, :visibility_level, :shared_runners_enabled)
+ corresponding_projects_attrs = Project.where(project_namespace_id: project_namespaces_attrs.map(&:first))
+ .order(:project_namespace_id).pluck(:project_namespace_id, :name, :path, :namespace_id, :visibility_level, :shared_runners_enabled)
+
+ expect(project_namespaces_attrs).to eq(corresponding_projects_attrs)
+ end
+end
+
+module BackfillProjectNamespaces
+ class TreeGenerator
+ def initialize(namespaces, projects, parent_nodes, child_nodes_count, tree_depth)
+ parent_nodes_ids = parent_nodes.map(&:id)
+
+ @namespaces = namespaces
+ @projects = projects
+ @subgroups_depth = tree_depth
+ @resource_count = child_nodes_count
+ @all_groups = [parent_nodes_ids]
+ end
+
+ def build_tree
+ (1..@subgroups_depth).each do |level|
+ parent_level = level - 1
+ current_level = level
+ parent_groups = @all_groups[parent_level]
+
+ parent_groups.each do |parent_id|
+ @resource_count.times do |i|
+ group_path = "child#{i}_level#{level}"
+ project_path = "project#{i}_level#{level}"
+ sub_group = @namespaces.create!(name: group_path, path: group_path, parent_id: parent_id, visibility_level: 20, type: 'Group')
+ @projects.create!(name: project_path, path: project_path, namespace_id: sub_group.id, visibility_level: 20)
+
+ track_group_id(current_level, sub_group.id)
+ end
+ end
+ end
+ end
+
+ def track_group_id(depth_level, group_id)
+ @all_groups[depth_level] ||= []
+ @all_groups[depth_level] << group_id
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id_spec.rb b/spec/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id_spec.rb
index c1ba1607b89..1830a7fc099 100644
--- a/spec/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id_spec.rb
+++ b/spec/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::RecalculateProjectAuthorizationsWithMinMaxUserId, schema: 20200204113224 do
+RSpec.describe Gitlab::BackgroundMigration::RecalculateProjectAuthorizationsWithMinMaxUserId, schema: 20181228175414 do
let(:users_table) { table(:users) }
let(:min) { 1 }
let(:max) { 5 }
diff --git a/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
index 30908145782..4cdb56d3d3b 100644
--- a/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
+++ b/spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid, schema: 20201110110454 do
+RSpec.describe Gitlab::BackgroundMigration::RecalculateVulnerabilitiesOccurrencesUuid, schema: 20181228175414 do
let(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
let(:users) { table(:users) }
let(:user) { create_user! }
diff --git a/spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb b/spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb
index 391b27b28e6..afcdaaf1cb8 100644
--- a/spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_duplicate_services_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateServices, :migration, schema: 20201207165956 do
+RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateServices, :migration, schema: 20181228175414 do
let_it_be(:users) { table(:users) }
let_it_be(:namespaces) { table(:namespaces) }
let_it_be(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb b/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb
index 47e1d4620cd..7214225c32c 100644
--- a/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_duplicate_vulnerabilities_findings_spec.rb
@@ -5,9 +5,9 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin
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(:project) { table(:projects).create!(id: 14219619, 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!(:scanner1) { 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') }
@@ -16,43 +16,68 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin
let(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
let(:vulnerability_identifier) do
vulnerability_identifiers.create!(
+ id: 1244459,
project_id: project.id,
external_type: 'vulnerability-identifier',
external_id: 'vulnerability-identifier',
- fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
+ fingerprint: '0a203e8cd5260a1948edbedc76c7cb91ad6a2e45',
name: 'vulnerability identifier')
end
- let!(:first_finding) do
+ let!(:vulnerability_for_first_duplicate) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:first_finding_duplicate) do
create_finding!(
- uuid: "test1",
- vulnerability_id: nil,
+ id: 5606961,
+ uuid: "bd95c085-71aa-51d7-9bb6-08ae669c262e",
+ vulnerability_id: vulnerability_for_first_duplicate.id,
report_type: 0,
- location_fingerprint: '2bda3014914481791847d8eca38d1a8d13b6ad76',
+ location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
primary_identifier_id: vulnerability_identifier.id,
- scanner_id: scanner.id,
+ scanner_id: scanner1.id,
project_id: project.id
)
end
- let!(:first_duplicate) do
+ let!(:vulnerability_for_second_duplicate) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:second_finding_duplicate) do
create_finding!(
- uuid: "test2",
- vulnerability_id: nil,
+ id: 8765432,
+ uuid: "5b714f58-1176-5b26-8fd5-e11dfcb031b5",
+ vulnerability_id: vulnerability_for_second_duplicate.id,
report_type: 0,
- location_fingerprint: '2bda3014914481791847d8eca38d1a8d13b6ad76',
+ location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
primary_identifier_id: vulnerability_identifier.id,
scanner_id: scanner2.id,
project_id: project.id
)
end
- let!(:second_duplicate) do
+ let!(:vulnerability_for_third_duplicate) do
+ create_vulnerability!(
+ project_id: project.id,
+ author_id: user.id
+ )
+ end
+
+ let!(:third_finding_duplicate) do
create_finding!(
- uuid: "test3",
- vulnerability_id: nil,
+ id: 8832995,
+ uuid: "cfe435fa-b25b-5199-a56d-7b007cc9e2d4",
+ vulnerability_id: vulnerability_for_third_duplicate.id,
report_type: 0,
- location_fingerprint: '2bda3014914481791847d8eca38d1a8d13b6ad76',
+ location_fingerprint: '00049d5119c2cb3bfb3d1ee1f6e031fe925aed75',
primary_identifier_id: vulnerability_identifier.id,
scanner_id: scanner3.id,
project_id: project.id
@@ -61,6 +86,7 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin
let!(:unrelated_finding) do
create_finding!(
+ id: 9999999,
uuid: "unreleated_finding",
vulnerability_id: nil,
report_type: 1,
@@ -71,7 +97,7 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin
)
end
- subject { described_class.new.perform(first_finding.id, unrelated_finding.id) }
+ subject { described_class.new.perform(first_finding_duplicate.id, unrelated_finding.id) }
before do
stub_const("#{described_class}::DELETE_BATCH_SIZE", 1)
@@ -82,7 +108,15 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin
expect { subject }.to change { vulnerability_findings.count }.from(4).to(2)
- expect(vulnerability_findings.pluck(:id)).to eq([second_duplicate.id, unrelated_finding.id])
+ expect(vulnerability_findings.pluck(:id)).to match_array([third_finding_duplicate.id, unrelated_finding.id])
+ end
+
+ it "removes vulnerabilites without findings" do
+ expect(vulnerabilities.count).to eq(3)
+
+ expect { subject }.to change { vulnerabilities.count }.from(3).to(1)
+
+ expect(vulnerabilities.pluck(:id)).to match_array([vulnerability_for_third_duplicate.id])
end
private
@@ -100,11 +134,12 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin
# 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: 'test')
- vulnerability_findings.create!(
+ params = {
vulnerability_id: vulnerability_id,
project_id: project_id,
name: name,
@@ -118,7 +153,9 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveDuplicateVulnerabilitiesFindin
metadata_version: metadata_version,
raw_metadata: raw_metadata,
uuid: uuid
- )
+ }
+ params[:id] = id unless id.nil?
+ vulnerability_findings.create!(params)
end
# rubocop:enable Metrics/ParameterLists
diff --git a/spec/lib/gitlab/background_migration/replace_blocked_by_links_spec.rb b/spec/lib/gitlab/background_migration/replace_blocked_by_links_spec.rb
index 561a602fab9..6cfdbb5a14e 100644
--- a/spec/lib/gitlab/background_migration/replace_blocked_by_links_spec.rb
+++ b/spec/lib/gitlab/background_migration/replace_blocked_by_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::ReplaceBlockedByLinks, schema: 20201015073808 do
+RSpec.describe Gitlab::BackgroundMigration::ReplaceBlockedByLinks, schema: 20181228175414 do
let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') }
let(:project) { table(:projects).create!(namespace_id: namespace.id, name: 'gitlab') }
let(:issue1) { table(:issues).create!(project_id: project.id, title: 'a') }
diff --git a/spec/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects_spec.rb b/spec/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects_spec.rb
index 68aa64a1c7d..ef90b5674f0 100644
--- a/spec/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects_spec.rb
+++ b/spec/lib/gitlab/background_migration/reset_shared_runners_for_transferred_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::ResetSharedRunnersForTransferredProjects, schema: 20201110161542 do
+RSpec.describe Gitlab::BackgroundMigration::ResetSharedRunnersForTransferredProjects, schema: 20181228175414 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/set_default_iteration_cadences_spec.rb b/spec/lib/gitlab/background_migration/set_default_iteration_cadences_spec.rb
deleted file mode 100644
index 46c919f0854..00000000000
--- a/spec/lib/gitlab/background_migration/set_default_iteration_cadences_spec.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::SetDefaultIterationCadences, schema: 20201231133921 do
- let(:namespaces) { table(:namespaces) }
- let(:iterations) { table(:sprints) }
- let(:iterations_cadences) { table(:iterations_cadences) }
-
- describe '#perform' do
- context 'when no iteration cadences exists' do
- let!(:group_1) { namespaces.create!(name: 'group 1', path: 'group-1') }
- let!(:group_2) { namespaces.create!(name: 'group 2', path: 'group-2') }
- let!(:group_3) { namespaces.create!(name: 'group 3', path: 'group-3') }
-
- let!(:iteration_1) { iterations.create!(group_id: group_1.id, iid: 1, title: 'Iteration 1', start_date: 10.days.ago, due_date: 8.days.ago) }
- let!(:iteration_2) { iterations.create!(group_id: group_3.id, iid: 1, title: 'Iteration 2', start_date: 10.days.ago, due_date: 8.days.ago) }
- let!(:iteration_3) { iterations.create!(group_id: group_3.id, iid: 1, title: 'Iteration 3', start_date: 5.days.ago, due_date: 2.days.ago) }
-
- subject { described_class.new.perform(group_1.id, group_2.id, group_3.id, namespaces.last.id + 1) }
-
- before do
- subject
- end
-
- it 'creates iterations_cadence records for the requested groups' do
- expect(iterations_cadences.count).to eq(2)
- end
-
- it 'assigns the iteration cadences to the iterations correctly' do
- iterations_cadence = iterations_cadences.find_by(group_id: group_1.id)
- iteration_records = iterations.where(iterations_cadence_id: iterations_cadence.id)
-
- expect(iterations_cadence.start_date).to eq(iteration_1.start_date)
- expect(iterations_cadence.last_run_date).to eq(iteration_1.start_date)
- expect(iterations_cadence.title).to eq('group 1 Iterations')
- expect(iteration_records.size).to eq(1)
- expect(iteration_records.first.id).to eq(iteration_1.id)
-
- iterations_cadence = iterations_cadences.find_by(group_id: group_3.id)
- iteration_records = iterations.where(iterations_cadence_id: iterations_cadence.id)
-
- expect(iterations_cadence.start_date).to eq(iteration_3.start_date)
- expect(iterations_cadence.last_run_date).to eq(iteration_3.start_date)
- expect(iterations_cadence.title).to eq('group 3 Iterations')
- expect(iteration_records.size).to eq(2)
- expect(iteration_records.first.id).to eq(iteration_2.id)
- expect(iteration_records.second.id).to eq(iteration_3.id)
- end
-
- it 'does not call Group class' do
- expect(::Group).not_to receive(:where)
-
- subject
- end
- end
-
- context 'when an iteration cadence exists for a group' do
- let!(:group) { namespaces.create!(name: 'group', path: 'group') }
-
- let!(:iterations_cadence_1) { iterations_cadences.create!(group_id: group.id, start_date: 2.days.ago, title: 'Cadence 1') }
-
- let!(:iteration_1) { iterations.create!(group_id: group.id, iid: 1, title: 'Iteration 1', start_date: 10.days.ago, due_date: 8.days.ago) }
- let!(:iteration_2) { iterations.create!(group_id: group.id, iterations_cadence_id: iterations_cadence_1.id, iid: 2, title: 'Iteration 2', start_date: 5.days.ago, due_date: 3.days.ago) }
-
- subject { described_class.new.perform(group.id) }
-
- it 'does not create a new iterations_cadence' do
- expect { subject }.not_to change { iterations_cadences.count }
- end
-
- it 'assigns iteration cadences to iterations if needed' do
- subject
-
- expect(iteration_1.reload.iterations_cadence_id).to eq(iterations_cadence_1.id)
- expect(iteration_2.reload.iterations_cadence_id).to eq(iterations_cadence_1.id)
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/background_migration/set_merge_request_diff_files_count_spec.rb b/spec/lib/gitlab/background_migration/set_merge_request_diff_files_count_spec.rb
index f23518625e4..1fdbdf25706 100644
--- a/spec/lib/gitlab/background_migration/set_merge_request_diff_files_count_spec.rb
+++ b/spec/lib/gitlab/background_migration/set_merge_request_diff_files_count_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::SetMergeRequestDiffFilesCount, schema: 20200807152315 do
+RSpec.describe Gitlab::BackgroundMigration::SetMergeRequestDiffFilesCount, schema: 20181228175414 do
let(:merge_request_diff_files) { table(:merge_request_diff_files) }
let(:merge_request_diffs) { table(:merge_request_diffs) }
let(:merge_requests) { table(:merge_requests) }
diff --git a/spec/lib/gitlab/background_migration/set_null_external_diff_store_to_local_value_spec.rb b/spec/lib/gitlab/background_migration/set_null_external_diff_store_to_local_value_spec.rb
deleted file mode 100644
index 6079ad2dd2a..00000000000
--- a/spec/lib/gitlab/background_migration/set_null_external_diff_store_to_local_value_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-# The test setup must begin before
-# 20200804041930_add_not_null_constraint_on_external_diff_store_to_merge_request_diffs.rb
-# has run, or else we cannot insert a row with `NULL` `external_diff_store` to
-# test against.
-RSpec.describe Gitlab::BackgroundMigration::SetNullExternalDiffStoreToLocalValue, schema: 20200804035230 do
- let!(:merge_request_diffs) { table(:merge_request_diffs) }
- let!(:merge_requests) { table(:merge_requests) }
- let!(:namespaces) { table(:namespaces) }
- let!(:projects) { table(:projects) }
- let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
- let!(:project) { projects.create!(namespace_id: namespace.id) }
- let!(:merge_request) { merge_requests.create!(source_branch: 'x', target_branch: 'master', target_project_id: project.id) }
-
- it 'correctly migrates nil external_diff_store to 1' do
- external_diff_store_1 = merge_request_diffs.create!(external_diff_store: 1, merge_request_id: merge_request.id)
- external_diff_store_2 = merge_request_diffs.create!(external_diff_store: 2, merge_request_id: merge_request.id)
- external_diff_store_nil = merge_request_diffs.create!(external_diff_store: nil, merge_request_id: merge_request.id)
-
- described_class.new.perform(external_diff_store_1.id, external_diff_store_nil.id)
-
- external_diff_store_1.reload
- external_diff_store_2.reload
- external_diff_store_nil.reload
-
- expect(external_diff_store_1.external_diff_store).to eq(1) # unchanged
- expect(external_diff_store_2.external_diff_store).to eq(2) # unchanged
- expect(external_diff_store_nil.external_diff_store).to eq(1) # nil => 1
- end
-end
diff --git a/spec/lib/gitlab/background_migration/set_null_package_files_file_store_to_local_value_spec.rb b/spec/lib/gitlab/background_migration/set_null_package_files_file_store_to_local_value_spec.rb
deleted file mode 100644
index 40d41262fc7..00000000000
--- a/spec/lib/gitlab/background_migration/set_null_package_files_file_store_to_local_value_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-# The test setup must begin before
-# 20200806004742_add_not_null_constraint_on_file_store_to_package_files.rb
-# has run, or else we cannot insert a row with `NULL` `file_store` to
-# test against.
-RSpec.describe Gitlab::BackgroundMigration::SetNullPackageFilesFileStoreToLocalValue, schema: 20200806004232 do
- let!(:packages_package_files) { table(:packages_package_files) }
- let!(:packages_packages) { table(:packages_packages) }
- let!(:projects) { table(:projects) }
- let!(:namespaces) { table(:namespaces) }
- let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') }
- let!(:project) { projects.create!(namespace_id: namespace.id) }
- let!(:package) { packages_packages.create!(project_id: project.id, name: 'bar', package_type: 1) }
-
- it 'correctly migrates nil file_store to 1' do
- file_store_1 = packages_package_files.create!(file_store: 1, file_name: 'foo_1', file: 'foo_1', package_id: package.id)
- file_store_2 = packages_package_files.create!(file_store: 2, file_name: 'foo_2', file: 'foo_2', package_id: package.id)
- file_store_nil = packages_package_files.create!(file_store: nil, file_name: 'foo_nil', file: 'foo_nil', package_id: package.id)
-
- described_class.new.perform(file_store_1.id, file_store_nil.id)
-
- file_store_1.reload
- file_store_2.reload
- file_store_nil.reload
-
- expect(file_store_1.file_store).to eq(1) # unchanged
- expect(file_store_2.file_store).to eq(2) # unchanged
- expect(file_store_nil.file_store).to eq(1) # nil => 1
- end
-end
diff --git a/spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb b/spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb
index f2fb2ab6b6e..841a7f306d7 100644
--- a/spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb
+++ b/spec/lib/gitlab/background_migration/steal_migrate_merge_request_diff_commit_users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::StealMigrateMergeRequestDiffCommitUsers do
+RSpec.describe Gitlab::BackgroundMigration::StealMigrateMergeRequestDiffCommitUsers, schema: 20211012134316 do
let(:migration) { described_class.new }
describe '#perform' do
diff --git a/spec/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb b/spec/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb
index 6c0a1d3a5b0..de9799c3642 100644
--- a/spec/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb
+++ b/spec/lib/gitlab/background_migration/update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::UpdateExistingSubgroupToMatchVisibilityLevelOfParent, schema: 2020_01_10_121314 do
+RSpec.describe Gitlab::BackgroundMigration::UpdateExistingSubgroupToMatchVisibilityLevelOfParent, schema: 20181228175414 do
include MigrationHelpers::NamespacesHelpers
context 'private visibility level' do
diff --git a/spec/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth_spec.rb b/spec/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth_spec.rb
index bebb398413b..33f5e38100e 100644
--- a/spec/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth_spec.rb
+++ b/spec/lib/gitlab/background_migration/update_existing_users_that_require_two_factor_auth_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::UpdateExistingUsersThatRequireTwoFactorAuth, schema: 20201030121314 do
+RSpec.describe Gitlab::BackgroundMigration::UpdateExistingUsersThatRequireTwoFactorAuth, schema: 20181228175414 do
include MigrationHelpers::NamespacesHelpers
let(:group_with_2fa_parent) { create_namespace('parent', Gitlab::VisibilityLevel::PRIVATE) }
diff --git a/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb b/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb
index 2dae4a65eeb..7af11ffa1e0 100644
--- a/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb
+++ b/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb
@@ -1,120 +1,8 @@
# frozen_string_literal: true
require 'spec_helper'
-require './db/post_migrate/20200128134110_migrate_commit_notes_mentions_to_db'
-require './db/post_migrate/20200211155539_migrate_merge_request_mentions_to_db'
-
-RSpec.describe Gitlab::BackgroundMigration::UserMentions::CreateResourceUserMention, schema: 20200211155539 do
- include MigrationsHelpers
-
- context 'when migrating data' do
- let(:users) { table(:users) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:notes) { table(:notes) }
- let(:routes) { table(:routes) }
-
- let(:author) { users.create!(email: 'author@example.com', notification_email: 'author@example.com', name: 'author', username: 'author', projects_limit: 10, state: 'active') }
- let(:member) { users.create!(email: 'member@example.com', notification_email: 'member@example.com', name: 'member', username: 'member', projects_limit: 10, state: 'active') }
- let(:admin) { users.create!(email: 'administrator@example.com', notification_email: 'administrator@example.com', name: 'administrator', username: 'administrator', admin: 1, projects_limit: 10, state: 'active') }
- let(:john_doe) { users.create!(email: 'john_doe@example.com', notification_email: 'john_doe@example.com', name: 'john_doe', username: 'john_doe', projects_limit: 10, state: 'active') }
- let(:skipped) { users.create!(email: 'skipped@example.com', notification_email: 'skipped@example.com', name: 'skipped', username: 'skipped', projects_limit: 10, state: 'active') }
-
- let(:mentioned_users) { [author, member, admin, john_doe, skipped] }
- let(:mentioned_users_refs) { mentioned_users.map { |u| "@#{u.username}" }.join(' ') }
-
- let(:group) { namespaces.create!(name: 'test1', path: 'test1', runners_token: 'my-token1', project_creation_level: 1, visibility_level: 20, type: 'Group') }
- let(:inaccessible_group) { namespaces.create!(name: 'test2', path: 'test2', runners_token: 'my-token2', project_creation_level: 1, visibility_level: 0, type: 'Group') }
- let(:project) { projects.create!(name: 'gitlab1', path: 'gitlab1', namespace_id: group.id, visibility_level: 0) }
-
- let(:mentioned_groups) { [group, inaccessible_group] }
- let(:group_mentions) { [group, inaccessible_group].map { |gr| "@#{gr.path}" }.join(' ') }
- let(:description_mentions) { "description with mentions #{mentioned_users_refs} and #{group_mentions}" }
-
- before do
- # build personal namespaces and routes for users
- mentioned_users.each do |u|
- namespace = namespaces.create!(path: u.username, name: u.name, runners_token: "my-token-u#{u.id}", owner_id: u.id, type: nil)
- routes.create!(path: namespace.path, source_type: 'Namespace', source_id: namespace.id)
- end
-
- # build namespaces and routes for groups
- mentioned_groups.each do |gr|
- routes.create!(path: gr.path, source_type: 'Namespace', source_id: gr.id)
- end
- end
-
- context 'migrate merge request mentions' do
- let(:merge_requests) { table(:merge_requests) }
- let(:merge_request_user_mentions) { table(:merge_request_user_mentions) }
-
- let!(:mr1) do
- merge_requests.create!(
- title: "title 1", state_id: 1, target_branch: 'feature1', source_branch: 'master',
- source_project_id: project.id, target_project_id: project.id, author_id: author.id,
- description: description_mentions
- )
- end
-
- let!(:mr2) do
- merge_requests.create!(
- title: "title 2", state_id: 1, target_branch: 'feature2', source_branch: 'master',
- source_project_id: project.id, target_project_id: project.id, author_id: author.id,
- description: 'some description'
- )
- end
-
- let!(:mr3) do
- merge_requests.create!(
- title: "title 3", state_id: 1, target_branch: 'feature3', source_branch: 'master',
- source_project_id: project.id, target_project_id: project.id, author_id: author.id,
- description: 'description with an email@example.com and some other @ char here.')
- end
-
- let(:user_mentions) { merge_request_user_mentions }
- let(:resource) { merge_request }
-
- it_behaves_like 'resource mentions migration', MigrateMergeRequestMentionsToDb, 'MergeRequest'
-
- context 'when FF disabled' do
- before do
- stub_feature_flags(migrate_user_mentions: false)
- end
-
- it_behaves_like 'resource migration not run', MigrateMergeRequestMentionsToDb, 'MergeRequest'
- end
- end
-
- context 'migrate commit mentions' do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') }
- let(:commit) { Commit.new(RepoHelpers.sample_commit, project) }
- let(:commit_user_mentions) { table(:commit_user_mentions) }
-
- let!(:note1) { notes.create!(commit_id: commit.id, noteable_type: 'Commit', project_id: project.id, author_id: author.id, note: description_mentions) }
- let!(:note2) { notes.create!(commit_id: commit.id, noteable_type: 'Commit', project_id: project.id, author_id: author.id, note: 'sample note') }
- let!(:note3) { notes.create!(commit_id: commit.id, noteable_type: 'Commit', project_id: project.id, author_id: author.id, note: description_mentions, system: true) }
-
- # this not does not have actual mentions
- let!(:note4) { notes.create!(commit_id: commit.id, noteable_type: 'Commit', project_id: project.id, author_id: author.id, note: 'note for an email@somesite.com and some other random @ ref' ) }
- # this should have pointed to an innexisted commit record in a commits table
- # but because commit is not an AR we'll just make it so that it does not have mentions
- let!(:note5) { notes.create!(commit_id: 'abc', noteable_type: 'Commit', project_id: project.id, author_id: author.id, note: 'note for an email@somesite.com and some other random @ ref') }
-
- let(:user_mentions) { commit_user_mentions }
- let(:resource) { commit }
-
- it_behaves_like 'resource notes mentions migration', MigrateCommitNotesMentionsToDb, 'Commit'
-
- context 'when FF disabled' do
- before do
- stub_feature_flags(migrate_user_mentions: false)
- end
-
- it_behaves_like 'resource notes migration not run', MigrateCommitNotesMentionsToDb, 'Commit'
- end
- end
- end
+RSpec.describe Gitlab::BackgroundMigration::UserMentions::CreateResourceUserMention, schema: 20181228175414 do
context 'checks no_quote_columns' do
it 'has correct no_quote_columns' do
expect(Gitlab::BackgroundMigration::UserMentions::Models::MergeRequest.no_quote_columns).to match([:note_id, :merge_request_id])
diff --git a/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb b/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
index 07f4429f7d9..5c197526a55 100644
--- a/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
+++ b/spec/lib/gitlab/background_migration/wrongfully_confirmed_email_unconfirmer_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::WrongfullyConfirmedEmailUnconfirmer, schema: 20200615111857 do
+RSpec.describe Gitlab::BackgroundMigration::WrongfullyConfirmedEmailUnconfirmer, schema: 20181228175414 do
let(:users) { table(:users) }
let(:emails) { table(:emails) }
let(:user_synced_attributes_metadata) { table(:user_synced_attributes_metadata) }