diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2019-04-29 14:16:03 +0200 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2019-06-17 17:09:05 +0200 |
commit | 8469f59d786be6762908f62d642625790999cb9b (patch) | |
tree | 03f99c605e465673e017e775a623ffa5b62f18d3 /spec/lib/gitlab/background_migration | |
parent | 0f777a8d49568d3f5ffdd4b75b594f07e9fbd2f0 (diff) | |
download | gitlab-ce-8469f59d786be6762908f62d642625790999cb9b.tar.gz |
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/lib/gitlab/background_migration')
11 files changed, 95 insertions, 905 deletions
diff --git a/spec/lib/gitlab/background_migration/create_gpg_key_subkeys_from_gpg_keys_spec.rb b/spec/lib/gitlab/background_migration/create_gpg_key_subkeys_from_gpg_keys_spec.rb deleted file mode 100644 index f974dc8fda2..00000000000 --- a/spec/lib/gitlab/background_migration/create_gpg_key_subkeys_from_gpg_keys_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'spec_helper' - -describe Gitlab::BackgroundMigration::CreateGpgKeySubkeysFromGpgKeys, :migration, schema: 20171005130944 do - context 'when GpgKey exists' do - let!(:gpg_key) { create(:gpg_key, key: GpgHelpers::User3.public_key) } # rubocop:disable RSpec/FactoriesInMigrationSpecs - - before do - GpgKeySubkey.destroy_all # rubocop: disable DestroyAll - end - - it 'generate the subkeys' do - expect do - described_class.new.perform(gpg_key.id) - end.to change { gpg_key.subkeys.count }.from(0).to(2) - end - - it 'schedules the signature update worker' do - expect(InvalidGpgSignatureUpdateWorker).to receive(:perform_async).with(gpg_key.id) - - described_class.new.perform(gpg_key.id) - end - end - - context 'when GpgKey does not exist' do - it 'does not do anything' do - expect(Gitlab::Gpg).not_to receive(:subkeys_from_key) - expect(InvalidGpgSignatureUpdateWorker).not_to receive(:perform_async) - - described_class.new.perform(123) - end - end -end diff --git a/spec/lib/gitlab/background_migration/delete_diff_files_spec.rb b/spec/lib/gitlab/background_migration/delete_diff_files_spec.rb deleted file mode 100644 index 0a5b99d27e7..00000000000 --- a/spec/lib/gitlab/background_migration/delete_diff_files_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'spec_helper' - -# rubocop:disable RSpec/FactoriesInMigrationSpecs -describe Gitlab::BackgroundMigration::DeleteDiffFiles, :migration, :sidekiq, schema: 20180619121030 do - describe '#perform' do - 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(0) - allow_any_instance_of(ProjectCiCdSetting).to receive(:default_git_depth).and_return(nil) - end - - context 'when diff files can be deleted' do - let(:merge_request) { create(:merge_request, :merged) } - let!(:merge_request_diff) do - merge_request.create_merge_request_diff - merge_request.merge_request_diffs.first - end - - let(:perform) do - described_class.new.perform(MergeRequestDiff.pluck(:id)) - end - - it 'deletes all merge request diff files' do - expect { perform } - .to change { merge_request_diff.merge_request_diff_files.count } - .from(20).to(0) - end - - it 'updates state to without_files' do - expect { perform } - .to change { merge_request_diff.reload.state } - .from('collected').to('without_files') - end - - it 'rollsback if something goes wrong' do - expect(described_class::MergeRequestDiffFile).to receive_message_chain(:where, :delete_all) - .and_raise - - expect { perform } - .to raise_error - - merge_request_diff.reload - - expect(merge_request_diff.state).to eq('collected') - expect(merge_request_diff.merge_request_diff_files.count).to eq(20) - end - end - - it 'reschedules itself when should_wait_deadtuple_vacuum' do - merge_request = create(:merge_request, :merged) - first_diff = merge_request.merge_request_diff - second_diff = merge_request.create_merge_request_diff - - Sidekiq::Testing.fake! do - worker = described_class.new - allow(worker).to receive(:should_wait_deadtuple_vacuum?) { true } - - worker.perform([first_diff.id, second_diff.id]) - - expect(described_class.name.demodulize).to be_scheduled_delayed_migration(5.minutes, [first_diff.id, second_diff.id]) - expect(BackgroundMigrationWorker.jobs.size).to eq(1) - end - end - end - - describe '#should_wait_deadtuple_vacuum?' do - it 'returns true when hitting merge_request_diff_files hits DEAD_TUPLES_THRESHOLD', :postgresql do - worker = described_class.new - threshold_query_result = [{ "n_dead_tup" => described_class::DEAD_TUPLES_THRESHOLD.to_s }] - normal_query_result = [{ "n_dead_tup" => '3' }] - - allow(worker) - .to receive(:execute_statement) - .with(/SELECT n_dead_tup */) - .and_return(threshold_query_result, normal_query_result) - - expect(worker.should_wait_deadtuple_vacuum?).to be(true) - end - end -end -# rubocop:enable RSpec/FactoriesInMigrationSpecs diff --git a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb deleted file mode 100644 index d3f7f1ded16..00000000000 --- a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb +++ /dev/null @@ -1,326 +0,0 @@ -require 'spec_helper' - -# rubocop:disable RSpec/FactoriesInMigrationSpecs -describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits, :migration, schema: 20171114162227 do - include GitHelpers - - let(:merge_request_diffs) { table(:merge_request_diffs) } - let(:merge_requests) { table(:merge_requests) } - - describe '#perform' do - let(:project) { create(:project, :repository) } - let(:merge_request) { merge_requests.create!(iid: 1, target_project_id: project.id, source_project_id: project.id, target_branch: 'feature', source_branch: 'master').becomes(MergeRequest) } - let(:merge_request_diff) { MergeRequest.find(merge_request.id).create_merge_request_diff } - let(:updated_merge_request_diff) { MergeRequestDiff.find(merge_request_diff.id) } - let(:rugged) { rugged_repo(project.repository) } - - before do - allow_any_instance_of(MergeRequestDiff) - .to receive(:commits_count=).and_return(nil) - end - - def diffs_to_hashes(diffs) - diffs.as_json(only: Gitlab::Git::Diff::SERIALIZE_KEYS).map(&:with_indifferent_access) - end - - def quote_yaml(value) - MergeRequestDiff.connection.quote(YAML.dump(value)) - end - - def convert_to_yaml(merge_request_diff_id, commits, diffs) - MergeRequestDiff.where(id: merge_request_diff_id).update_all( - "st_commits = #{quote_yaml(commits)}, st_diffs = #{quote_yaml(diffs)}" - ) - end - - shared_examples 'updated MR diff' do - before do - convert_to_yaml(merge_request_diff.id, commits, diffs) - - MergeRequestDiffCommit.delete_all - MergeRequestDiffFile.delete_all - - subject.perform(merge_request_diff.id, merge_request_diff.id) - end - - it 'creates correct entries in the merge_request_diff_commits table' do - expect(updated_merge_request_diff.merge_request_diff_commits.count).to eq(expected_commits.count) - expect(updated_merge_request_diff.commits.map(&:to_hash)).to eq(expected_commits) - end - - it 'creates correct entries in the merge_request_diff_files table' do - expect(updated_merge_request_diff.merge_request_diff_files.count).to eq(expected_diffs.count) - expect(diffs_to_hashes(updated_merge_request_diff.raw_diffs)).to eq(expected_diffs) - end - - it 'sets the st_commits and st_diffs columns to nil' do - expect(updated_merge_request_diff.st_commits_before_type_cast).to be_nil - expect(updated_merge_request_diff.st_diffs_before_type_cast).to be_nil - end - end - - context 'when the diff IDs passed do not exist' do - it 'does not raise' do - expect { subject.perform(0, 0) }.not_to raise_exception - end - end - - context 'when the merge request diff has no serialised commits or diffs' do - before do - merge_request_diff.update(st_commits: nil, st_diffs: nil) - end - - it 'does not raise' do - expect { subject.perform(merge_request_diff.id, merge_request_diff.id) } - .not_to raise_exception - end - end - - context 'processing multiple merge request diffs' do - let(:start_id) { described_class::MergeRequestDiff.minimum(:id) } - let(:stop_id) { described_class::MergeRequestDiff.maximum(:id) } - - before do - merge_request.create_merge_request_diff - - convert_to_yaml(start_id, merge_request_diff.commits, diffs_to_hashes(merge_request_diff.merge_request_diff_files)) - convert_to_yaml(stop_id, updated_merge_request_diff.commits, diffs_to_hashes(updated_merge_request_diff.merge_request_diff_files)) - - MergeRequestDiffCommit.delete_all - MergeRequestDiffFile.delete_all - end - - context 'when BUFFER_ROWS is exceeded' do - before do - stub_const("#{described_class}::BUFFER_ROWS", 1) - - allow(Gitlab::Database).to receive(:bulk_insert).and_call_original - end - - it 'inserts commit rows in chunks of BUFFER_ROWS' do - # There are 29 commits in each diff, so we should have slices of 20 + 9 + 20 + 9. - stub_const("#{described_class}::BUFFER_ROWS", 20) - - expect(Gitlab::Database).to receive(:bulk_insert) - .with('merge_request_diff_commits', anything) - .exactly(4) - .times - .and_call_original - - subject.perform(start_id, stop_id) - end - - it 'inserts diff rows in chunks of DIFF_FILE_BUFFER_ROWS' do - # There are 20 files in each diff, so we should have slices of 20 + 20. - stub_const("#{described_class}::DIFF_FILE_BUFFER_ROWS", 20) - - expect(Gitlab::Database).to receive(:bulk_insert) - .with('merge_request_diff_files', anything) - .exactly(2) - .times - .and_call_original - - subject.perform(start_id, stop_id) - end - end - - context 'when BUFFER_ROWS is not exceeded' do - it 'only updates once' do - expect(Gitlab::Database).to receive(:bulk_insert) - .with('merge_request_diff_commits', anything) - .once - .and_call_original - - expect(Gitlab::Database).to receive(:bulk_insert) - .with('merge_request_diff_files', anything) - .once - .and_call_original - - subject.perform(start_id, stop_id) - end - end - - context 'when some rows were already inserted due to a previous failure' do - before do - subject.perform(start_id, stop_id) - - convert_to_yaml(start_id, merge_request_diff.commits, diffs_to_hashes(merge_request_diff.merge_request_diff_files)) - convert_to_yaml(stop_id, updated_merge_request_diff.commits, diffs_to_hashes(updated_merge_request_diff.merge_request_diff_files)) - end - - it 'does not raise' do - expect { subject.perform(start_id, stop_id) }.not_to raise_exception - end - - it 'logs a message' do - expect(Rails.logger).to receive(:info) - .with( - a_string_matching(described_class.name).and(matching([start_id, stop_id].inspect)) - ) - .twice - - subject.perform(start_id, stop_id) - end - - it 'ends up with the correct rows' do - expect(updated_merge_request_diff.commits.count).to eq(29) - expect(updated_merge_request_diff.raw_diffs.count).to eq(20) - end - end - - context 'when the merge request diff update fails' do - let(:exception) { ActiveRecord::RecordNotFound } - - let(:perform_ignoring_exceptions) do - subject.perform(start_id, stop_id) - rescue described_class::Error - end - - before do - allow_any_instance_of(ActiveRecord::Relation) - .to receive(:update_all).and_raise(exception) - end - - it 'raises an error' do - expect { subject.perform(start_id, stop_id) } - .to raise_exception(described_class::Error) - end - - it 'logs the error' do - expect(Rails.logger).to receive(:info).with( - a_string_matching(described_class.name) - .and(matching([start_id, stop_id].inspect)) - .and(matching(exception.name)) - ) - - perform_ignoring_exceptions - end - - it 'still adds diff commits' do - expect { perform_ignoring_exceptions } - .to change { MergeRequestDiffCommit.count } - end - - it 'still adds diff files' do - expect { perform_ignoring_exceptions } - .to change { MergeRequestDiffFile.count } - end - end - end - - context 'when the merge request diff has valid commits and diffs' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:expected_commits) { commits } - let(:diffs) { diffs_to_hashes(merge_request_diff.merge_request_diff_files) } - let(:expected_diffs) { diffs } - - include_examples 'updated MR diff' - end - - context 'when the merge request diff has diffs but no commits' do - let(:commits) { nil } - let(:expected_commits) { [] } - let(:diffs) { diffs_to_hashes(merge_request_diff.merge_request_diff_files) } - let(:expected_diffs) { diffs } - - include_examples 'updated MR diff' - end - - context 'when the merge request diffs do not have too_large set' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:expected_commits) { commits } - let(:expected_diffs) { diffs_to_hashes(merge_request_diff.merge_request_diff_files) } - - let(:diffs) do - expected_diffs.map { |diff| diff.except(:too_large) } - end - - include_examples 'updated MR diff' - end - - context 'when the merge request diffs do not have a_mode and b_mode set' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:expected_commits) { commits } - let(:expected_diffs) { diffs_to_hashes(merge_request_diff.merge_request_diff_files) } - - let(:diffs) do - expected_diffs.map { |diff| diff.except(:a_mode, :b_mode) } - end - - include_examples 'updated MR diff' - end - - context 'when the merge request diffs have binary content' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:expected_commits) { commits } - let(:expected_diffs) { diffs } - - # The start of a PDF created by Illustrator - let(:binary_string) do - "\x25\x50\x44\x46\x2d\x31\x2e\x35\x0d\x25\xe2\xe3\xcf\xd3\x0d\x0a".force_encoding(Encoding::BINARY) - end - - let(:diffs) do - [ - { - 'diff' => binary_string, - 'new_path' => 'path', - 'old_path' => 'path', - 'a_mode' => '100644', - 'b_mode' => '100644', - 'new_file' => false, - 'renamed_file' => false, - 'deleted_file' => false, - 'too_large' => false - } - ] - end - - include_examples 'updated MR diff' - end - - context 'when the merge request diff has commits, but no diffs' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:expected_commits) { commits } - let(:diffs) { [] } - let(:expected_diffs) { diffs } - - include_examples 'updated MR diff' - end - - context 'when the merge request diffs have invalid content' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:expected_commits) { commits } - let(:diffs) { ['--broken-diff'] } - let(:expected_diffs) { [] } - - include_examples 'updated MR diff' - end - - context 'when the merge request diffs are Rugged::Patch instances' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:first_commit) { project.repository.commit(merge_request_diff.head_commit_sha) } - let(:expected_commits) { commits } - let(:diffs) { rugged_diff(first_commit.sha).patches } - let(:expected_diffs) { [] } - - include_examples 'updated MR diff' - end - - context 'when the merge request diffs are Rugged::Diff::Delta instances' do - let(:commits) { merge_request_diff.commits.map(&:to_hash) } - let(:first_commit) { project.repository.commit(merge_request_diff.head_commit_sha) } - let(:expected_commits) { commits } - let(:diffs) { rugged_diff(first_commit.sha).deltas } - let(:expected_diffs) { [] } - - include_examples 'updated MR diff' - end - - def rugged_diff(commit_sha) - rugged_commit = rugged.lookup(commit_sha) - rugged_commit.parents[0].diff(rugged_commit) - end - end -end -# rubocop:enable RSpec/FactoriesInMigrationSpecs diff --git a/spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb b/spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb new file mode 100644 index 00000000000..eecd290e3ca --- /dev/null +++ b/spec/lib/gitlab/background_migration/merge_request_assignees_migration_progress_check_spec.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::BackgroundMigration::MergeRequestAssigneesMigrationProgressCheck do + context 'rescheduling' do + context 'when there are ongoing and no dead jobs' do + it 'reschedules check' do + allow(Gitlab::BackgroundMigration).to receive(:exists?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(true) + + allow(Gitlab::BackgroundMigration).to receive(:dead_jobs?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(false) + + expect(BackgroundMigrationWorker).to receive(:perform_in).with(described_class::RESCHEDULE_DELAY, described_class.name) + + described_class.new.perform + end + end + + context 'when there are ongoing and dead jobs' do + it 'reschedules check' do + allow(Gitlab::BackgroundMigration).to receive(:exists?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(true) + + allow(Gitlab::BackgroundMigration).to receive(:dead_jobs?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(true) + + expect(BackgroundMigrationWorker).to receive(:perform_in).with(described_class::RESCHEDULE_DELAY, described_class.name) + + described_class.new.perform + end + end + + context 'when there retrying jobs and no scheduled' do + it 'reschedules check' do + allow(Gitlab::BackgroundMigration).to receive(:exists?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(false) + + allow(Gitlab::BackgroundMigration).to receive(:retrying_jobs?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(true) + + expect(BackgroundMigrationWorker).to receive(:perform_in).with(described_class::RESCHEDULE_DELAY, described_class.name) + + described_class.new.perform + end + end + end + + context 'when there are no scheduled, or retrying or dead' do + it 'enables feature' do + allow(Gitlab::BackgroundMigration).to receive(:exists?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(false) + + allow(Gitlab::BackgroundMigration).to receive(:retrying_jobs?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(false) + + allow(Gitlab::BackgroundMigration).to receive(:dead_jobs?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(false) + + expect(Feature).to receive(:enable).with(:multiple_merge_request_assignees) + + described_class.new.perform + end + end + + context 'when there are only dead jobs' do + it 'raises DeadJobsError error' do + allow(Gitlab::BackgroundMigration).to receive(:exists?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(false) + + allow(Gitlab::BackgroundMigration).to receive(:retrying_jobs?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(false) + + allow(Gitlab::BackgroundMigration).to receive(:dead_jobs?) + .with('PopulateMergeRequestAssigneesTable') + .and_return(true) + + expect { described_class.new.perform } + .to raise_error(described_class::DeadJobsError, + "Only dead background jobs in the queue for #{described_class::WORKER}") + end + end +end diff --git a/spec/lib/gitlab/background_migration/populate_external_pipeline_source_spec.rb b/spec/lib/gitlab/background_migration/populate_external_pipeline_source_spec.rb deleted file mode 100644 index c6bc3db88a3..00000000000 --- a/spec/lib/gitlab/background_migration/populate_external_pipeline_source_spec.rb +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -# rubocop:disable RSpec/FactoriesInMigrationSpecs -describe Gitlab::BackgroundMigration::PopulateExternalPipelineSource, :migration, schema: 20180916011959 do - let(:migration) { described_class.new } - - before do - # This migration was created before we introduced metadata configs - stub_feature_flags(ci_build_metadata_config: false) - # 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 - - let!(:internal_pipeline) { create(:ci_pipeline, source: :web) } - let(:pipelines) { [internal_pipeline, unknown_pipeline].map(&:id) } - - let!(:unknown_pipeline) do - build(:ci_pipeline, source: :unknown) - .tap { |pipeline| pipeline.save(validate: false) } - end - - subject { migration.perform(pipelines.min, pipelines.max) } - - shared_examples 'no changes' do - it 'does not change the pipeline source' do - expect { subject }.not_to change { unknown_pipeline.reload.source } - end - end - - context 'when unknown pipeline is external' do - before do - create(:generic_commit_status, pipeline: unknown_pipeline) - end - - it 'populates the pipeline source' do - subject - - expect(unknown_pipeline.reload.source).to eq('external') - end - - it 'can be repeated without effect' do - subject - - expect { subject }.not_to change { unknown_pipeline.reload.source } - end - end - - context 'when unknown pipeline has just a build' do - before do - create(:ci_build, pipeline: unknown_pipeline) - end - - it_behaves_like 'no changes' - end - - context 'when unknown pipeline has no statuses' do - it_behaves_like 'no changes' - end - - context 'when unknown pipeline has a build and a status' do - before do - create(:generic_commit_status, pipeline: unknown_pipeline) - create(:ci_build, pipeline: unknown_pipeline) - end - - it_behaves_like 'no changes' - end -end -# rubocop:enable RSpec/FactoriesInMigrationSpecs diff --git a/spec/lib/gitlab/background_migration/populate_import_state_spec.rb b/spec/lib/gitlab/background_migration/populate_import_state_spec.rb deleted file mode 100644 index fcb869022de..00000000000 --- a/spec/lib/gitlab/background_migration/populate_import_state_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'spec_helper' - -describe Gitlab::BackgroundMigration::PopulateImportState, :migration, schema: 20180502134117 do - let(:migration) { described_class.new } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:import_state) { table(:project_mirror_data) } - - before do - 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_status: :none, import_url: generate(:url)) - projects.create!(id: 3, namespace_id: 1, name: 'gitlab3', - path: 'gitlab3', import_error: "bar", import_status: :failed, - import_url: generate(:url)) - - allow(BackgroundMigrationWorker).to receive(:perform_in) - end - - it "creates new import_state records with project's import data" do - expect(projects.where.not(import_status: :none).count).to eq(2) - - expect do - migration.perform(1, 3) - end.to change { import_state.all.count }.from(0).to(2) - - expect(import_state.first.last_error).to eq("foo") - expect(import_state.last.last_error).to eq("bar") - expect(import_state.first.status).to eq("started") - expect(import_state.last.status).to eq("failed") - expect(projects.first.import_status).to eq("none") - expect(projects.last.import_status).to eq("none") - end -end diff --git a/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_improved_spec.rb b/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_improved_spec.rb deleted file mode 100644 index d1d64574627..00000000000 --- a/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_improved_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Gitlab::BackgroundMigration::PopulateMergeRequestMetricsWithEventsDataImproved, :migration, schema: 20181204154019 do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:users) { table(:users) } - let(:events) { table(:events) } - - let(:user) { users.create!(email: 'test@example.com', projects_limit: 100, username: 'test') } - - 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 = {}) - params.merge!(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 - - def create_merge_request_event(id, params = {}) - params.merge!(id: id, - project_id: project.id, - author_id: user.id, - target_type: 'MergeRequest') - - events.create(params) - end - - describe '#perform' do - it 'creates and updates closed and merged events' do - timestamp = Time.new('2018-01-01 12:00:00').utc - - create_merge_request(1) - create_merge_request_event(1, target_id: 1, action: 3, updated_at: timestamp) - create_merge_request_event(2, target_id: 1, action: 3, updated_at: timestamp + 10.seconds) - - create_merge_request_event(3, target_id: 1, action: 7, updated_at: timestamp) - create_merge_request_event(4, target_id: 1, action: 7, updated_at: timestamp + 10.seconds) - - subject.perform(1, 1) - - merge_request = MergeRequest.first - - expect(merge_request.metrics).to have_attributes(latest_closed_by_id: user.id, - latest_closed_at: timestamp + 10.seconds, - merged_by_id: user.id) - end - end -end diff --git a/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_spec.rb b/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_spec.rb deleted file mode 100644 index ff1bd9f7850..00000000000 --- a/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_spec.rb +++ /dev/null @@ -1,132 +0,0 @@ -require 'rails_helper' - -# rubocop:disable RSpec/FactoriesInMigrationSpecs -describe Gitlab::BackgroundMigration::PopulateMergeRequestMetricsWithEventsData, :migration, schema: 20171128214150 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 - - describe '#perform' do - let(:mr_with_event) { create(:merge_request) } - let!(:merged_event) { create(:event, :merged, target: mr_with_event) } - let!(:closed_event) { create(:event, :closed, target: mr_with_event) } - - before do - # Make sure no metrics are created and kept through after_* callbacks. - mr_with_event.metrics.destroy! - end - - it 'inserts metrics and updates closed and merged events' do - subject.perform(mr_with_event.id, mr_with_event.id) - - mr_with_event.reload - - expect(mr_with_event.metrics).to have_attributes(latest_closed_by_id: closed_event.author_id, - merged_by_id: merged_event.author_id) - expect(mr_with_event.metrics.latest_closed_at.to_s).to eq(closed_event.updated_at.to_s) - end - end - - describe '#insert_metrics_for_range' do - let!(:mrs_without_metrics) { create_list(:merge_request, 3) } - let!(:mrs_with_metrics) { create_list(:merge_request, 2) } - - before do - # Make sure no metrics are created and kept through after_* callbacks. - mrs_without_metrics.each { |m| m.metrics.destroy! } - end - - it 'inserts merge_request_metrics for merge_requests without one' do - expect { subject.insert_metrics_for_range(MergeRequest.first.id, MergeRequest.last.id) } - .to change(MergeRequest::Metrics, :count).from(2).to(5) - - mrs_without_metrics.each do |mr_without_metrics| - expect(mr_without_metrics.reload.metrics).to be_present - end - end - - it 'does not inserts merge_request_metrics for MRs out of given range' do - expect { subject.insert_metrics_for_range(mrs_with_metrics.first.id, mrs_with_metrics.last.id) } - .not_to change(MergeRequest::Metrics, :count).from(2) - end - end - - describe '#update_metrics_with_events_data' do - context 'closed events data update' do - let(:users) { create_list(:user, 3) } - let(:mrs_with_event) { create_list(:merge_request, 3) } - - before do - create_list(:event, 2, :closed, author: users.first, target: mrs_with_event.first) - create_list(:event, 3, :closed, author: users.second, target: mrs_with_event.second) - create(:event, :closed, author: users.third, target: mrs_with_event.third) - end - - it 'migrates multiple MR metrics with closed event data' do - mr_without_event = create(:merge_request) - create(:event, :merged) - - subject.update_metrics_with_events_data(mrs_with_event.first.id, mrs_with_event.last.id) - - mrs_with_event.each do |mr_with_event| - latest_event = Event.where(action: 3, target: mr_with_event).last - - mr_with_event.metrics.reload - - expect(mr_with_event.metrics.latest_closed_by).to eq(latest_event.author) - expect(mr_with_event.metrics.latest_closed_at.to_s).to eq(latest_event.updated_at.to_s) - end - - expect(mr_without_event.metrics.reload).to have_attributes(latest_closed_by_id: nil, - latest_closed_at: nil) - end - - it 'does not updates metrics out of given range' do - out_of_range_mr = create(:merge_request) - create(:event, :closed, author: users.last, target: out_of_range_mr) - - expect { subject.perform(mrs_with_event.first.id, mrs_with_event.second.id) } - .not_to change { out_of_range_mr.metrics.reload.merged_by } - .from(nil) - end - end - - context 'merged events data update' do - let(:users) { create_list(:user, 3) } - let(:mrs_with_event) { create_list(:merge_request, 3) } - - before do - create_list(:event, 2, :merged, author: users.first, target: mrs_with_event.first) - create_list(:event, 3, :merged, author: users.second, target: mrs_with_event.second) - create(:event, :merged, author: users.third, target: mrs_with_event.third) - end - - it 'migrates multiple MR metrics with merged event data' do - mr_without_event = create(:merge_request) - create(:event, :merged) - - subject.update_metrics_with_events_data(mrs_with_event.first.id, mrs_with_event.last.id) - - mrs_with_event.each do |mr_with_event| - latest_event = Event.where(action: Event::MERGED, target: mr_with_event).last - - expect(mr_with_event.metrics.reload.merged_by).to eq(latest_event.author) - end - - expect(mr_without_event.metrics.reload).to have_attributes(merged_by_id: nil) - end - - it 'does not updates metrics out of given range' do - out_of_range_mr = create(:merge_request) - create(:event, :merged, author: users.last, target: out_of_range_mr) - - expect { subject.perform(mrs_with_event.first.id, mrs_with_event.second.id) } - .not_to change { out_of_range_mr.metrics.reload.merged_by } - .from(nil) - end - end - end -end -# rubocop:enable RSpec/FactoriesInMigrationSpecs diff --git a/spec/lib/gitlab/background_migration/redact_links_spec.rb b/spec/lib/gitlab/background_migration/redact_links_spec.rb deleted file mode 100644 index a40e68069cc..00000000000 --- a/spec/lib/gitlab/background_migration/redact_links_spec.rb +++ /dev/null @@ -1,96 +0,0 @@ -require 'spec_helper' - -describe Gitlab::BackgroundMigration::RedactLinks, :migration, schema: 20181014121030 do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:issues) { table(:issues) } - let(:notes) { table(:notes) } - let(:snippets) { table(:snippets) } - let(:users) { table(:users) } - let(:merge_requests) { table(:merge_requests) } - let(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab-org') } - let(:project) { projects.create(namespace_id: namespace.id, name: 'foo') } - let(:user) { users.create!(email: 'test@example.com', projects_limit: 100, username: 'test') } - - def create_merge_request(id, params) - params.merge!(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 - - def create_issue(id, params) - params.merge!(id: id, title: "issue#{id}", project_id: project.id) - - issues.create(params) - end - - def create_note(id, params) - params[:id] = id - - notes.create(params) - end - - def create_snippet(id, params) - params.merge!(id: id, author_id: user.id) - - snippets.create(params) - end - - def create_resource(model, id, params) - send("create_#{model.name.underscore}", id, params) - end - - shared_examples_for 'redactable resource' do - it 'updates only matching texts' do - matching_text = 'some text /sent_notifications/00000000000000000000000000000000/unsubscribe more text' - redacted_text = 'some text /sent_notifications/REDACTED/unsubscribe more text' - create_resource(model, 1, { field => matching_text }) - create_resource(model, 2, { field => 'not matching text' }) - create_resource(model, 3, { field => matching_text }) - create_resource(model, 4, { field => redacted_text }) - create_resource(model, 5, { field => matching_text }) - - expected = { field => 'some text /sent_notifications/REDACTED/unsubscribe more text', - "#{field}_html" => nil } - expect_any_instance_of("Gitlab::BackgroundMigration::RedactLinks::#{model}".constantize).to receive(:update_columns).with(expected).and_call_original - - subject.perform(model, field, 2, 4) - - expect(model.where(field => matching_text).pluck(:id)).to eq [1, 5] - expect(model.find(3).reload[field]).to eq redacted_text - end - end - - context 'resource is Issue' do - it_behaves_like 'redactable resource' do - let(:model) { Issue } - let(:field) { :description } - end - end - - context 'resource is Merge Request' do - it_behaves_like 'redactable resource' do - let(:model) { MergeRequest } - let(:field) { :description } - end - end - - context 'resource is Note' do - it_behaves_like 'redactable resource' do - let(:model) { Note } - let(:field) { :note } - end - end - - context 'resource is Snippet' do - it_behaves_like 'redactable resource' do - let(:model) { Snippet } - let(:field) { :description } - end - end -end diff --git a/spec/lib/gitlab/background_migration/rollback_import_state_data_spec.rb b/spec/lib/gitlab/background_migration/rollback_import_state_data_spec.rb deleted file mode 100644 index cef3b6e4568..00000000000 --- a/spec/lib/gitlab/background_migration/rollback_import_state_data_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe Gitlab::BackgroundMigration::RollbackImportStateData, :migration, schema: 20180502134117 do - let(:migration) { described_class.new } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:import_state) { table(:project_mirror_data) } - - before do - namespaces.create(id: 1, name: 'gitlab-org', path: 'gitlab-org') - - projects.create!(id: 1, namespace_id: 1, name: 'gitlab1', import_url: generate(:url)) - projects.create!(id: 2, namespace_id: 1, name: 'gitlab2', path: 'gitlab2', import_url: generate(:url)) - - import_state.create!(id: 1, project_id: 1, status: :started, last_error: "foo") - import_state.create!(id: 2, project_id: 2, status: :failed) - - allow(BackgroundMigrationWorker).to receive(:perform_in) - end - - it "creates new import_state records with project's import data" do - migration.perform(1, 2) - - expect(projects.first.import_status).to eq("started") - expect(projects.second.import_status).to eq("failed") - expect(projects.first.import_error).to eq("foo") - end -end diff --git a/spec/lib/gitlab/background_migration/schedule_diff_files_deletion_spec.rb b/spec/lib/gitlab/background_migration/schedule_diff_files_deletion_spec.rb deleted file mode 100644 index ec8ba0ce127..00000000000 --- a/spec/lib/gitlab/background_migration/schedule_diff_files_deletion_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'spec_helper' - -describe Gitlab::BackgroundMigration::ScheduleDiffFilesDeletion, :migration, :sidekiq, schema: 20180619121030 do - describe '#perform' do - let(:merge_request_diffs) { table(:merge_request_diffs) } - let(:merge_requests) { table(:merge_requests) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - - before do - stub_const("#{described_class.name}::DIFF_BATCH_SIZE", 3) - - namespaces.create!(id: 1, name: 'gitlab', path: 'gitlab') - projects.create!(id: 1, namespace_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', state: 'merged') - - merge_request_diffs.create!(id: 1, merge_request_id: 1, state: 'collected') - merge_request_diffs.create!(id: 2, merge_request_id: 1, state: 'empty') - merge_request_diffs.create!(id: 3, merge_request_id: 1, state: 'without_files') - merge_request_diffs.create!(id: 4, merge_request_id: 1, state: 'collected') - merge_request_diffs.create!(id: 5, merge_request_id: 1, state: 'collected') - merge_request_diffs.create!(id: 6, merge_request_id: 1, state: 'collected') - merge_request_diffs.create!(id: 7, merge_request_id: 1, state: 'collected') - - merge_requests.update(1, latest_merge_request_diff_id: 7) - end - - it 'correctly schedules diff file deletion workers' do - Sidekiq::Testing.fake! do - Timecop.freeze do - described_class.new.perform - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, [1, 4, 5]) - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, [6]) - - expect(BackgroundMigrationWorker.jobs.size).to eq(2) - end - end - end - end -end |