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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/background_migration')
-rw-r--r--spec/lib/gitlab/background_migration/backfill_namespace_id_for_project_route_spec.rb4
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb124
-rw-r--r--spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb104
-rw-r--r--spec/lib/gitlab/background_migration/cleanup_orphaned_routes_spec.rb80
-rw-r--r--spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/fix_merge_request_diff_commit_users_spec.rb297
-rw-r--r--spec/lib/gitlab/background_migration/migrate_pages_to_zip_storage_spec.rb43
-rw-r--r--spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb54
8 files changed, 368 insertions, 340 deletions
diff --git a/spec/lib/gitlab/background_migration/backfill_namespace_id_for_project_route_spec.rb b/spec/lib/gitlab/background_migration/backfill_namespace_id_for_project_route_spec.rb
index 2dcd4645c84..2949bc068c8 100644
--- a/spec/lib/gitlab/background_migration/backfill_namespace_id_for_project_route_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_namespace_id_for_project_route_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdForProjectRoute do
+# this needs the schema to be before we introduce the not null constraint on routes#namespace_id
+RSpec.describe Gitlab::BackgroundMigration::BackfillNamespaceIdForProjectRoute, schema: 20220606060825 do
let(:migration) { described_class.new }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb
new file mode 100644
index 00000000000..fd6c055b9f6
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_project_feature_package_registry_access_level_spec.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillProjectFeaturePackageRegistryAccessLevel do
+ let(:non_null_project_features) { { pages_access_level: 20 } }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:project_features) { table(:project_features) }
+
+ let(:namespace1) { namespaces.create!(name: 'namespace 1', path: 'namespace1') }
+ let(:namespace2) { namespaces.create!(name: 'namespace 2', path: 'namespace2') }
+ let(:namespace3) { namespaces.create!(name: 'namespace 3', path: 'namespace3') }
+ let(:namespace4) { namespaces.create!(name: 'namespace 4', path: 'namespace4') }
+ let(:namespace5) { namespaces.create!(name: 'namespace 5', path: 'namespace5') }
+ let(:namespace6) { namespaces.create!(name: 'namespace 6', path: 'namespace6') }
+
+ let(:project1) do
+ projects.create!(namespace_id: namespace1.id, project_namespace_id: namespace1.id, packages_enabled: false)
+ end
+
+ let(:project2) do
+ projects.create!(namespace_id: namespace2.id, project_namespace_id: namespace2.id, packages_enabled: nil)
+ end
+
+ let(:project3) do
+ projects.create!(
+ namespace_id: namespace3.id,
+ project_namespace_id: namespace3.id,
+ packages_enabled: true,
+ visibility_level: Gitlab::VisibilityLevel::PRIVATE
+ )
+ end
+
+ let(:project4) do
+ projects.create!(
+ namespace_id: namespace4.id,
+ project_namespace_id: namespace4.id,
+ packages_enabled: true, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ end
+
+ let(:project5) do
+ projects.create!(
+ namespace_id: namespace5.id,
+ project_namespace_id: namespace5.id,
+ packages_enabled: true,
+ visibility_level: Gitlab::VisibilityLevel::PUBLIC
+ )
+ end
+
+ let(:project6) do
+ projects.create!(namespace_id: namespace6.id, project_namespace_id: namespace6.id, packages_enabled: false)
+ end
+
+ let!(:project_feature1) do
+ project_features.create!(
+ project_id: project1.id,
+ package_registry_access_level: ProjectFeature::ENABLED,
+ **non_null_project_features
+ )
+ end
+
+ let!(:project_feature2) do
+ project_features.create!(
+ project_id: project2.id,
+ package_registry_access_level: ProjectFeature::ENABLED,
+ **non_null_project_features
+ )
+ end
+
+ let!(:project_feature3) do
+ project_features.create!(
+ project_id: project3.id,
+ package_registry_access_level: ProjectFeature::DISABLED,
+ **non_null_project_features
+ )
+ end
+
+ let!(:project_feature4) do
+ project_features.create!(
+ project_id: project4.id,
+ package_registry_access_level: ProjectFeature::DISABLED,
+ **non_null_project_features
+ )
+ end
+
+ let!(:project_feature5) do
+ project_features.create!(
+ project_id: project5.id,
+ package_registry_access_level: ProjectFeature::DISABLED,
+ **non_null_project_features
+ )
+ end
+
+ let!(:project_feature6) do
+ project_features.create!(
+ project_id: project6.id,
+ package_registry_access_level: ProjectFeature::ENABLED,
+ **non_null_project_features
+ )
+ end
+
+ subject(:perform_migration) do
+ described_class.new(start_id: project1.id,
+ end_id: project5.id,
+ batch_table: :projects,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection)
+ .perform
+ end
+
+ it 'backfills project_features.package_registry_access_level', :aggregate_failures do
+ perform_migration
+
+ expect(project_feature1.reload.package_registry_access_level).to eq(ProjectFeature::DISABLED)
+ expect(project_feature2.reload.package_registry_access_level).to eq(ProjectFeature::DISABLED)
+ expect(project_feature3.reload.package_registry_access_level).to eq(ProjectFeature::PRIVATE)
+ expect(project_feature4.reload.package_registry_access_level).to eq(ProjectFeature::ENABLED)
+ expect(project_feature5.reload.package_registry_access_level).to eq(ProjectFeature::PUBLIC)
+ expect(project_feature6.reload.package_registry_access_level).to eq(ProjectFeature::ENABLED)
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb
new file mode 100644
index 00000000000..ca7ca41a33e
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_project_member_namespace_id_spec.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillProjectMemberNamespaceId, :migration, schema: 20220516054011 do
+ let(:migration) do
+ described_class.new(start_id: 1, end_id: 10,
+ batch_table: table_name, batch_column: batch_column,
+ sub_batch_size: sub_batch_size, pause_ms: pause_ms,
+ connection: ApplicationRecord.connection)
+ end
+
+ let(:members_table) { table(:members) }
+ let(:projects_table) { table(:projects) }
+ let(:namespaces_table) { table(:namespaces) }
+
+ let(:table_name) { 'members' }
+ let(:batch_column) { :id }
+ let(:sub_batch_size) { 100 }
+ let(:pause_ms) { 0 }
+
+ subject(:perform_migration) do
+ migration.perform
+ end
+
+ before do
+ namespaces_table.create!(id: 201, name: 'group1', path: 'group1', type: 'Group')
+ namespaces_table.create!(id: 202, name: 'group2', path: 'group2', type: 'Group')
+ namespaces_table.create!(id: 300, name: 'project-namespace-1', path: 'project-namespace-1-path', type: 'Project')
+ namespaces_table.create!(id: 301, name: 'project-namespace-2', path: 'project-namespace-2-path', type: 'Project')
+ namespaces_table.create!(id: 302, name: 'project-namespace-3', path: 'project-namespace-3-path', type: 'Project')
+
+ projects_table.create!(id: 100, name: 'project1', path: 'project1', namespace_id: 202, project_namespace_id: 300)
+ projects_table.create!(id: 101, name: 'project2', path: 'project2', namespace_id: 202, project_namespace_id: 301)
+ projects_table.create!(id: 102, name: 'project3', path: 'project3', namespace_id: 202, project_namespace_id: 302)
+
+ # project1, no member namespace (fill in)
+ members_table.create!(id: 1, source_id: 100,
+ source_type: 'Project', type: 'ProjectMember',
+ member_namespace_id: nil, access_level: 10, notification_level: 3)
+ # bogus source id, no member namespace id (do nothing)
+ members_table.create!(id: 2, source_id: non_existing_record_id,
+ source_type: 'Project', type: 'ProjectMember',
+ member_namespace_id: nil, access_level: 10, notification_level: 3)
+ # project3, existing member namespace id (do nothing)
+ members_table.create!(id: 3, source_id: 102,
+ source_type: 'Project', type: 'ProjectMember',
+ member_namespace_id: 300, access_level: 10, notification_level: 3)
+
+ # Group memberships (do not change)
+ # group1, no member namespace (do nothing)
+ members_table.create!(id: 4, source_id: 201,
+ source_type: 'Namespace', type: 'GroupMember',
+ member_namespace_id: nil, access_level: 10, notification_level: 3)
+ # group2, existing member namespace (do nothing)
+ members_table.create!(id: 5, source_id: 202,
+ source_type: 'Namespace', type: 'GroupMember',
+ member_namespace_id: 201, access_level: 10, notification_level: 3)
+
+ # Project Namespace memberships (do not change)
+ # project namespace, existing member namespace (do nothing)
+ members_table.create!(id: 6, source_id: 300,
+ source_type: 'Namespace', type: 'ProjectNamespaceMember',
+ member_namespace_id: 201, access_level: 10, notification_level: 3)
+ # project namespace, not member namespace (do nothing)
+ members_table.create!(id: 7, source_id: 301,
+ source_type: 'Namespace', type: 'ProjectNamespaceMember',
+ member_namespace_id: 201, access_level: 10, notification_level: 3)
+ end
+
+ it 'backfills `member_namespace_id` for the selected records', :aggregate_failures do
+ expect(members_table.where(type: 'ProjectMember', member_namespace_id: nil).count).to eq 2
+ expect(members_table.where(type: 'GroupMember', member_namespace_id: nil).count).to eq 1
+
+ queries = ActiveRecord::QueryRecorder.new do
+ perform_migration
+ end
+
+ # rubocop:disable Layout/LineLength
+ expect(queries.count).to eq(3)
+ expect(members_table.where(type: 'ProjectMember', member_namespace_id: nil).count).to eq 1 # just the bogus one
+ expect(members_table.where(type: 'ProjectMember').pluck(:member_namespace_id)).to match_array([nil, 300, 300])
+ expect(members_table.where(type: 'GroupMember', member_namespace_id: nil).count).to eq 1
+ expect(members_table.where(type: 'GroupMember').pluck(:member_namespace_id)).to match_array([nil, 201])
+ # rubocop:enable Layout/LineLength
+ 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
+
+ context 'when given a negative pause_ms' do
+ let(:pause_ms) { -9 }
+ let(:sub_batch_size) { 2 }
+
+ it 'uses 0 as a floor for pause_ms' do
+ expect(migration).to receive(:sleep).with(0)
+
+ perform_migration
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/cleanup_orphaned_routes_spec.rb b/spec/lib/gitlab/background_migration/cleanup_orphaned_routes_spec.rb
new file mode 100644
index 00000000000..a09d5559d33
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/cleanup_orphaned_routes_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# this needs the schema to be before we introduce the not null constraint on routes#namespace_id
+RSpec.describe Gitlab::BackgroundMigration::CleanupOrphanedRoutes, schema: 20220606060825 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:routes) { table(:routes) }
+
+ let!(:namespace1) { namespaces.create!(name: 'batchtest1', type: 'Group', path: 'space1') }
+ let!(:namespace2) { namespaces.create!(name: 'batchtest2', type: 'Group', parent_id: namespace1.id, path: 'space2') }
+ let!(:namespace3) { namespaces.create!(name: 'batchtest3', type: 'Group', parent_id: namespace2.id, path: 'space3') }
+
+ let!(:proj_namespace1) { namespaces.create!(name: 'proj1', path: 'proj1', type: 'Project', parent_id: namespace1.id) }
+ let!(:proj_namespace2) { namespaces.create!(name: 'proj2', path: 'proj2', type: 'Project', parent_id: namespace2.id) }
+ let!(:proj_namespace3) { namespaces.create!(name: 'proj3', path: 'proj3', type: 'Project', parent_id: namespace3.id) }
+
+ # rubocop:disable Layout/LineLength
+ let!(:proj1) { projects.create!(name: 'proj1', path: 'proj1', namespace_id: namespace1.id, project_namespace_id: proj_namespace1.id) }
+ let!(:proj2) { projects.create!(name: 'proj2', path: 'proj2', namespace_id: namespace2.id, project_namespace_id: proj_namespace2.id) }
+ let!(:proj3) { projects.create!(name: 'proj3', path: 'proj3', namespace_id: namespace3.id, project_namespace_id: proj_namespace3.id) }
+
+ # valid namespace routes with not null namespace_id
+ let!(:namespace_route1) { routes.create!(path: 'space1', source_id: namespace1.id, source_type: 'Namespace', namespace_id: namespace1.id) }
+ # valid namespace routes with null namespace_id
+ let!(:namespace_route2) { routes.create!(path: 'space1/space2', source_id: namespace2.id, source_type: 'Namespace') }
+ let!(:namespace_route3) { routes.create!(path: 'space1/space3', source_id: namespace3.id, source_type: 'Namespace') }
+ # invalid/orphaned namespace route
+ let!(:orphaned_namespace_route_a) { routes.create!(path: 'space1/space4', source_id: non_existing_record_id, source_type: 'Namespace') }
+ let!(:orphaned_namespace_route_b) { routes.create!(path: 'space1/space5', source_id: non_existing_record_id - 1, source_type: 'Namespace') }
+
+ # valid project routes with not null namespace_id
+ let!(:proj_route1) { routes.create!(path: 'space1/proj1', source_id: proj1.id, source_type: 'Project', namespace_id: proj_namespace1.id) }
+ # valid project routes with null namespace_id
+ let!(:proj_route2) { routes.create!(path: 'space1/space2/proj2', source_id: proj2.id, source_type: 'Project') }
+ let!(:proj_route3) { routes.create!(path: 'space1/space3/proj3', source_id: proj3.id, source_type: 'Project') }
+ # invalid/orphaned namespace route
+ let!(:orphaned_project_route_a) { routes.create!(path: 'space1/space3/proj5', source_id: non_existing_record_id, source_type: 'Project') }
+ let!(:orphaned_project_route_b) { routes.create!(path: 'space1/space3/proj6', source_id: non_existing_record_id - 1, source_type: 'Project') }
+ # rubocop:enable Layout/LineLength
+
+ let!(:migration_attrs) do
+ {
+ start_id: Route.minimum(:id),
+ end_id: Route.maximum(:id),
+ batch_table: :routes,
+ batch_column: :id,
+ sub_batch_size: 100,
+ pause_ms: 0,
+ connection: ApplicationRecord.connection
+ }
+ end
+
+ let!(:migration) { described_class.new(**migration_attrs) }
+
+ subject(:perform_migration) { migration.perform }
+
+ it 'cleans orphaned routes', :aggregate_failures do
+ all_route_ids = Route.pluck(:id)
+
+ orphaned_route_ids = [
+ orphaned_namespace_route_a, orphaned_namespace_route_b, orphaned_project_route_a, orphaned_project_route_b
+ ].pluck(:id)
+ remaining_routes = (all_route_ids - orphaned_route_ids).sort
+
+ expect { perform_migration }.to change { Route.pluck(:id) }.to contain_exactly(*remaining_routes)
+ expect(Route.all).to all(have_attributes(namespace_id: be_present))
+
+ # expect that routes that had namespace_id set did not change namespace_id
+ expect(namespace_route1.reload.namespace_id).to eq(namespace1.id)
+ expect(proj_route1.reload.namespace_id).to eq(proj_namespace1.id)
+ 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/encrypt_integration_properties_spec.rb b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
index 7334867e8fb..38e8b159e63 100644
--- a/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
+++ b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe Gitlab::BackgroundMigration::EncryptIntegrationProperties do
+RSpec.describe Gitlab::BackgroundMigration::EncryptIntegrationProperties, schema: 20220415124804 do
let(:integrations) do
table(:integrations) do |integrations|
integrations.send :attr_encrypted, :encrypted_properties_tmp,
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
index c343ee438b8..99df21562b0 100644
--- 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
@@ -2,314 +2,23 @@
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
+ it 'does nothing' 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')
+ expect { migration.perform(project.id) }.not_to raise_error
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)
+ expect { migration.perform(-1) }.not_to raise_error
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
diff --git a/spec/lib/gitlab/background_migration/migrate_pages_to_zip_storage_spec.rb b/spec/lib/gitlab/background_migration/migrate_pages_to_zip_storage_spec.rb
deleted file mode 100644
index 557dd8ddee6..00000000000
--- a/spec/lib/gitlab/background_migration/migrate_pages_to_zip_storage_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::MigratePagesToZipStorage do
- let(:namespace) { create(:group) } # rubocop: disable RSpec/FactoriesInMigrationSpecs
- let(:migration) { described_class.new }
-
- describe '#perform' do
- context 'when there is project to migrate' do
- let!(:project) { create_project('project') }
-
- after do
- FileUtils.rm_rf(project.pages_path)
- end
-
- it 'migrates project to zip storage' do
- expect_next_instance_of(::Pages::MigrateFromLegacyStorageService,
- anything,
- ignore_invalid_entries: false,
- mark_projects_as_not_deployed: false) do |service|
- expect(service).to receive(:execute_for_batch).with(project.id..project.id).and_call_original
- end
-
- migration.perform(project.id, project.id)
-
- expect(project.reload.pages_metadatum.pages_deployment.file.filename).to eq("_migrated.zip")
- end
- end
- end
-
- def create_project(path)
- project = create(:project) # rubocop: disable RSpec/FactoriesInMigrationSpecs
- project.mark_pages_as_deployed
-
- FileUtils.mkdir_p File.join(project.pages_path, "public")
- File.open(File.join(project.pages_path, "public/index.html"), "w") do |f|
- f.write("Hello!")
- end
-
- project
- end
-end
diff --git a/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb b/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb
new file mode 100644
index 00000000000..035ea6eadcf
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/set_legacy_open_source_license_available_for_non_public_projects_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::SetLegacyOpenSourceLicenseAvailableForNonPublicProjects,
+ :migration,
+ schema: 20220520040416 do
+ let(:namespaces_table) { table(:namespaces) }
+ let(:projects_table) { table(:projects) }
+ let(:project_settings_table) { table(:project_settings) }
+
+ subject(:perform_migration) do
+ described_class.new(start_id: 1,
+ end_id: 30,
+ batch_table: :projects,
+ batch_column: :id,
+ sub_batch_size: 2,
+ pause_ms: 0,
+ connection: ActiveRecord::Base.connection)
+ .perform
+ end
+
+ let(:queries) { ActiveRecord::QueryRecorder.new { perform_migration } }
+
+ before do
+ namespaces_table.create!(id: 1, name: 'namespace', path: 'namespace-path-1')
+ namespaces_table.create!(id: 2, name: 'namespace', path: 'namespace-path-2', type: 'Project')
+ namespaces_table.create!(id: 3, name: 'namespace', path: 'namespace-path-3', type: 'Project')
+ namespaces_table.create!(id: 4, name: 'namespace', path: 'namespace-path-4', type: 'Project')
+
+ projects_table
+ .create!(id: 11, name: 'proj-1', path: 'path-1', namespace_id: 1, project_namespace_id: 2, visibility_level: 0)
+ projects_table
+ .create!(id: 12, name: 'proj-2', path: 'path-2', namespace_id: 1, project_namespace_id: 3, visibility_level: 10)
+ projects_table
+ .create!(id: 13, name: 'proj-3', path: 'path-3', namespace_id: 1, project_namespace_id: 4, visibility_level: 20)
+
+ project_settings_table.create!(project_id: 11, legacy_open_source_license_available: true)
+ project_settings_table.create!(project_id: 12, legacy_open_source_license_available: true)
+ project_settings_table.create!(project_id: 13, legacy_open_source_license_available: true)
+ end
+
+ it 'sets `legacy_open_source_license_available` attribute to false for non-public projects', :aggregate_failures do
+ expect(queries.count).to eq(3)
+
+ expect(migrated_attribute(11)).to be_falsey
+ expect(migrated_attribute(12)).to be_falsey
+ expect(migrated_attribute(13)).to be_truthy
+ end
+
+ def migrated_attribute(project_id)
+ project_settings_table.find(project_id).legacy_open_source_license_available
+ end
+end