diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2019-04-29 15:16:03 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2019-06-17 18:09:05 +0300 |
commit | 8469f59d786be6762908f62d642625790999cb9b (patch) | |
tree | 03f99c605e465673e017e775a623ffa5b62f18d3 /spec/migrations | |
parent | 0f777a8d49568d3f5ffdd4b75b594f07e9fbd2f0 (diff) |
Backport the EE schema and migrations to CE
This backports all EE schema changes to CE, including EE migrations,
ensuring both use the same schema.
== Updated tests
A spec related to ghost and support bot users had to be modified to make
it pass. The spec in question assumes that the "support_bot" column
exists when defining the spec. In the single codebase setup this is not
the case, as the column is backported in a later migration. Any attempt
to use a different schema version or use of "around" blocks to
conditionally disable specs won't help, as reverting the backport
migration would also drop the "support_bot" column. Removing the
"support_bot" tests entirely appears to be the only solution.
We also need to update some foreign key tests now that we have
backported the EE columns. Fortunately, these changes are very minor.
== Backporting migrations
This commit moves EE specific migrations (except those for the Geo
tracking database) and related files to CE, and also removes any traces
of the ee/db directory.
Some migrations had to be modified or removed, as they no longer work
with the schema being backported. These migrations were all quite old,
so we opted for removing them where modifying them would take too much
time and effort.
Some old migrations were modified in EE, while also existing in CE. In
these cases we took the EE code, and in one case removed them entirely.
It's not worth spending time trying to merge these changes somehow as we
plan to remove old migrations around the release of 12.0, see
https://gitlab.com/gitlab-org/gitlab-ce/issues/59177 for more details.
Diffstat (limited to 'spec/migrations')
20 files changed, 168 insertions, 799 deletions
diff --git a/spec/migrations/active_record/schema_spec.rb b/spec/migrations/active_record/schema_spec.rb index 9d35b3cd642..fbf5d387d0e 100644 --- a/spec/migrations/active_record/schema_spec.rb +++ b/spec/migrations/active_record/schema_spec.rb @@ -5,8 +5,7 @@ require 'spec_helper' describe ActiveRecord::Schema do let(:latest_migration_timestamp) do - migrations_paths = %w[db ee/db] - .product(%w[migrate post_migrate]) + migrations_paths = %w[db/migrate db/post_migrate] .map { |path| Rails.root.join(*path, '*') } migrations = Dir[*migrations_paths] diff --git a/spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb b/spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb new file mode 100644 index 00000000000..cad10ba30ef --- /dev/null +++ b/spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20190404143330_add_unique_constraint_to_approvals_user_id_and_merge_request_id.rb') + +describe AddUniqueConstraintToApprovalsUserIdAndMergeRequestId, :migration do + let(:migration) { described_class.new } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:merge_requests) { table(:merge_requests) } + let(:approvals) { table(:approvals) } + + describe '#up' do + before do + namespaces.create(id: 1, name: 'ns', path: 'ns') + projects.create(id: 1, namespace_id: 1) + merge_requests.create(id: 1, target_branch: 'master', source_branch: 'feature-1', target_project_id: 1) + merge_requests.create(id: 2, target_branch: 'master', source_branch: 'feature-2', target_project_id: 1) + end + + it 'deletes duplicate records and keeps the first one' do + first_approval = approvals.create(id: 1, merge_request_id: 1, user_id: 1) + approvals.create(id: 2, merge_request_id: 1, user_id: 1) + + migration.up + + expect(approvals.all.to_a).to contain_exactly(first_approval) + end + + it 'does not delete unique records' do + unique_approvals = [ + approvals.create(id: 1, merge_request_id: 1, user_id: 1), + approvals.create(id: 2, merge_request_id: 1, user_id: 2), + approvals.create(id: 3, merge_request_id: 2, user_id: 1) + ] + + migration.up + + expect(approvals.all.to_a).to contain_exactly(*unique_approvals) + end + + it 'creates unique index' do + migration.up + + expect(migration.index_exists?(:approvals, [:user_id, :merge_request_id], unique: true)).to be_truthy + end + end + + describe '#down' do + it 'removes unique index' do + migration.up + migration.down + + expect(migration.index_exists?(:approvals, [:user_id, :merge_request_id], unique: true)).to be_falsey + end + end +end diff --git a/spec/migrations/clean_up_for_members_spec.rb b/spec/migrations/clean_up_for_members_spec.rb deleted file mode 100644 index 1a79f94cf0d..00000000000 --- a/spec/migrations/clean_up_for_members_spec.rb +++ /dev/null @@ -1,83 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20171216111734_clean_up_for_members.rb') - -describe CleanUpForMembers, :migration do - before do - stub_feature_flags(enforced_sso: false) - end - - let(:migration) { described_class.new } - let(:groups) { table(:namespaces) } - let!(:group_member) { create_group_member } - let!(:unbinded_group_member) { create_group_member } - let!(:invited_group_member) { create_group_member(true) } - let!(:not_valid_group_member) { create_group_member } - let!(:project_member) { create_project_member } - let!(:invited_project_member) { create_project_member(true) } - let!(:unbinded_project_member) { create_project_member } - let!(:not_valid_project_member) { create_project_member } - - it 'removes members without proper user_id' do - unbinded_group_member.update_column(:user_id, nil) - not_valid_group_member.update_column(:user_id, 9999) - unbinded_project_member.update_column(:user_id, nil) - not_valid_project_member.update_column(:user_id, 9999) - - migrate! - - expect(Member.all).not_to include(unbinded_group_member, not_valid_group_member, unbinded_project_member, not_valid_project_member) - expect(Member.all).to include(group_member, invited_group_member, project_member, invited_project_member) - end - - def create_group_member(invited = false) - fill_member(GroupMember.new(source_id: create_group.id, source_type: 'Namespace'), invited) - end - - def create_project_member(invited = false) - fill_member(ProjectMember.new(project: create_project), invited) - end - - def fill_member(member_object, invited) - member_object.tap do |m| - m.access_level = 40 - m.notification_level = 3 - - if invited - m.user_id = nil - m.invite_token = 'xxx' - m.invite_email = 'email@email.com' - else - m.user_id = create_user.id - end - - m.save - end - - member_object - end - - def create_group - name = FFaker::Lorem.characters(10) - - groups.create!(type: 'Group', name: name, path: name.downcase.gsub(/\s/, '_')) - end - - def create_project - name = FFaker::Lorem.characters(10) - creator = create_user - - Project.create(name: name, - path: name.downcase.gsub(/\s/, '_'), - namespace: creator.namespace, - creator: creator) - end - - def create_user - User.create(email: FFaker::Internet.email, - password: '12345678', - name: FFaker::Name.name, - username: FFaker::Internet.user_name, - confirmed_at: Time.now, - confirmation_token: nil) - end -end diff --git a/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb b/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb deleted file mode 100644 index 651341906c2..00000000000 --- a/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20170502101023_cleanup_namespaceless_pending_delete_projects.rb') - -describe CleanupNamespacelessPendingDeleteProjects, :migration, schema: 20180222043024 do - let(:projects) { table(:projects) } - - before do - # Stub after_save callbacks that will fail when Project has no namespace - allow_any_instance_of(Project).to receive(:ensure_storage_path_exists).and_return(nil) - allow_any_instance_of(Project).to receive(:update_project_statistics).and_return(nil) - end - - describe '#up' do - it 'only cleans up pending delete projects' do - projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: 1) - projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ee', namespace_id: 2, pending_delete: true) - project = Project.new(pending_delete: true, namespace_id: nil) - project.save(validate: false) - - expect(NamespacelessProjectDestroyWorker).to receive(:bulk_perform_async).with([[project.id]]) - - described_class.new.up - end - - it 'does nothing when no pending delete projects without namespace found' do - projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: 1) - projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ee', namespace_id: 2, pending_delete: true) - - expect(NamespacelessProjectDestroyWorker).not_to receive(:bulk_perform_async) - - described_class.new.up - end - end -end diff --git a/spec/migrations/create_missing_namespace_for_internal_users_spec.rb b/spec/migrations/create_missing_namespace_for_internal_users_spec.rb index ac3a4b1f68f..3fd4c5bc8d6 100644 --- a/spec/migrations/create_missing_namespace_for_internal_users_spec.rb +++ b/spec/migrations/create_missing_namespace_for_internal_users_spec.rb @@ -6,37 +6,32 @@ describe CreateMissingNamespaceForInternalUsers, :migration do let(:namespaces) { table(:namespaces) } let(:routes) { table(:routes) } - internal_user_types = [:ghost] - internal_user_types << :support_bot if ActiveRecord::Base.connection.column_exists?(:users, :support_bot) - - internal_user_types.each do |attr| - context "for #{attr} user" do - let(:internal_user) do - users.create!(email: 'test@example.com', projects_limit: 100, username: 'test', attr => true) - end + context "for ghost user" do + let(:internal_user) do + users.create!(email: 'test@example.com', projects_limit: 100, username: 'test', ghost: true) + end - it 'creates the missing namespace' do - expect(namespaces.find_by(owner_id: internal_user.id)).to be_nil + it 'creates the missing namespace' do + expect(namespaces.find_by(owner_id: internal_user.id)).to be_nil - migrate! + migrate! - namespace = Namespace.find_by(type: nil, owner_id: internal_user.id) - route = namespace.route + namespace = Namespace.find_by(type: nil, owner_id: internal_user.id) + route = namespace.route - expect(namespace.path).to eq(route.path) - expect(namespace.name).to eq(route.name) - end + expect(namespace.path).to eq(route.path) + expect(namespace.name).to eq(route.name) + end - it 'sets notification email' do - users.update(internal_user.id, notification_email: nil) + it 'sets notification email' do + users.update(internal_user.id, notification_email: nil) - expect(users.find(internal_user.id).notification_email).to be_nil + expect(users.find(internal_user.id).notification_email).to be_nil - migrate! + migrate! - user = users.find(internal_user.id) - expect(user.notification_email).to eq(user.email) - end + user = users.find(internal_user.id) + expect(user.notification_email).to eq(user.email) end end end diff --git a/spec/migrations/delete_inconsistent_internal_id_records_spec.rb b/spec/migrations/delete_inconsistent_internal_id_records_spec.rb deleted file mode 100644 index 58b8b4a16f0..00000000000 --- a/spec/migrations/delete_inconsistent_internal_id_records_spec.rb +++ /dev/null @@ -1,161 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180723130817_delete_inconsistent_internal_id_records.rb') - -describe DeleteInconsistentInternalIdRecords, :migration do - let!(:namespace) { table(:namespaces).create!(name: 'test', path: 'test') } - let!(:project1) { table(:projects).create!(namespace_id: namespace.id) } - let!(:project2) { table(:projects).create!(namespace_id: namespace.id) } - let!(:project3) { table(:projects).create!(namespace_id: namespace.id) } - - let(:internal_ids) { table(:internal_ids) } - let(:internal_id_query) { ->(project) { InternalId.where(usage: InternalId.usages[scope.to_s.tableize], project_id: project.id) } } - - let(:create_models) do - [project1, project2, project3].each do |project| - 3.times do |i| - attributes = required_attributes.merge(project_id: project.id, - iid: i.succ) - - table(scope.to_s.pluralize).create!(attributes) - end - end - end - - shared_examples_for 'deleting inconsistent internal_id records' do - before do - create_models - - [project1, project2, project3].each do |project| - internal_ids.create!(project_id: project.id, usage: InternalId.usages[scope.to_s.tableize], last_value: 3) - end - - internal_id_query.call(project1).first.tap do |iid| - iid.last_value = iid.last_value - 2 - # This is an inconsistent record - iid.save! - end - - internal_id_query.call(project3).first.tap do |iid| - iid.last_value = iid.last_value + 2 - # This is a consistent record - iid.save! - end - end - - it "deletes inconsistent records" do - expect { migrate! }.to change { internal_id_query.call(project1).size }.from(1).to(0) - end - - it "retains consistent records" do - expect { migrate! }.not_to change { internal_id_query.call(project2).size } - end - - it "retains consistent records, especially those with a greater last_value" do - expect { migrate! }.not_to change { internal_id_query.call(project3).size } - end - end - - context 'for issues' do - let(:scope) { :issue } - let(:required_attributes) { {} } - - it_behaves_like 'deleting inconsistent internal_id records' - end - - context 'for merge_requests' do - let(:scope) { :merge_request } - - let(:create_models) do - [project1, project2, project3].each do |project| - 3.times do |i| - table(:merge_requests).create!( - target_project_id: project.id, - source_project_id: project.id, - target_branch: 'master', - source_branch: j.to_s, - iid: i.succ - ) - end - end - end - - it_behaves_like 'deleting inconsistent internal_id records' - end - - context 'for deployments' do - let(:scope) { :deployment } - let(:deployments) { table(:deployments) } - - let(:create_models) do - 3.times { |i| deployments.create!(project_id: project1.id, iid: i, environment_id: 1, ref: 'master', sha: 'a', tag: false) } - 3.times { |i| deployments.create!(project_id: project2.id, iid: i, environment_id: 1, ref: 'master', sha: 'a', tag: false) } - 3.times { |i| deployments.create!(project_id: project3.id, iid: i, environment_id: 1, ref: 'master', sha: 'a', tag: false) } - end - - it_behaves_like 'deleting inconsistent internal_id records' - end - - context 'for milestones (by project)' do - let(:scope) { :milestone } - let(:required_attributes) { { title: 'test' } } - - it_behaves_like 'deleting inconsistent internal_id records' - end - - context 'for ci_pipelines' do - let(:scope) { :ci_pipeline } - let(:required_attributes) { { ref: 'test' } } - - it_behaves_like 'deleting inconsistent internal_id records' - end - - context 'for milestones (by group)' do - # milestones (by group) is a little different than most of the other models - let(:groups) { table(:namespaces) } - let(:group1) { groups.create(name: 'Group 1', type: 'Group', path: 'group_1') } - let(:group2) { groups.create(name: 'Group 2', type: 'Group', path: 'group_2') } - let(:group3) { groups.create(name: 'Group 2', type: 'Group', path: 'group_3') } - - let(:internal_id_query) { ->(group) { InternalId.where(usage: InternalId.usages['milestones'], namespace_id: group.id) } } - - before do - [group1, group2, group3].each do |group| - 3.times do |i| - table(:milestones).create!( - group_id: group.id, - title: 'test', - iid: i.succ - ) - end - - internal_ids.create!(namespace_id: group.id, usage: InternalId.usages['milestones'], last_value: 3) - end - - internal_id_query.call(group1).first.tap do |iid| - iid.last_value = iid.last_value - 2 - # This is an inconsistent record - iid.save! - end - - internal_id_query.call(group3).first.tap do |iid| - iid.last_value = iid.last_value + 2 - # This is a consistent record - iid.save! - end - end - - it "deletes inconsistent records" do - expect { migrate! }.to change { internal_id_query.call(group1).size }.from(1).to(0) - end - - it "retains consistent records" do - expect { migrate! }.not_to change { internal_id_query.call(group2).size } - end - - it "retains consistent records, especially those with a greater last_value" do - expect { migrate! }.not_to change { internal_id_query.call(group3).size } - end - end -end diff --git a/spec/migrations/enqueue_delete_diff_files_workers_spec.rb b/spec/migrations/enqueue_delete_diff_files_workers_spec.rb deleted file mode 100644 index 6bae870920c..00000000000 --- a/spec/migrations/enqueue_delete_diff_files_workers_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180619121030_enqueue_delete_diff_files_workers.rb') - -describe EnqueueDeleteDiffFilesWorkers, :migration, :sidekiq do - it 'correctly schedules diff files deletion schedulers' do - Sidekiq::Testing.fake! do - expect(BackgroundMigrationWorker) - .to receive(:perform_async) - .with(described_class::SCHEDULER) - .and_call_original - - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq(1) - end - end -end diff --git a/spec/migrations/enqueue_redact_links_spec.rb b/spec/migrations/enqueue_redact_links_spec.rb deleted file mode 100644 index a5da76977b7..00000000000 --- a/spec/migrations/enqueue_redact_links_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181014121030_enqueue_redact_links.rb') - -describe EnqueueRedactLinks, :migration, :sidekiq do - let(:merge_requests) { table(:merge_requests) } - let(:issues) { table(:issues) } - let(:notes) { table(:notes) } - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - let(:snippets) { table(:snippets) } - let(:users) { table(:users) } - let(:user) { users.create!(email: 'test@example.com', projects_limit: 100, username: 'test') } - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 1) - - text = 'some text /sent_notifications/00000000000000000000000000000000/unsubscribe more text' - group = namespaces.create!(name: 'gitlab', path: 'gitlab') - project = projects.create!(namespace_id: group.id) - - merge_requests.create!(id: 1, target_project_id: project.id, source_project_id: project.id, target_branch: 'feature', source_branch: 'master', description: text) - issues.create!(id: 1, description: text) - notes.create!(id: 1, note: text) - notes.create!(id: 2, note: text) - snippets.create!(id: 1, description: text, author_id: user.id) - end - - it 'correctly schedules background migrations' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, "Note", "note", 1, 1) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, "Note", "note", 2, 2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, "Issue", "description", 1, 1) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, "MergeRequest", "description", 1, 1) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, "Snippet", "description", 1, 1) - expect(BackgroundMigrationWorker.jobs.size).to eq 5 - end - end - end -end diff --git a/spec/migrations/migrate_import_attributes_data_from_projects_to_project_mirror_data_spec.rb b/spec/migrations/migrate_import_attributes_data_from_projects_to_project_mirror_data_spec.rb deleted file mode 100644 index 972c6dffc6f..00000000000 --- a/spec/migrations/migrate_import_attributes_data_from_projects_to_project_mirror_data_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180502134117_migrate_import_attributes_data_from_projects_to_project_mirror_data.rb') - -describe MigrateImportAttributesDataFromProjectsToProjectMirrorData, :sidekiq, :migration do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:import_state) { table(:project_mirror_data) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - namespaces.create(id: 1, name: 'gitlab-org', path: 'gitlab-org') - - projects.create!(id: 1, namespace_id: 1, name: 'gitlab1', - path: 'gitlab1', import_error: "foo", import_status: :started, - import_url: generate(:url)) - projects.create!(id: 2, namespace_id: 1, name: 'gitlab2', - path: 'gitlab2', import_error: "bar", import_status: :failed, - import_url: generate(:url)) - projects.create!(id: 3, namespace_id: 1, name: 'gitlab3', path: 'gitlab3', import_status: :none, import_url: generate(:url)) - end - - it 'schedules delayed background migrations in batches in bulk' do - Sidekiq::Testing.fake! do - Timecop.freeze do - expect(projects.where.not(import_status: :none).count).to eq(2) - - subject.up - - expect(BackgroundMigrationWorker.jobs.size).to eq 2 - expect(described_class::UP_MIGRATION).to be_scheduled_delayed_migration(5.minutes, 1, 1) - expect(described_class::UP_MIGRATION).to be_scheduled_delayed_migration(10.minutes, 2, 2) - end - end - end - - describe '#down' do - before do - import_state.create!(id: 1, project_id: 1, status: :started) - import_state.create!(id: 2, project_id: 2, status: :started) - end - - it 'schedules delayed background migrations in batches in bulk for rollback' do - Sidekiq::Testing.fake! do - Timecop.freeze do - expect(import_state.where.not(status: :none).count).to eq(2) - - subject.down - - expect(BackgroundMigrationWorker.jobs.size).to eq 2 - expect(described_class::DOWN_MIGRATION).to be_scheduled_delayed_migration(5.minutes, 1, 1) - expect(described_class::DOWN_MIGRATION).to be_scheduled_delayed_migration(10.minutes, 2, 2) - end - end - end - end -end diff --git a/spec/migrations/migrate_remaining_mr_metrics_populating_background_migration_spec.rb b/spec/migrations/migrate_remaining_mr_metrics_populating_background_migration_spec.rb deleted file mode 100644 index 47dab18183c..00000000000 --- a/spec/migrations/migrate_remaining_mr_metrics_populating_background_migration_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180521162137_migrate_remaining_mr_metrics_populating_background_migration.rb') - -describe MigrateRemainingMrMetricsPopulatingBackgroundMigration, :migration, :sidekiq do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:mrs) { table(:merge_requests) } - - before do - namespaces.create!(id: 1, name: 'foo', path: 'foo') - projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 1) - projects.create!(id: 456, name: 'gitlab2', path: 'gitlab2', namespace_id: 1) - projects.create!(id: 789, name: 'gitlab3', path: 'gitlab3', namespace_id: 1) - mrs.create!(title: 'foo', target_branch: 'target', source_branch: 'source', target_project_id: 123) - mrs.create!(title: 'bar', target_branch: 'target', source_branch: 'source', target_project_id: 456) - mrs.create!(title: 'kux', target_branch: 'target', source_branch: 'source', target_project_id: 789) - end - - it 'correctly schedules background migrations' do - stub_const("#{described_class.name}::BATCH_SIZE", 2) - - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(10.minutes, mrs.first.id, mrs.second.id) - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(20.minutes, mrs.third.id, mrs.third.id) - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - end - end - end -end diff --git a/spec/migrations/populate_mr_metrics_with_events_data_spec.rb b/spec/migrations/populate_mr_metrics_with_events_data_spec.rb deleted file mode 100644 index 291a52b904d..00000000000 --- a/spec/migrations/populate_mr_metrics_with_events_data_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181204154019_populate_mr_metrics_with_events_data.rb') - -describe PopulateMrMetricsWithEventsData, :migration, :sidekiq do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab-org') } - let(:project) { projects.create(namespace_id: namespace.id, name: 'foo') } - let(:merge_requests) { table(:merge_requests) } - - def create_merge_request(id) - params = { - id: id, - target_project_id: project.id, - target_branch: 'master', - source_project_id: project.id, - source_branch: 'mr name', - title: "mr name#{id}" - } - - merge_requests.create!(params) - end - - it 'correctly schedules background migrations' do - create_merge_request(1) - create_merge_request(2) - create_merge_request(3) - - stub_const("#{described_class.name}::BATCH_SIZE", 2) - - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(8.minutes, 1, 2) - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(16.minutes, 3, 3) - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - end - end - end -end diff --git a/spec/migrations/populate_project_statistics_packages_size_spec.rb b/spec/migrations/populate_project_statistics_packages_size_spec.rb new file mode 100644 index 00000000000..4ad91342f25 --- /dev/null +++ b/spec/migrations/populate_project_statistics_packages_size_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20190418132125_populate_project_statistics_packages_size.rb') + +describe PopulateProjectStatisticsPackagesSize, :migration do + let(:project_statistics) { table(:project_statistics) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:packages) { table(:packages_packages) } + let(:package_files) { table(:packages_package_files) } + + let(:file_size) { 1.kilobyte } + let(:repo_size) { 2.megabytes } + let(:lfs_size) { 3.gigabytes } + let(:artifacts_size) { 4.terabytes } + let(:storage_size) { repo_size + lfs_size + artifacts_size } + + let(:namespace) { namespaces.create(name: 'foo', path: 'foo') } + let(:package) { packages.create!(project_id: project.id, name: 'a package', package_type: 1) } + let(:project) { projects.create!(namespace_id: namespace.id) } + + let!(:statistics) { project_statistics.create!(project_id: project.id, namespace_id: namespace.id, storage_size: storage_size, repository_size: repo_size, lfs_objects_size: lfs_size, build_artifacts_size: artifacts_size) } + let!(:package_file) { package_files.create!(package_id: package.id, file: 'a file.txt', file_name: 'a file.txt', size: file_size)} + + it 'backfills ProjectStatistics packages_size' do + expect { migrate! } + .to change { statistics.reload.packages_size } + .from(nil).to(file_size) + end + + it 'updates ProjectStatistics storage_size' do + expect { migrate! } + .to change { statistics.reload.storage_size } + .by(file_size) + end +end diff --git a/spec/migrations/populate_rule_type_on_approval_merge_request_rules_spec.rb b/spec/migrations/populate_rule_type_on_approval_merge_request_rules_spec.rb new file mode 100644 index 00000000000..99dfb165173 --- /dev/null +++ b/spec/migrations/populate_rule_type_on_approval_merge_request_rules_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20190520201748_populate_rule_type_on_approval_merge_request_rules.rb') + +describe PopulateRuleTypeOnApprovalMergeRequestRules, :migration do + let(:migration) { described_class.new } + + describe '#up' do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:merge_requests) { table(:merge_requests) } + let(:approval_rules) { table(:approval_merge_request_rules) } + + # We use integers here since at the time of writing CE does not yet have the + # appropriate models and enum definitions. + let(:regular_rule_type) { 1 } + let(:code_owner_rule_type) { 2 } + + before do + namespaces.create!(id: 11, name: 'gitlab', path: 'gitlab') + projects.create!(id: 101, namespace_id: 11, name: 'gitlab', path: 'gitlab') + merge_requests.create!(id: 1, target_project_id: 101, source_project_id: 101, target_branch: 'feature', source_branch: 'master') + + approval_rules.create!(id: 1, merge_request_id: 1, name: "Default", code_owner: false, rule_type: regular_rule_type) + approval_rules.create!(id: 2, merge_request_id: 1, name: "Code Owners", code_owner: true, rule_type: regular_rule_type) + end + + it 'backfills ApprovalMergeRequestRules code_owner rule_type' do + expect(approval_rules.where(rule_type: regular_rule_type).pluck(:id)).to contain_exactly(1, 2) + expect(approval_rules.where(rule_type: code_owner_rule_type).pluck(:id)).to be_empty + + migrate! + + expect(approval_rules.where(rule_type: regular_rule_type).pluck(:id)).to contain_exactly(1) + expect(approval_rules.where(rule_type: code_owner_rule_type).pluck(:id)).to contain_exactly(2) + end + end +end diff --git a/spec/migrations/remove_orphaned_label_links_spec.rb b/spec/migrations/remove_orphaned_label_links_spec.rb deleted file mode 100644 index e8c44c141c3..00000000000 --- a/spec/migrations/remove_orphaned_label_links_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180906051323_remove_orphaned_label_links.rb') - -describe RemoveOrphanedLabelLinks, :migration do - let(:label_links) { table(:label_links) } - let(:labels) { table(:labels) } - - let(:project) { create(:project) } # rubocop:disable RSpec/FactoriesInMigrationSpecs - let(:label) { create_label } - - before do - # This migration was created before we introduced ProjectCiCdSetting#default_git_depth - allow_any_instance_of(ProjectCiCdSetting).to receive(:default_git_depth).and_return(nil) - allow_any_instance_of(ProjectCiCdSetting).to receive(:default_git_depth=).and_return(0) - end - - context 'add foreign key on label_id' do - let!(:label_link_with_label) { create_label_link(label_id: label.id) } - let!(:label_link_without_label) { create_label_link(label_id: nil) } - - it 'removes orphaned labels without corresponding label' do - expect { migrate! }.to change { LabelLink.count }.from(2).to(1) - end - - it 'does not remove entries with valid label_id' do - expect { migrate! }.not_to change { label_link_with_label.reload } - end - end - - def create_label(**opts) - labels.create!( - project_id: project.id, - **opts - ) - end - - def create_label_link(**opts) - label_links.create!( - target_id: 1, - target_type: 'Issue', - **opts - ) - end -end diff --git a/spec/migrations/remove_soft_removed_objects_spec.rb b/spec/migrations/remove_soft_removed_objects_spec.rb deleted file mode 100644 index d0bde98b80e..00000000000 --- a/spec/migrations/remove_soft_removed_objects_spec.rb +++ /dev/null @@ -1,99 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20171207150343_remove_soft_removed_objects.rb') - -describe RemoveSoftRemovedObjects, :migration do - describe '#up' do - let!(:groups) do - table(:namespaces).tap do |t| - t.inheritance_column = nil - end - end - - let!(:routes) do - table(:routes).tap do |t| - t.inheritance_column = nil - end - end - - it 'removes various soft removed objects' do - 5.times do - create_with_deleted_at(:issue) - end - - regular_issue = create(:issue) # rubocop:disable RSpec/FactoriesInMigrationSpecs - - run_migration - - expect(Issue.count).to eq(1) - expect(Issue.first).to eq(regular_issue) - end - - it 'removes the temporary indexes once soft removed data has been removed' do - migration = described_class.new - - run_migration - - disable_migrations_output do - expect(migration.temporary_index_exists?(Issue)).to eq(false) - end - end - - it 'removes routes of soft removed personal namespaces' do - namespace = create_with_deleted_at(:namespace) - group = groups.create!(name: 'group', path: 'group_path', type: 'Group') - routes.create!(source_id: group.id, source_type: 'Group', name: 'group', path: 'group_path') - - expect(routes.where(source_id: namespace.id).exists?).to eq(true) - expect(routes.where(source_id: group.id).exists?).to eq(true) - - run_migration - - expect(routes.where(source_id: namespace.id).exists?).to eq(false) - expect(routes.where(source_id: group.id).exists?).to eq(true) - end - - it 'schedules the removal of soft removed groups' do - group = create_deleted_group - admin = create(:user, admin: true) # rubocop:disable RSpec/FactoriesInMigrationSpecs - - expect_any_instance_of(GroupDestroyWorker) - .to receive(:perform) - .with(group.id, admin.id) - - run_migration - end - - it 'does not remove soft removed groups when no admin user could be found' do - create_deleted_group - - expect_any_instance_of(GroupDestroyWorker) - .not_to receive(:perform) - - run_migration - end - end - - def run_migration - disable_migrations_output do - migrate! - end - end - - def create_with_deleted_at(*args) - row = create(*args) # rubocop:disable RSpec/FactoriesInMigrationSpecs - - # We set "deleted_at" this way so we don't run into any column cache issues. - row.class.where(id: row.id).update_all(deleted_at: 1.year.ago) - - row - end - - def create_deleted_group - group = groups.create!(name: 'group', path: 'group_path', type: 'Group') - routes.create!(source_id: group.id, source_type: 'Group', name: 'group', path: 'group_path') - - groups.where(id: group.id).update_all(deleted_at: 1.year.ago) - - group - end -end diff --git a/spec/migrations/schedule_create_gpg_key_subkeys_from_gpg_keys_spec.rb b/spec/migrations/schedule_create_gpg_key_subkeys_from_gpg_keys_spec.rb deleted file mode 100644 index c4427910518..00000000000 --- a/spec/migrations/schedule_create_gpg_key_subkeys_from_gpg_keys_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20171005130944_schedule_create_gpg_key_subkeys_from_gpg_keys') - -describe ScheduleCreateGpgKeySubkeysFromGpgKeys, :migration, :sidekiq do - before do - create(:gpg_key, id: 1, key: GpgHelpers::User1.public_key) # rubocop:disable RSpec/FactoriesInMigrationSpecs - create(:gpg_key, id: 2, key: GpgHelpers::User3.public_key) # rubocop:disable RSpec/FactoriesInMigrationSpecs - # Delete all subkeys so they can be recreated - GpgKeySubkey.destroy_all # rubocop: disable DestroyAll - end - - it 'correctly schedules background migrations' do - Sidekiq::Testing.fake! do - migrate! - - expect(described_class::MIGRATION).to be_scheduled_migration(1) - expect(described_class::MIGRATION).to be_scheduled_migration(2) - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - end - end - - it 'schedules background migrations' do - perform_enqueued_jobs do - expect(GpgKeySubkey.count).to eq(0) - - migrate! - - expect(GpgKeySubkey.count).to eq(3) - end - end -end diff --git a/spec/migrations/schedule_merge_request_assignees_migration_progress_check_spec.rb b/spec/migrations/schedule_merge_request_assignees_migration_progress_check_spec.rb new file mode 100644 index 00000000000..bea985fabb1 --- /dev/null +++ b/spec/migrations/schedule_merge_request_assignees_migration_progress_check_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20190402224749_schedule_merge_request_assignees_migration_progress_check.rb') + +describe ScheduleMergeRequestAssigneesMigrationProgressCheck do + describe '#up' do + it 'schedules MergeRequestAssigneesMigrationProgressCheck background job' do + expect(BackgroundMigrationWorker).to receive(:perform_async) + .with(described_class::MIGRATION) + .and_call_original + + subject.up + end + end +end diff --git a/spec/migrations/schedule_merge_request_diff_migrations_spec.rb b/spec/migrations/schedule_merge_request_diff_migrations_spec.rb deleted file mode 100644 index 9f7e47bae0d..00000000000 --- a/spec/migrations/schedule_merge_request_diff_migrations_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20170703130158_schedule_merge_request_diff_migrations') - -describe ScheduleMergeRequestDiffMigrations, :migration, :sidekiq do - let(:merge_request_diffs) { table(:merge_request_diffs) } - let(:merge_requests) { table(:merge_requests) } - let(:projects) { table(:projects) } - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 1) - - projects.create!(id: 1, name: 'gitlab', path: 'gitlab') - - merge_requests.create!(id: 1, target_project_id: 1, source_project_id: 1, target_branch: 'feature', source_branch: 'master') - - merge_request_diffs.create!(id: 1, merge_request_id: 1, st_commits: YAML.dump([]), st_diffs: nil) - merge_request_diffs.create!(id: 2, merge_request_id: 1, st_commits: nil, st_diffs: YAML.dump([])) - merge_request_diffs.create!(id: 3, merge_request_id: 1, st_commits: nil, st_diffs: nil) - merge_request_diffs.create!(id: 4, merge_request_id: 1, st_commits: YAML.dump([]), st_diffs: YAML.dump([])) - end - - it 'correctly schedules background migrations' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 1, 1) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 2, 2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(15.minutes, 4, 4) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 - end - end - end - - it 'schedules background migrations' do - perform_enqueued_jobs do - non_empty = 'st_commits IS NOT NULL OR st_diffs IS NOT NULL' - - expect(merge_request_diffs.where(non_empty).count).to eq 3 - - migrate! - - expect(merge_request_diffs.where(non_empty).count).to eq 0 - end - end -end diff --git a/spec/migrations/schedule_merge_request_diff_migrations_take_two_spec.rb b/spec/migrations/schedule_merge_request_diff_migrations_take_two_spec.rb deleted file mode 100644 index 5bcb923af7b..00000000000 --- a/spec/migrations/schedule_merge_request_diff_migrations_take_two_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20170926150348_schedule_merge_request_diff_migrations_take_two') - -describe ScheduleMergeRequestDiffMigrationsTakeTwo, :migration, :sidekiq do - let(:merge_request_diffs) { table(:merge_request_diffs) } - let(:merge_requests) { table(:merge_requests) } - let(:projects) { table(:projects) } - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 1) - - projects.create!(id: 1, name: 'gitlab', path: 'gitlab') - - merge_requests.create!(id: 1, target_project_id: 1, source_project_id: 1, target_branch: 'feature', source_branch: 'master') - - merge_request_diffs.create!(id: 1, merge_request_id: 1, st_commits: YAML.dump([]), st_diffs: nil) - merge_request_diffs.create!(id: 2, merge_request_id: 1, st_commits: nil, st_diffs: YAML.dump([])) - merge_request_diffs.create!(id: 3, merge_request_id: 1, st_commits: nil, st_diffs: nil) - merge_request_diffs.create!(id: 4, merge_request_id: 1, st_commits: YAML.dump([]), st_diffs: YAML.dump([])) - end - - it 'correctly schedules background migrations' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 1, 1) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(20.minutes, 2, 2) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(30.minutes, 4, 4) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 - end - end - end - - it 'migrates the data' do - perform_enqueued_jobs do - non_empty = 'st_commits IS NOT NULL OR st_diffs IS NOT NULL' - - expect(merge_request_diffs.where(non_empty).count).to eq 3 - - migrate! - - expect(merge_request_diffs.where(non_empty).count).to eq 0 - end - end -end diff --git a/spec/migrations/schedule_populate_merge_request_metrics_with_events_data_spec.rb b/spec/migrations/schedule_populate_merge_request_metrics_with_events_data_spec.rb deleted file mode 100644 index 578440cba20..00000000000 --- a/spec/migrations/schedule_populate_merge_request_metrics_with_events_data_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20171128214150_schedule_populate_merge_request_metrics_with_events_data.rb') - -describe SchedulePopulateMergeRequestMetricsWithEventsData, :migration, :sidekiq do - # commits_count attribute is added in a next migration - before do - allow_any_instance_of(MergeRequestDiff) - .to receive(:commits_count=).and_return(nil) - end - - let!(:mrs) { create_list(:merge_request, 3) } # rubocop:disable RSpec/FactoriesInMigrationSpecs - - it 'correctly schedules background migrations' do - stub_const("#{described_class.name}::BATCH_SIZE", 2) - - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(10.minutes, mrs.first.id, mrs.second.id) - - expect(described_class::MIGRATION) - .to be_scheduled_delayed_migration(20.minutes, mrs.third.id, mrs.third.id) - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - end - end - end -end |