diff options
Diffstat (limited to 'spec/migrations')
48 files changed, 496 insertions, 1909 deletions
diff --git a/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb b/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb index 669e31618a3..77d8dd002e3 100644 --- a/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb +++ b/spec/migrations/20191125114345_add_admin_mode_protected_path_spec.rb @@ -4,10 +4,9 @@ require 'spec_helper' require Rails.root.join('db', 'migrate', '20191125114345_add_admin_mode_protected_path.rb') describe AddAdminModeProtectedPath do - ADMIN_MODE_ENDPOINT = '/admin/session' - subject(:migration) { described_class.new } + let(:admin_mode_endpoint) { '/admin/session' } let(:application_settings) { table(:application_settings) } context 'no settings available' do @@ -30,7 +29,7 @@ describe AddAdminModeProtectedPath do application_settings.create!(protected_paths: '{a,b,c}') protected_paths_before = %w[a b c] - protected_paths_after = protected_paths_before.dup << ADMIN_MODE_ENDPOINT + protected_paths_after = protected_paths_before.dup << admin_mode_endpoint expect { migrate! }.to change { application_settings.first.protected_paths }.from(protected_paths_before).to(protected_paths_after) end @@ -38,13 +37,13 @@ describe AddAdminModeProtectedPath do it 'new default includes admin mode endpoint' do settings_before = application_settings.create! - expect(settings_before.protected_paths).not_to include(ADMIN_MODE_ENDPOINT) + expect(settings_before.protected_paths).not_to include(admin_mode_endpoint) migrate! application_settings.reset_column_information settings_after = application_settings.create! - expect(settings_after.protected_paths).to include(ADMIN_MODE_ENDPOINT) + expect(settings_after.protected_paths).to include(admin_mode_endpoint) end end diff --git a/spec/migrations/active_record/schedule_set_confidential_note_events_on_services_spec.rb b/spec/migrations/active_record/schedule_set_confidential_note_events_on_services_spec.rb deleted file mode 100644 index e973454ecc8..00000000000 --- a/spec/migrations/active_record/schedule_set_confidential_note_events_on_services_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180122154930_schedule_set_confidential_note_events_on_services.rb') - -describe ScheduleSetConfidentialNoteEventsOnServices do - let(:services_table) { table(:services) } - let(:migration_class) { Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnServices } - let(:migration_name) { migration_class.to_s.demodulize } - - let!(:service_1) { services_table.create!(confidential_note_events: nil, note_events: true) } - let!(:service_2) { services_table.create!(confidential_note_events: nil, note_events: true) } - let!(:service_migrated) { services_table.create!(confidential_note_events: true, note_events: true) } - let!(:service_skip) { services_table.create!(confidential_note_events: nil, note_events: false) } - let!(:service_new) { services_table.create!(confidential_note_events: false, note_events: true) } - let!(:service_4) { services_table.create!(confidential_note_events: nil, note_events: true) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - end - - it 'schedules background migrations at correct time' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(migration_name).to be_scheduled_delayed_migration(20.minutes, service_1.id, service_1.id) - expect(migration_name).to be_scheduled_delayed_migration(40.minutes, service_2.id, service_2.id) - expect(migration_name).to be_scheduled_delayed_migration(60.minutes, service_4.id, service_4.id) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 - end - end - end - - it 'correctly processes services', :sidekiq_might_not_need_inline do - perform_enqueued_jobs do - expect(services_table.where(confidential_note_events: nil).count).to eq 4 - expect(services_table.where(confidential_note_events: true).count).to eq 1 - - migrate! - - expect(services_table.where(confidential_note_events: nil).count).to eq 1 - expect(services_table.where(confidential_note_events: true).count).to eq 4 - end - end -end diff --git a/spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb b/spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb deleted file mode 100644 index ceca38b148e..00000000000 --- a/spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180710162338_add_foreign_key_from_notification_settings_to_users.rb') - -describe AddForeignKeyFromNotificationSettingsToUsers do - let(:notification_settings) { table(:notification_settings) } - let(:users) { table(:users) } - let(:projects) { table(:projects) } - - before do - users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) - projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: 1) - end - - describe 'removal of orphans without user' do - let!(:notification_setting_without_user) { create_notification_settings!(user_id: 123) } - let!(:notification_setting_with_user) { create_notification_settings!(user_id: users.last.id) } - - it 'removes orphaned notification_settings without user' do - expect { migrate! }.to change { notification_settings.count }.by(-1) - end - - it "doesn't remove notification_settings with valid user" do - expect { migrate! }.not_to change { notification_setting_with_user.reload } - end - end - - def create_notification_settings!(**opts) - notification_settings.create!( - source_id: projects.last.id, - source_type: 'Project', - user_id: users.last.id, - **opts) - end -end diff --git a/spec/migrations/add_foreign_keys_to_todos_spec.rb b/spec/migrations/add_foreign_keys_to_todos_spec.rb deleted file mode 100644 index 49fb3c1a911..00000000000 --- a/spec/migrations/add_foreign_keys_to_todos_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180201110056_add_foreign_keys_to_todos.rb') - -describe AddForeignKeysToTodos do - let(:todos) { table(:todos) } - let(:users) { table(:users) } - let(:projects) { table(:projects) } - - let(:project) { projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: 1) } - let(:user) { users.create!(email: 'email@email.com', name: 'foo', username: 'foo', projects_limit: 0) } - - context 'add foreign key on user_id' do - let!(:todo_with_user) { create_todo(user_id: user.id) } - let!(:todo_without_user) { create_todo(user_id: 4711) } - - it 'removes orphaned todos without corresponding user' do - expect { migrate! }.to change { Todo.count }.from(2).to(1) - end - - it 'does not remove entries with valid user_id' do - expect { migrate! }.not_to change { todo_with_user.reload } - end - end - - context 'add foreign key on author_id' do - let!(:todo_with_author) { create_todo(author_id: user.id) } - let!(:todo_with_invalid_author) { create_todo(author_id: 4711) } - - it 'removes orphaned todos by author_id' do - expect { migrate! }.to change { Todo.count }.from(2).to(1) - end - - it 'does not touch author_id for valid entries' do - expect { migrate! }.not_to change { todo_with_author.reload } - end - end - - context 'add foreign key on note_id' do - let(:note) { table(:notes).create! } - let!(:todo_with_note) { create_todo(note_id: note.id) } - let!(:todo_with_invalid_note) { create_todo(note_id: 4711) } - let!(:todo_without_note) { create_todo(note_id: nil) } - - it 'deletes todo if note_id is set but does not exist in notes table' do - expect { migrate! }.to change { Todo.count }.from(3).to(2) - end - - it 'does not touch entry if note_id is nil' do - expect { migrate! }.not_to change { todo_without_note.reload } - end - - it 'does not touch note_id for valid entries' do - expect { migrate! }.not_to change { todo_with_note.reload } - end - end - - def create_todo(**opts) - todos.create!( - project_id: project.id, - user_id: user.id, - author_id: user.id, - target_type: '', - action: 0, - state: '', **opts - ) - end -end diff --git a/spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb b/spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb new file mode 100644 index 00000000000..507b1a8d580 --- /dev/null +++ b/spec/migrations/add_incident_settings_to_all_existing_projects_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20200609212701_add_incident_settings_to_all_existing_projects.rb') + +describe AddIncidentSettingsToAllExistingProjects, :migration do + let(:project_incident_management_settings) { table(:project_incident_management_settings) } + let(:labels) { table(:labels) } + let(:label_links) { table(:label_links) } + let(:issues) { table(:issues) } + let(:projects) { table(:projects) } + let(:namespaces) { table(:namespaces) } + + RSpec.shared_examples 'setting not added' do + it 'does not add settings' do + migrate! + + expect { migrate! }.not_to change { IncidentManagement::ProjectIncidentManagementSetting.count } + end + end + + RSpec.shared_examples 'project has no incident settings' do + it 'has no settings' do + migrate! + + expect(settings).to eq(nil) + end + end + + RSpec.shared_examples 'no change to incident settings' do + it 'does not change existing settings' do + migrate! + + expect(settings.create_issue).to eq(existing_create_issue) + end + end + + RSpec.shared_context 'with incident settings' do + let(:existing_create_issue) { false } + before do + project_incident_management_settings.create( + project_id: project.id, + create_issue: existing_create_issue + ) + end + end + + describe 'migrate!' do + let(:namespace) { namespaces.create!(name: 'foo', path: 'foo') } + let!(:project) { projects.create!(namespace_id: namespace.id) } + let(:settings) { project_incident_management_settings.find_by(project_id: project.id) } + + context 'when project does not have incident label' do + context 'does not have incident settings' do + include_examples 'setting not added' + include_examples 'project has no incident settings' + end + + context 'and has incident settings' do + include_context 'with incident settings' + + include_examples 'setting not added' + include_examples 'no change to incident settings' + end + end + + context 'when project has incident labels' do + before do + issue = issues.create!(project_id: project.id) + incident_label_attrs = IncidentManagement::CreateIssueService::INCIDENT_LABEL + incident_label = labels.create!(project_id: project.id, **incident_label_attrs) + label_links.create!(target_id: issue.id, label_id: incident_label.id, target_type: 'Issue') + end + + context 'when project has incident settings' do + include_context 'with incident settings' + + include_examples 'setting not added' + include_examples 'no change to incident settings' + end + + context 'does not have incident settings' do + it 'adds incident settings with old defaults' do + migrate! + + expect(settings.create_issue).to eq(true) + expect(settings.send_email).to eq(false) + expect(settings.issue_template_key).to eq(nil) + end + end + end + end +end diff --git a/spec/migrations/add_not_null_constraint_to_project_mirror_data_foreign_key_spec.rb b/spec/migrations/add_not_null_constraint_to_project_mirror_data_foreign_key_spec.rb deleted file mode 100644 index 03f65aba7c0..00000000000 --- a/spec/migrations/add_not_null_constraint_to_project_mirror_data_foreign_key_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180508100222_add_not_null_constraint_to_project_mirror_data_foreign_key.rb') - -describe AddNotNullConstraintToProjectMirrorDataForeignKey do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:import_state) { table(:project_mirror_data) } - - before do - import_state.create!(id: 1, project_id: nil, status: :started) - end - - it 'removes every import state without an associated project_id' do - expect do - subject.up - end.to change { import_state.count }.from(1).to(0) - end -end diff --git a/spec/migrations/add_pages_access_level_to_project_feature_spec.rb b/spec/migrations/add_pages_access_level_to_project_feature_spec.rb deleted file mode 100644 index 69f1e3ba3d0..00000000000 --- a/spec/migrations/add_pages_access_level_to_project_feature_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180423204600_add_pages_access_level_to_project_feature.rb') - -describe AddPagesAccessLevelToProjectFeature do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:features) { table(:project_features) } - let!(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab') } - let!(:first_project) { projects.create(name: 'gitlab1', path: 'gitlab1', namespace_id: namespace.id) } - let!(:first_project_features) { features.create(project_id: first_project.id) } - let!(:second_project) { projects.create(name: 'gitlab2', path: 'gitlab2', namespace_id: namespace.id) } - let!(:second_project_features) { features.create(project_id: second_project.id) } - - it 'correctly migrate pages for old projects to be public' do - migrate! - - # For old projects pages should be public - expect(first_project_features.reload.pages_access_level).to eq ProjectFeature::PUBLIC - expect(second_project_features.reload.pages_access_level).to eq ProjectFeature::PUBLIC - end - - it 'after migration pages are enabled as default' do - migrate! - - # For new project default is enabled - third_project = projects.create(name: 'gitlab3', path: 'gitlab3', namespace_id: namespace.id) - third_project_features = features.create(project_id: third_project.id) - expect(third_project_features.reload.pages_access_level).to eq ProjectFeature::ENABLED - end -end diff --git a/spec/migrations/add_pipeline_build_foreign_key_spec.rb b/spec/migrations/add_pipeline_build_foreign_key_spec.rb deleted file mode 100644 index dd0189b6bfc..00000000000 --- a/spec/migrations/add_pipeline_build_foreign_key_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180420010016_add_pipeline_build_foreign_key.rb') - -describe AddPipelineBuildForeignKey do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:pipelines) { table(:ci_pipelines) } - let(:builds) { table(:ci_builds) } - - before do - namespaces.create(id: 10, name: 'gitlab-org', path: 'gitlab-org') - projects.create!(id: 11, namespace_id: 10, name: 'gitlab', path: 'gitlab') - pipelines.create!(id: 12, project_id: 11, ref: 'master', sha: 'adf43c3a') - - builds.create!(id: 101, commit_id: 12, project_id: 11) - builds.create!(id: 102, commit_id: 222, project_id: 11) - builds.create!(id: 103, commit_id: 333, project_id: 11) - builds.create!(id: 104, commit_id: 12, project_id: 11) - builds.create!(id: 106, commit_id: nil, project_id: 11) - builds.create!(id: 107, commit_id: 12, project_id: nil) - end - - it 'adds foreign key after removing orphans' do - expect(builds.all.count).to eq 6 - expect(foreign_key_exists?(:ci_builds, :ci_pipelines, column: :commit_id)).to be_falsey - - migrate! - - expect(builds.all.pluck(:id)).to eq [101, 104] - expect(foreign_key_exists?(:ci_builds, :ci_pipelines, column: :commit_id)).to be_truthy - end -end diff --git a/spec/migrations/add_unique_constraint_to_project_features_project_id_spec.rb b/spec/migrations/add_unique_constraint_to_project_features_project_id_spec.rb deleted file mode 100644 index 91abf0f7d1c..00000000000 --- a/spec/migrations/add_unique_constraint_to_project_features_project_id_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180511174224_add_unique_constraint_to_project_features_project_id.rb') - -describe AddUniqueConstraintToProjectFeaturesProjectId do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:features) { table(:project_features) } - let(:migration) { described_class.new } - - describe '#up' do - before do - (1..3).each do |i| - namespaces.create(id: i, name: "ns-test-#{i}", path: "ns-test-i#{i}") - projects.create!(id: i, name: "test-#{i}", path: "test-#{i}", namespace_id: i) - end - - features.create!(id: 1, project_id: 1) - features.create!(id: 2, project_id: 1) - features.create!(id: 3, project_id: 2) - features.create!(id: 4, project_id: 2) - features.create!(id: 5, project_id: 2) - features.create!(id: 6, project_id: 3) - end - - it 'creates a unique index and removes duplicates' do - expect(migration.index_exists?(:project_features, :project_id, unique: false, name: 'index_project_features_on_project_id')).to be true - - expect { migration.up }.to change { features.count }.from(6).to(3) - - expect(migration.index_exists?(:project_features, :project_id, unique: true, name: 'index_project_features_on_project_id')).to be true - expect(migration.index_exists?(:project_features, :project_id, name: 'index_project_features_on_project_id_unique')).to be false - - project_1_features = features.where(project_id: 1) - expect(project_1_features.count).to eq(1) - expect(project_1_features.first.id).to eq(2) - - project_2_features = features.where(project_id: 2) - expect(project_2_features.count).to eq(1) - expect(project_2_features.first.id).to eq(5) - - project_3_features = features.where(project_id: 3) - expect(project_3_features.count).to eq(1) - expect(project_3_features.first.id).to eq(6) - end - end - - describe '#down' do - it 'restores the original index' do - migration.up - - expect(migration.index_exists?(:project_features, :project_id, unique: true, name: 'index_project_features_on_project_id')).to be true - - migration.down - - expect(migration.index_exists?(:project_features, :project_id, unique: false, name: 'index_project_features_on_project_id')).to be true - expect(migration.index_exists?(:project_features, :project_id, name: 'index_project_features_on_project_id_old')).to be false - end - end -end diff --git a/spec/migrations/assure_commits_count_for_merge_request_diff_spec.rb b/spec/migrations/assure_commits_count_for_merge_request_diff_spec.rb deleted file mode 100644 index e9ef6bf3e2d..00000000000 --- a/spec/migrations/assure_commits_count_for_merge_request_diff_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180425131009_assure_commits_count_for_merge_request_diff.rb') - -describe AssureCommitsCountForMergeRequestDiff, :redis do - let(:migration) { spy('migration') } - - before do - allow(Gitlab::BackgroundMigration::AddMergeRequestDiffCommitsCount) - .to receive(:new).and_return(migration) - end - - context 'when there are still unmigrated commit_counts afterwards' do - let(:namespaces) { table('namespaces') } - let(:projects) { table('projects') } - let(:merge_requests) { table('merge_requests') } - let(:diffs) { table('merge_request_diffs') } - - before do - namespace = namespaces.create(name: 'foo', path: 'foo') - project = projects.create!(namespace_id: namespace.id) - merge_request = merge_requests.create!(source_branch: 'x', target_branch: 'y', target_project_id: project.id) - diffs.create!(commits_count: nil, merge_request_id: merge_request.id) - diffs.create!(commits_count: nil, merge_request_id: merge_request.id) - end - - it 'migrates commit_counts sequentially in batches' do - migrate! - - expect(migration).to have_received(:perform).once - end - end -end diff --git a/spec/migrations/backfill_imported_snippet_repositories_spec.rb b/spec/migrations/backfill_imported_snippet_repositories_spec.rb new file mode 100644 index 00000000000..c77978b23e4 --- /dev/null +++ b/spec/migrations/backfill_imported_snippet_repositories_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20200608072931_backfill_imported_snippet_repositories.rb') + +describe BackfillImportedSnippetRepositories do + let(:users) { table(:users) } + let(:snippets) { table(:snippets) } + let(:user) { users.create(id: 1, email: 'user@example.com', projects_limit: 10, username: 'test', name: 'Test', state: 'active') } + + def create_snippet(id) + params = { + id: id, + type: 'PersonalSnippet', + author_id: user.id, + file_name: 'foo', + content: 'bar' + } + + snippets.create!(params) + end + + it 'correctly schedules background migrations' do + create_snippet(1) + create_snippet(2) + create_snippet(3) + create_snippet(5) + create_snippet(7) + create_snippet(8) + create_snippet(10) + + Sidekiq::Testing.fake! do + Timecop.freeze do + migrate! + + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(2.minutes, 1, 3) + + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(4.minutes, 5, 5) + + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(6.minutes, 7, 8) + + expect(described_class::MIGRATION) + .to be_scheduled_delayed_migration(8.minutes, 10, 10) + + expect(BackgroundMigrationWorker.jobs.size).to eq(4) + end + end + end +end diff --git a/spec/migrations/backfill_releases_name_with_tag_name_spec.rb b/spec/migrations/backfill_releases_name_with_tag_name_spec.rb deleted file mode 100644 index b38b8dff3fa..00000000000 --- a/spec/migrations/backfill_releases_name_with_tag_name_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20181212104941_backfill_releases_name_with_tag_name.rb') - -describe BackfillReleasesNameWithTagName do - let(:releases) { table(:releases) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - - let(:namespace) { namespaces.create(name: 'foo', path: 'foo') } - let(:project) { projects.create!(namespace_id: namespace.id) } - let(:release) { releases.create!(project_id: project.id, tag: 'v1.0.0') } - - it 'defaults name to tag value' do - expect(release.tag).to be_present - - migrate! - - release.reload - expect(release.name).to eq(release.tag) - end -end diff --git a/spec/migrations/backfill_status_page_published_incidents_spec.rb b/spec/migrations/backfill_status_page_published_incidents_spec.rb new file mode 100644 index 00000000000..ccdc8be4168 --- /dev/null +++ b/spec/migrations/backfill_status_page_published_incidents_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20200421195234_backfill_status_page_published_incidents.rb') + +describe BackfillStatusPagePublishedIncidents, :migration do + subject(:migration) { described_class.new } + + describe '#up' do + let(:projects) { table(:projects) } + let(:status_page_settings) { table(:status_page_settings) } + let(:issues) { table(:issues) } + let(:incidents) { table(:status_page_published_incidents) } + + let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab') } + let(:project_without_status_page) { projects.create!(namespace_id: namespace.id) } + let(:enabled_project) { projects.create!(namespace_id: namespace.id) } + let(:disabled_project) { projects.create!(namespace_id: namespace.id) } + + let!(:enabled_setting) { status_page_settings.create!(enabled: true, project_id: enabled_project.id, **status_page_setting_attrs) } + let!(:disabled_setting) { status_page_settings.create!(enabled: false, project_id: disabled_project.id, **status_page_setting_attrs) } + + let!(:published_issue) { issues.create!(confidential: false, project_id: enabled_project.id) } + let!(:nonpublished_issue_1) { issues.create!(confidential: true, project_id: enabled_project.id) } + let!(:nonpublished_issue_2) { issues.create!(confidential: false, project_id: disabled_project.id) } + let!(:nonpublished_issue_3) { issues.create!(confidential: false, project_id: project_without_status_page.id) } + + let(:current_time) { Time.current.change(usec: 0) } + let(:status_page_setting_attrs) do + { + aws_s3_bucket_name: 'bucket', + aws_region: 'region', + aws_access_key: 'key', + encrypted_aws_secret_key: 'abc123', + encrypted_aws_secret_key_iv: 'abc123' + } + end + + it 'creates a StatusPage::PublishedIncident record for each published issue' do + Timecop.freeze(current_time) do + expect(incidents.all).to be_empty + + migrate! + + incident = incidents.first + + expect(incidents.count).to eq(1) + expect(incident.issue_id).to eq(published_issue.id) + expect(incident.created_at).to eq(current_time) + expect(incident.updated_at).to eq(current_time) + end + end + end +end diff --git a/spec/migrations/backfill_store_project_full_path_in_repo_spec.rb b/spec/migrations/backfill_store_project_full_path_in_repo_spec.rb deleted file mode 100644 index a2adde37f11..00000000000 --- a/spec/migrations/backfill_store_project_full_path_in_repo_spec.rb +++ /dev/null @@ -1,98 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require Rails.root.join('db', 'post_migrate', '20181010133639_backfill_store_project_full_path_in_repo.rb') - -describe BackfillStoreProjectFullPathInRepo do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:group) { namespaces.create!(name: 'foo', path: 'foo') } - let(:subgroup) { namespaces.create!(name: 'bar', path: 'bar', parent_id: group.id) } - - subject(:migration) { described_class.new } - - around do |example| - perform_enqueued_jobs do - example.run - end - end - - describe '#up' do - shared_examples_for 'writes the full path to git config' do - it 'writes the git config', :sidekiq_might_not_need_inline do - expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service| - allow(repository_service).to receive(:cleanup) - expect(repository_service).to receive(:set_config).with('gitlab.fullpath' => expected_path) - end - - migration.up - end - - it 'retries in case of failure', :sidekiq_might_not_need_inline do - repository_service = spy(:repository_service) - - allow(Gitlab::GitalyClient::RepositoryService).to receive(:new).and_return(repository_service) - - allow(repository_service).to receive(:set_config).and_raise(GRPC::BadStatus, 'Retry me') - expect(repository_service).to receive(:set_config).exactly(3).times - - migration.up - end - - it 'cleans up repository before writing the config', :sidekiq_might_not_need_inline do - expect_next_instance_of(Gitlab::GitalyClient::RepositoryService) do |repository_service| - expect(repository_service).to receive(:cleanup).ordered - expect(repository_service).to receive(:set_config).ordered - end - - migration.up - end - - context 'legacy storage' do - it 'finds the repository at the correct location' do - Project.find(project.id).create_repository - - expect { migration.up }.not_to raise_error - end - end - - context 'hashed storage' do - it 'finds the repository at the correct location' do - project.update_attribute(:storage_version, 1) - - Project.find(project.id).create_repository - - expect { migration.up }.not_to raise_error - end - end - end - - context 'project in group' do - let!(:project) { projects.create!(namespace_id: group.id, name: 'baz', path: 'baz') } - let(:expected_path) { 'foo/baz' } - - it_behaves_like 'writes the full path to git config' - end - - context 'project in subgroup' do - let!(:project) { projects.create!(namespace_id: subgroup.id, name: 'baz', path: 'baz') } - let(:expected_path) { 'foo/bar/baz' } - - it_behaves_like 'writes the full path to git config' - end - end - - describe '#down' do - context 'project in group' do - let!(:project) { projects.create!(namespace_id: group.id, name: 'baz', path: 'baz') } - - it 'deletes the gitlab full config value', :sidekiq_might_not_need_inline do - expect_any_instance_of(Gitlab::GitalyClient::RepositoryService) - .to receive(:delete_config).with(['gitlab.fullpath']) - - migration.down - end - end - end -end diff --git a/spec/migrations/cap_designs_filename_length_to_new_limit_spec.rb b/spec/migrations/cap_designs_filename_length_to_new_limit_spec.rb new file mode 100644 index 00000000000..daa07953cb5 --- /dev/null +++ b/spec/migrations/cap_designs_filename_length_to_new_limit_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20200602013901_cap_designs_filename_length_to_new_limit') + +describe CapDesignsFilenameLengthToNewLimit, :migration, schema: 20200528125905 do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:issues) { table(:issues) } + let(:designs) { table(:design_management_designs) } + + let(:filename_below_limit) { generate_filename(254) } + let(:filename_at_limit) { generate_filename(255) } + let(:filename_above_limit) { generate_filename(256) } + + let!(:namespace) { namespaces.create!(name: 'foo', path: 'foo') } + let!(:project) { projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab', namespace_id: namespace.id) } + let!(:issue) { issues.create!(description: 'issue', project_id: project.id) } + + def generate_filename(length, extension: '.png') + name = 'a' * (length - extension.length) + + "#{name}#{extension}" + end + + def create_design(filename) + designs.create!( + issue_id: issue.id, + project_id: project.id, + filename: filename + ) + end + + it 'correctly sets filenames that are above the limit' do + [ + filename_below_limit, + filename_at_limit, + filename_above_limit + ].each(&method(:create_design)) + + migrate! + + expect(designs.find(1).filename).to eq(filename_below_limit) + expect(designs.find(2).filename).to eq(filename_at_limit) + expect(designs.find(3).filename).to eq([described_class::MODIFIED_NAME, 3, described_class::MODIFIED_EXTENSION].join) + end + + it 'runs after filename limit has been set' do + # This spec file uses the `schema:` keyword to run these tests + # against a schema version before the one that sets the limit, + # as otherwise we can't create the design data with filenames greater + # than the limit. + # + # For this test, we migrate any skipped versions up to this migration. + migration_context.migrate(20200602013901) + + create_design(filename_at_limit) + expect { create_design(filename_above_limit) }.to raise_error(ActiveRecord::StatementInvalid) + end +end diff --git a/spec/migrations/change_default_value_for_dsa_key_restriction_spec.rb b/spec/migrations/change_default_value_for_dsa_key_restriction_spec.rb deleted file mode 100644 index 448f1e2106e..00000000000 --- a/spec/migrations/change_default_value_for_dsa_key_restriction_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180531220618_change_default_value_for_dsa_key_restriction.rb') - -describe ChangeDefaultValueForDsaKeyRestriction do - let(:application_settings) { table(:application_settings) } - - before do - application_settings.create! - end - - it 'changes the default value for dsa_key_restriction' do - expect(application_settings.first.dsa_key_restriction).to eq(0) - - migrate! - - application_settings.reset_column_information - new_setting = application_settings.create! - - expect(application_settings.count).to eq(2) - expect(new_setting.dsa_key_restriction).to eq(-1) - end - - it 'changes the existing setting' do - setting = application_settings.last - - expect(setting.dsa_key_restriction).to eq(0) - - migrate! - - expect(application_settings.count).to eq(1) - expect(setting.reload.dsa_key_restriction).to eq(-1) - end -end diff --git a/spec/migrations/cleanup_build_stage_migration_spec.rb b/spec/migrations/cleanup_build_stage_migration_spec.rb deleted file mode 100644 index 961e719e2fc..00000000000 --- a/spec/migrations/cleanup_build_stage_migration_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180420010616_cleanup_build_stage_migration.rb') - -describe CleanupBuildStageMigration, :redis do - let(:migration) { spy('migration') } - - before do - allow(Gitlab::BackgroundMigration::MigrateBuildStage) - .to receive(:new).and_return(migration) - end - - context 'when there are pending background migrations' do - it 'processes pending jobs synchronously' do - Sidekiq::Testing.disable! do - BackgroundMigrationWorker - .perform_in(2.minutes, 'MigrateBuildStage', [1, 1]) - BackgroundMigrationWorker - .perform_async('MigrateBuildStage', [1, 1]) - - migrate! - - expect(migration).to have_received(:perform).with(1, 1).twice - end - end - end - - context 'when there are no background migrations pending' do - it 'does nothing' do - Sidekiq::Testing.disable! do - migrate! - - expect(migration).not_to have_received(:perform) - end - end - end - - context 'when there are still unmigrated builds present' do - let(:builds) { table('ci_builds') } - - before do - builds.create!(name: 'test:1', ref: 'master') - builds.create!(name: 'test:2', ref: 'master') - end - - it 'migrates stages sequentially in batches' do - expect(builds.all).to all(have_attributes(stage_id: nil)) - - migrate! - - expect(migration).to have_received(:perform).once - end - end -end diff --git a/spec/migrations/cleanup_environments_external_url_spec.rb b/spec/migrations/cleanup_environments_external_url_spec.rb deleted file mode 100644 index 54fcb8c62cd..00000000000 --- a/spec/migrations/cleanup_environments_external_url_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20181108091549_cleanup_environments_external_url.rb') - -describe CleanupEnvironmentsExternalUrl do - let(:environments) { table(:environments) } - let(:invalid_entries) { environments.where(environments.arel_table[:external_url].matches('javascript://%')) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - - before do - namespace = namespaces.create(name: 'foo', path: 'foo') - project = projects.create!(namespace_id: namespace.id) - - environments.create!(id: 1, project_id: project.id, name: 'poisoned', slug: 'poisoned', external_url: 'javascript://alert("1")') - end - - it 'clears every environment with a javascript external_url' do - expect do - subject.up - end.to change { invalid_entries.count }.from(1).to(0) - end - - it 'do not removes environments' do - expect do - subject.up - end.not_to change { environments.count } - end -end diff --git a/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb b/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb index 06b6d5e3b46..27c954d2984 100644 --- a/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb +++ b/spec/migrations/cleanup_projects_with_missing_namespace_spec.rb @@ -5,10 +5,6 @@ require 'spec_helper' require Rails.root.join('db', 'post_migrate', '20200511080113_add_projects_foreign_key_to_namespaces.rb') require Rails.root.join('db', 'post_migrate', '20200511083541_cleanup_projects_with_missing_namespace.rb') -LOST_AND_FOUND_GROUP = 'lost-and-found' -USER_TYPE_GHOST = 5 -ACCESS_LEVEL_OWNER = 50 - # In order to test the CleanupProjectsWithMissingNamespace migration, we need # to first create an orphaned project (one with an invalid namespace_id) # and then run the migration to check that the project was properly cleaned up @@ -77,31 +73,39 @@ describe CleanupProjectsWithMissingNamespace, :migration, schema: SchemaVersionF end it 'creates the ghost user' do - expect(users.where(user_type: USER_TYPE_GHOST).count).to eq(0) + expect(users.where(user_type: described_class::User::USER_TYPE_GHOST).count).to eq(0) disable_migrations_output { migrate! } - expect(users.where(user_type: USER_TYPE_GHOST).count).to eq(1) + expect(users.where(user_type: described_class::User::USER_TYPE_GHOST).count).to eq(1) end it 'creates the lost-and-found group, owned by the ghost user' do expect( - Group.where(Group.arel_table[:name].matches("#{LOST_AND_FOUND_GROUP}%")).count + described_class::Group.where( + described_class::Group + .arel_table[:name] + .matches("#{described_class::User::LOST_AND_FOUND_GROUP}%") + ).count ).to eq(0) disable_migrations_output { migrate! } - ghost_user = users.find_by(user_type: USER_TYPE_GHOST) + ghost_user = users.find_by(user_type: described_class::User::USER_TYPE_GHOST) expect( - Group + described_class::Group .joins('INNER JOIN members ON namespaces.id = members.source_id') .where('namespaces.type = ?', 'Group') .where('members.type = ?', 'GroupMember') .where('members.source_type = ?', 'Namespace') .where('members.user_id = ?', ghost_user.id) .where('members.requested_at IS NULL') - .where('members.access_level = ?', ACCESS_LEVEL_OWNER) - .where(Group.arel_table[:name].matches("#{LOST_AND_FOUND_GROUP}%")) + .where('members.access_level = ?', described_class::ACCESS_LEVEL_OWNER) + .where( + described_class::Group + .arel_table[:name] + .matches("#{described_class::User::LOST_AND_FOUND_GROUP}%") + ) .count ).to eq(1) end @@ -114,7 +118,11 @@ describe CleanupProjectsWithMissingNamespace, :migration, schema: SchemaVersionF disable_migrations_output { migrate! } - lost_and_found_group = Group.find_by(Group.arel_table[:name].matches("#{LOST_AND_FOUND_GROUP}%")) + lost_and_found_group = described_class::Group.find_by( + described_class::Group + .arel_table[:name] + .matches("#{described_class::User::LOST_AND_FOUND_GROUP}%") + ) orphaned_project = projects.find_by(id: orphaned_project.id) expect(orphaned_project.visibility_level).to eq(0) diff --git a/spec/migrations/cleanup_stages_position_migration_spec.rb b/spec/migrations/cleanup_stages_position_migration_spec.rb deleted file mode 100644 index 62b9c4e84e3..00000000000 --- a/spec/migrations/cleanup_stages_position_migration_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180604123514_cleanup_stages_position_migration.rb') - -describe CleanupStagesPositionMigration, :redis do - let(:migration) { spy('migration') } - - before do - allow(Gitlab::BackgroundMigration::MigrateStageIndex) - .to receive(:new).and_return(migration) - end - - context 'when there are pending background migrations' do - it 'processes pending jobs synchronously' do - Sidekiq::Testing.disable! do - BackgroundMigrationWorker - .perform_in(2.minutes, 'MigrateStageIndex', [1, 1]) - BackgroundMigrationWorker - .perform_async('MigrateStageIndex', [1, 1]) - - migrate! - - expect(migration).to have_received(:perform).with(1, 1).twice - end - end - end - - context 'when there are no background migrations pending' do - it 'does nothing' do - Sidekiq::Testing.disable! do - migrate! - - expect(migration).not_to have_received(:perform) - end - end - end - - context 'when there are still unmigrated stages present' do - let(:stages) { table('ci_stages') } - let(:builds) { table('ci_builds') } - - let!(:entities) do - %w[build test broken].map do |name| - stages.create(name: name) - end - end - - before do - stages.update_all(position: nil) - - builds.create(name: 'unit', stage_id: entities.first.id, stage_idx: 1, ref: 'master') - builds.create(name: 'unit', stage_id: entities.second.id, stage_idx: 1, ref: 'master') - end - - it 'migrates stages sequentially for every stage' do - expect(stages.all).to all(have_attributes(position: nil)) - - migrate! - - expect(migration).to have_received(:perform) - .with(entities.first.id, entities.first.id) - expect(migration).to have_received(:perform) - .with(entities.second.id, entities.second.id) - expect(migration).not_to have_received(:perform) - .with(entities.third.id, entities.third.id) - 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 deleted file mode 100644 index 0872f23c02e..00000000000 --- a/spec/migrations/create_missing_namespace_for_internal_users_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180413022611_create_missing_namespace_for_internal_users.rb') - -describe CreateMissingNamespaceForInternalUsers do - let(:users) { table(:users) } - let(:namespaces) { table(:namespaces) } - let(:routes) { table(:routes) } - - 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 - - migrate! - - 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 - - it 'sets notification email' do - users.update(internal_user.id, notification_email: nil) - - expect(users.find(internal_user.id).notification_email).to be_nil - - migrate! - - user = users.find(internal_user.id) - expect(user.notification_email).to eq(user.email) - end - end -end diff --git a/spec/migrations/drop_duplicate_protected_tags_spec.rb b/spec/migrations/drop_duplicate_protected_tags_spec.rb deleted file mode 100644 index 7135a15484c..00000000000 --- a/spec/migrations/drop_duplicate_protected_tags_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180711103851_drop_duplicate_protected_tags.rb') - -describe DropDuplicateProtectedTags do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:protected_tags) { table(:protected_tags) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 2) - - namespaces.create(id: 1, name: 'gitlab-org', path: 'gitlab-org') - projects.create!(id: 1, namespace_id: 1, name: 'gitlab1', path: 'gitlab1') - projects.create!(id: 2, namespace_id: 1, name: 'gitlab2', path: 'gitlab2') - end - - it 'removes duplicated protected tags' do - protected_tags.create!(id: 1, project_id: 1, name: 'foo') - tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo1') - protected_tags.create!(id: 3, project_id: 1, name: 'foo') - tag4 = protected_tags.create!(id: 4, project_id: 1, name: 'foo') - tag5 = protected_tags.create!(id: 5, project_id: 2, name: 'foo') - - migrate! - - expect(protected_tags.all.count).to eq 3 - expect(protected_tags.all.pluck(:id)).to contain_exactly(tag2.id, tag4.id, tag5.id) - end - - it 'does not remove unique protected tags' do - tag1 = protected_tags.create!(id: 1, project_id: 1, name: 'foo1') - tag2 = protected_tags.create!(id: 2, project_id: 1, name: 'foo2') - tag3 = protected_tags.create!(id: 3, project_id: 1, name: 'foo3') - - migrate! - - expect(protected_tags.all.count).to eq 3 - expect(protected_tags.all.pluck(:id)).to contain_exactly(tag1.id, tag2.id, tag3.id) - end -end diff --git a/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb b/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb deleted file mode 100644 index 4d0a0b31571..00000000000 --- a/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require Rails.root.join('db', 'post_migrate', '20190711201818_encrypt_deploy_tokens_tokens.rb') - -describe EncryptDeployTokensTokens do - let(:migration) { described_class.new } - let(:deployment_tokens) { table(:deploy_tokens) } - let(:plaintext) { "secret-token" } - let(:expires_at) { DateTime.now + 1.year } - let(:ciphertext) { Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext) } - - describe '#up' do - it 'keeps plaintext token the same and populates token_encrypted if not present' do - deploy_token = deployment_tokens.create!( - name: 'test_token', - read_repository: true, - expires_at: expires_at, - username: 'gitlab-token-1', - token: plaintext - ) - - migration.up - - expect(deploy_token.reload.token).to eq(plaintext) - expect(deploy_token.reload.token_encrypted).to eq(ciphertext) - end - end - - describe '#down' do - it 'decrypts encrypted token and saves it' do - deploy_token = deployment_tokens.create!( - name: 'test_token', - read_repository: true, - expires_at: expires_at, - username: 'gitlab-token-1', - token_encrypted: ciphertext - ) - - migration.down - - expect(deploy_token.reload.token).to eq(plaintext) - expect(deploy_token.reload.token_encrypted).to eq(ciphertext) - end - end -end diff --git a/spec/migrations/enqueue_verify_pages_domain_workers_spec.rb b/spec/migrations/enqueue_verify_pages_domain_workers_spec.rb deleted file mode 100644 index ffb1c04a6c5..00000000000 --- a/spec/migrations/enqueue_verify_pages_domain_workers_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180216121030_enqueue_verify_pages_domain_workers') - -describe EnqueueVerifyPagesDomainWorkers do - around do |example| - Sidekiq::Testing.fake! do - example.run - end - end - - let(:domains_table) { table(:pages_domains) } - - describe '#up' do - it 'enqueues a verification worker for every domain' do - domains = Array.new(3) do |i| - domains_table.create!(domain: "my#{i}.domain.com", verification_code: "123#{i}") - end - - expect { migrate! }.to change(PagesDomainVerificationWorker.jobs, :size).by(3) - - enqueued_ids = PagesDomainVerificationWorker.jobs.map { |job| job['args'] } - expected_ids = domains.map { |domain| [domain.id] } - - expect(enqueued_ids).to match_array(expected_ids) - end - end -end diff --git a/spec/migrations/fill_empty_finished_at_in_deployments_spec.rb b/spec/migrations/fill_empty_finished_at_in_deployments_spec.rb deleted file mode 100644 index 546a805dec8..00000000000 --- a/spec/migrations/fill_empty_finished_at_in_deployments_spec.rb +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181030135124_fill_empty_finished_at_in_deployments') - -describe FillEmptyFinishedAtInDeployments do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:environments) { table(:environments) } - let(:deployments) { table(:deployments) } - - context 'when a deployment row does not have a value on finished_at' do - context 'when a deployment succeeded' do - before do - namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1') - projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: 123) - environments.create!(id: 1, name: 'production', slug: 'production', project_id: 1) - deployments.create!(id: 1, iid: 1, project_id: 1, environment_id: 1, ref: 'master', sha: 'xxx', tag: false) - end - - it 'correctly replicates finished_at by created_at' do - expect(deployments.last.created_at).not_to be_nil - expect(deployments.last.finished_at).to be_nil - - migrate! - - expect(deployments.last.created_at).not_to be_nil - expect(deployments.last.finished_at).to eq(deployments.last.created_at) - end - end - - context 'when a deployment is running' do - before do - namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1') - projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: 123) - environments.create!(id: 1, name: 'production', slug: 'production', project_id: 1) - deployments.create!(id: 1, iid: 1, project_id: 1, environment_id: 1, ref: 'master', sha: 'xxx', tag: false, status: 1) - end - - it 'does not fill finished_at' do - expect(deployments.last.created_at).not_to be_nil - expect(deployments.last.finished_at).to be_nil - - migrate! - - expect(deployments.last.created_at).not_to be_nil - expect(deployments.last.finished_at).to be_nil - end - end - end - - context 'when a deployment row does has a value on finished_at' do - let(:finished_at) { '2018-10-30 11:12:02 UTC' } - - before do - namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1') - projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: 123) - environments.create!(id: 1, name: 'production', slug: 'production', project_id: 1) - deployments.create!(id: 1, iid: 1, project_id: 1, environment_id: 1, ref: 'master', sha: 'xxx', tag: false, finished_at: finished_at) - end - - it 'does not affect existing value' do - expect(deployments.last.created_at).not_to be_nil - expect(deployments.last.finished_at).not_to be_nil - - migrate! - - expect(deployments.last.created_at).not_to be_nil - expect(deployments.last.finished_at).to eq(finished_at) - end - end -end diff --git a/spec/migrations/fill_file_store_spec.rb b/spec/migrations/fill_file_store_spec.rb deleted file mode 100644 index 732fdc2a0bb..00000000000 --- a/spec/migrations/fill_file_store_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180424151928_fill_file_store') - -describe FillFileStore do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:builds) { table(:ci_builds) } - let(:job_artifacts) { table(:ci_job_artifacts) } - let(:lfs_objects) { table(:lfs_objects) } - let(:uploads) { table(:uploads) } - - before do - namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1') - projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 123) - builds.create!(id: 1) - - ## - # Create rows that have nullfied `file_store` column - job_artifacts.create!(project_id: 123, job_id: 1, file_type: 1, file_store: nil) - lfs_objects.create!(oid: 123, size: 10, file: 'file_name', file_store: nil) - uploads.create!(size: 10, path: 'path', uploader: 'uploader', mount_point: 'file_name', store: nil) - end - - it 'correctly migrates nullified file_store/store column', :sidekiq_might_not_need_inline do - expect(job_artifacts.where(file_store: nil).count).to eq(1) - expect(lfs_objects.where(file_store: nil).count).to eq(1) - expect(uploads.where(store: nil).count).to eq(1) - - expect(job_artifacts.where(file_store: 1).count).to eq(0) - expect(lfs_objects.where(file_store: 1).count).to eq(0) - expect(uploads.where(store: 1).count).to eq(0) - - migrate! - - expect(job_artifacts.where(file_store: nil).count).to eq(0) - expect(lfs_objects.where(file_store: nil).count).to eq(0) - expect(uploads.where(store: nil).count).to eq(0) - - expect(job_artifacts.where(file_store: 1).count).to eq(1) - expect(lfs_objects.where(file_store: 1).count).to eq(1) - expect(uploads.where(store: 1).count).to eq(1) - end -end diff --git a/spec/migrations/generate_missing_routes_spec.rb b/spec/migrations/generate_missing_routes_spec.rb deleted file mode 100644 index bc7cd3bd55e..00000000000 --- a/spec/migrations/generate_missing_routes_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180702134423_generate_missing_routes.rb') - -describe GenerateMissingRoutes do - describe '#up' do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:routes) { table(:routes) } - - it 'creates routes for projects without a route' do - namespace = namespaces.create!(name: 'GitLab', path: 'gitlab', type: 'Group') - - routes.create!( - path: 'gitlab', - source_type: 'Namespace', - source_id: namespace.id - ) - - project = projects.create!( - name: 'GitLab CE', - path: 'gitlab-ce', - namespace_id: namespace.id - ) - - described_class.new.up - - route = routes.find_by(source_type: 'Project') - - expect(route.source_id).to eq(project.id) - expect(route.path).to eq("gitlab/gitlab-ce-#{project.id}") - end - - it 'creates routes for namespaces without a route' do - namespace = namespaces.create!(name: 'GitLab', path: 'gitlab') - - described_class.new.up - - route = routes.find_by(source_type: 'Namespace') - - expect(route.source_id).to eq(namespace.id) - expect(route.path).to eq("gitlab-#{namespace.id}") - end - - it 'does not create routes for namespaces that already have a route' do - namespace = namespaces.create!(name: 'GitLab', path: 'gitlab') - - routes.create!( - path: 'gitlab', - source_type: 'Namespace', - source_id: namespace.id - ) - - described_class.new.up - - expect(routes.count).to eq(1) - end - - it 'does not create routes for projects that already have a route' do - namespace = namespaces.create!(name: 'GitLab', path: 'gitlab') - - routes.create!( - path: 'gitlab', - source_type: 'Namespace', - source_id: namespace.id - ) - - project = projects.create!( - name: 'GitLab CE', - path: 'gitlab-ce', - namespace_id: namespace.id - ) - - routes.create!( - path: 'gitlab/gitlab-ce', - source_type: 'Project', - source_id: project.id - ) - - described_class.new.up - - expect(routes.count).to eq(2) - end - end -end diff --git a/spec/migrations/import_common_metrics_spec.rb b/spec/migrations/import_common_metrics_spec.rb deleted file mode 100644 index 8c28b46cb38..00000000000 --- a/spec/migrations/import_common_metrics_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180831164910_import_common_metrics.rb') - -describe ImportCommonMetrics do - describe '#up' do - it "imports all prometheus metrics" do - expect(PrometheusMetric.common).to be_empty - - migrate! - - expect(PrometheusMetric.common).not_to be_empty - end - end -end diff --git a/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb b/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb deleted file mode 100644 index a3ed9b722d5..00000000000 --- a/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb') - -describe MigrateClusterConfigureWorkerSidekiqQueue, :redis do - include Gitlab::Database::MigrationHelpers - include StubWorker - - context 'when there are jobs in the queue' do - it 'correctly migrates queue when migrating up' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'gcp_cluster:cluster_platform_configure').perform_async('Something', [1]) - stub_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1]) - - described_class.new.up - - expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 0 - expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 2 - end - end - - it 'does not affect other queues under the same namespace' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'gcp_cluster:cluster_install_app').perform_async('Something', [1]) - stub_worker(queue: 'gcp_cluster:cluster_provision').perform_async('Something', [1]) - stub_worker(queue: 'gcp_cluster:cluster_wait_for_app_installation').perform_async('Something', [1]) - stub_worker(queue: 'gcp_cluster:wait_for_cluster_creation').perform_async('Something', [1]) - stub_worker(queue: 'gcp_cluster:cluster_wait_for_ingress_ip_address').perform_async('Something', [1]) - stub_worker(queue: 'gcp_cluster:cluster_project_configure').perform_async('Something', [1]) - - described_class.new.up - - expect(sidekiq_queue_length('gcp_cluster:cluster_install_app')).to eq 1 - expect(sidekiq_queue_length('gcp_cluster:cluster_provision')).to eq 1 - expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_app_installation')).to eq 1 - expect(sidekiq_queue_length('gcp_cluster:wait_for_cluster_creation')).to eq 1 - expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_ingress_ip_address')).to eq 1 - expect(sidekiq_queue_length('gcp_cluster:cluster_project_configure')).to eq 1 - end - end - - it 'correctly migrates queue when migrating down' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1]) - - described_class.new.down - - expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 1 - expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 0 - end - end - end - - context 'when there are no jobs in the queues' do - it 'does not raise error when migrating up' do - expect { described_class.new.up }.not_to raise_error - end - - it 'does not raise error when migrating down' do - expect { described_class.new.down }.not_to raise_error - end - end -end diff --git a/spec/migrations/migrate_create_trace_artifact_sidekiq_queue_spec.rb b/spec/migrations/migrate_create_trace_artifact_sidekiq_queue_spec.rb deleted file mode 100644 index 6e0bd487d1f..00000000000 --- a/spec/migrations/migrate_create_trace_artifact_sidekiq_queue_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180306074045_migrate_create_trace_artifact_sidekiq_queue.rb') - -describe MigrateCreateTraceArtifactSidekiqQueue, :redis do - include Gitlab::Database::MigrationHelpers - include StubWorker - - context 'when there are jobs in the queues' do - it 'correctly migrates queue when migrating up' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'pipeline_default:create_trace_artifact').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_background:archive_trace').perform_async('Something', [1]) - - described_class.new.up - - expect(sidekiq_queue_length('pipeline_default:create_trace_artifact')).to eq 0 - expect(sidekiq_queue_length('pipeline_background:archive_trace')).to eq 2 - end - end - - it 'does not affect other queues under the same namespace' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'pipeline_default:build_coverage').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_default:build_trace_sections').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_default:pipeline_metrics').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_default:pipeline_notification').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_default:update_head_pipeline_for_merge_request').perform_async('Something', [1]) - - described_class.new.up - - expect(sidekiq_queue_length('pipeline_default:build_coverage')).to eq 1 - expect(sidekiq_queue_length('pipeline_default:build_trace_sections')).to eq 1 - expect(sidekiq_queue_length('pipeline_default:pipeline_metrics')).to eq 1 - expect(sidekiq_queue_length('pipeline_default:pipeline_notification')).to eq 1 - expect(sidekiq_queue_length('pipeline_default:update_head_pipeline_for_merge_request')).to eq 1 - end - end - - it 'correctly migrates queue when migrating down' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'pipeline_background:archive_trace').perform_async('Something', [1]) - - described_class.new.down - - expect(sidekiq_queue_length('pipeline_default:create_trace_artifact')).to eq 1 - expect(sidekiq_queue_length('pipeline_background:archive_trace')).to eq 0 - end - end - end - - context 'when there are no jobs in the queues' do - it 'does not raise error when migrating up' do - expect { described_class.new.up }.not_to raise_error - end - - it 'does not raise error when migrating down' do - expect { described_class.new.down }.not_to raise_error - end - end -end diff --git a/spec/migrations/migrate_forbidden_redirect_uris_spec.rb b/spec/migrations/migrate_forbidden_redirect_uris_spec.rb deleted file mode 100644 index 7c3cc9f07c8..00000000000 --- a/spec/migrations/migrate_forbidden_redirect_uris_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181026091631_migrate_forbidden_redirect_uris.rb') - -describe MigrateForbiddenRedirectUris do - let(:oauth_application) { table(:oauth_applications) } - let(:oauth_access_grant) { table(:oauth_access_grants) } - - let!(:control_app) { oauth_application.create(random_params) } - let!(:control_access_grant) { oauth_application.create(random_params) } - let!(:forbidden_js_app) { oauth_application.create(random_params.merge(redirect_uri: 'javascript://alert()')) } - let!(:forbidden_vb_app) { oauth_application.create(random_params.merge(redirect_uri: 'VBSCRIPT://alert()')) } - let!(:forbidden_access_grant) { oauth_application.create(random_params.merge(redirect_uri: 'vbscript://alert()')) } - - context 'oauth application' do - it 'migrates forbidden javascript URI' do - expect { migrate! }.to change { forbidden_js_app.reload.redirect_uri }.to('http://forbidden-scheme-has-been-overwritten') - end - - it 'migrates forbidden VBScript URI' do - expect { migrate! }.to change { forbidden_vb_app.reload.redirect_uri }.to('http://forbidden-scheme-has-been-overwritten') - end - - it 'does not migrate a valid URI' do - expect { migrate! }.not_to change { control_app.reload.redirect_uri } - end - end - - context 'access grant' do - it 'migrates forbidden VBScript URI' do - expect { migrate! }.to change { forbidden_access_grant.reload.redirect_uri }.to('http://forbidden-scheme-has-been-overwritten') - end - - it 'does not migrate a valid URI' do - expect { migrate! }.not_to change { control_access_grant.reload.redirect_uri } - end - end - - def random_params - { - name: 'test', - secret: 'test', - uid: Doorkeeper::OAuth::Helpers::UniqueToken.generate, - redirect_uri: 'http://valid.com' - } - end -end diff --git a/spec/migrations/migrate_legacy_artifacts_to_job_artifacts_spec.rb b/spec/migrations/migrate_legacy_artifacts_to_job_artifacts_spec.rb deleted file mode 100644 index 5133afdf5b0..00000000000 --- a/spec/migrations/migrate_legacy_artifacts_to_job_artifacts_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180816161409_migrate_legacy_artifacts_to_job_artifacts.rb') - -describe MigrateLegacyArtifactsToJobArtifacts do - let(:migration_class) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts } - let(:migration_name) { migration_class.to_s.demodulize } - - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:pipelines) { table(:ci_pipelines) } - let(:jobs) { table(:ci_builds) } - let(:job_artifacts) { table(:ci_job_artifacts) } - let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') } - let(:project) { projects.create!(name: 'gitlab', path: 'gitlab-ce', namespace_id: namespace.id) } - let(:pipeline) { pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a') } - let(:archive_file_type) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts::ARCHIVE_FILE_TYPE } - let(:metadata_file_type) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts::METADATA_FILE_TYPE } - let(:local_store) { ::ObjectStorage::Store::LOCAL } - let(:remote_store) { ::ObjectStorage::Store::REMOTE } - let(:legacy_location) { Gitlab::BackgroundMigration::MigrateLegacyArtifacts::LEGACY_PATH_FILE_LOCATION } - - context 'when legacy artifacts exist' do - before do - jobs.create!(id: 1, commit_id: pipeline.id, project_id: project.id, status: :success, artifacts_file: 'archive.zip') - jobs.create!(id: 2, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_metadata: 'metadata.gz') - jobs.create!(id: 3, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_file: 'archive.zip', artifacts_metadata: 'metadata.gz') - jobs.create!(id: 4, commit_id: pipeline.id, project_id: project.id, status: :running) - jobs.create!(id: 5, commit_id: pipeline.id, project_id: project.id, status: :success, artifacts_file: 'archive.zip', artifacts_file_store: remote_store, artifacts_metadata: 'metadata.gz') - jobs.create!(id: 6, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_file: 'archive.zip', artifacts_metadata: 'metadata.gz') - end - - it 'schedules a background migration' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(migration_name).to be_scheduled_delayed_migration(5.minutes, 1, 6) - expect(BackgroundMigrationWorker.jobs.size).to eq 1 - end - end - end - - it 'migrates legacy artifacts to ci_job_artifacts table', :sidekiq_might_not_need_inline do - migrate! - - expect(job_artifacts.order(:job_id, :file_type).pluck('project_id, job_id, file_type, file_store, size, expire_at, file, file_sha256, file_location')) - .to eq([[project.id, 1, archive_file_type, local_store, nil, nil, 'archive.zip', nil, legacy_location], - [project.id, 3, archive_file_type, local_store, nil, nil, 'archive.zip', nil, legacy_location], - [project.id, 3, metadata_file_type, local_store, nil, nil, 'metadata.gz', nil, legacy_location], - [project.id, 5, archive_file_type, remote_store, nil, nil, 'archive.zip', nil, legacy_location], - [project.id, 5, metadata_file_type, local_store, nil, nil, 'metadata.gz', nil, legacy_location], - [project.id, 6, archive_file_type, local_store, nil, nil, 'archive.zip', nil, legacy_location], - [project.id, 6, metadata_file_type, local_store, nil, nil, 'metadata.gz', nil, legacy_location]]) - end - end - - context 'when legacy artifacts do not exist' do - before do - jobs.create!(id: 1, commit_id: pipeline.id, project_id: project.id, status: :success) - jobs.create!(id: 2, commit_id: pipeline.id, project_id: project.id, status: :failed, artifacts_metadata: 'metadata.gz') - end - - it 'does not schedule background migrations' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(BackgroundMigrationWorker.jobs.size).to eq 0 - end - end - end - end -end diff --git a/spec/migrations/migrate_null_wiki_access_levels_spec.rb b/spec/migrations/migrate_null_wiki_access_levels_spec.rb deleted file mode 100644 index f4753f67e17..00000000000 --- a/spec/migrations/migrate_null_wiki_access_levels_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180809195358_migrate_null_wiki_access_levels.rb') - -describe MigrateNullWikiAccessLevels do - let(:namespaces) { table('namespaces') } - let(:projects) { table(:projects) } - let(:project_features) { table(:project_features) } - let(:migration) { described_class.new } - - before do - namespace = namespaces.create(name: 'foo', path: 'foo') - - projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1', namespace_id: namespace.id) - projects.create!(id: 2, name: 'gitlab2', path: 'gitlab2', namespace_id: namespace.id) - projects.create!(id: 3, name: 'gitlab3', path: 'gitlab3', namespace_id: namespace.id) - - project_features.create!(id: 1, project_id: 1, wiki_access_level: nil) - project_features.create!(id: 2, project_id: 2, wiki_access_level: 10) - project_features.create!(id: 3, project_id: 3, wiki_access_level: 20) - end - - describe '#up' do - it 'migrates existing project_features with wiki_access_level NULL to 20' do - expect { migration.up }.to change { project_features.where(wiki_access_level: 20).count }.by(1) - end - end -end diff --git a/spec/migrations/migrate_object_storage_upload_sidekiq_queue_spec.rb b/spec/migrations/migrate_object_storage_upload_sidekiq_queue_spec.rb deleted file mode 100644 index aa4951b2f14..00000000000 --- a/spec/migrations/migrate_object_storage_upload_sidekiq_queue_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180603190921_migrate_object_storage_upload_sidekiq_queue.rb') - -describe MigrateObjectStorageUploadSidekiqQueue, :redis do - include Gitlab::Database::MigrationHelpers - include StubWorker - - context 'when there are jobs in the queue' do - it 'correctly migrates queue when migrating up' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'object_storage_upload').perform_async('Something', [1]) - stub_worker(queue: 'object_storage:object_storage_background_move').perform_async('Something', [1]) - - described_class.new.up - - expect(sidekiq_queue_length('object_storage_upload')).to eq 0 - expect(sidekiq_queue_length('object_storage:object_storage_background_move')).to eq 2 - end - end - end - - context 'when there are no jobs in the queues' do - it 'does not raise error when migrating up' do - expect { described_class.new.up }.not_to raise_error - end - end -end diff --git a/spec/migrations/migrate_update_head_pipeline_for_merge_request_sidekiq_queue_spec.rb b/spec/migrations/migrate_update_head_pipeline_for_merge_request_sidekiq_queue_spec.rb deleted file mode 100644 index 204c38b3fc5..00000000000 --- a/spec/migrations/migrate_update_head_pipeline_for_merge_request_sidekiq_queue_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180307012445_migrate_update_head_pipeline_for_merge_request_sidekiq_queue.rb') - -describe MigrateUpdateHeadPipelineForMergeRequestSidekiqQueue, :redis do - include Gitlab::Database::MigrationHelpers - include StubWorker - - context 'when there are jobs in the queues' do - it 'correctly migrates queue when migrating up' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'pipeline_default:update_head_pipeline_for_merge_request').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_processing:update_head_pipeline_for_merge_request').perform_async('Something', [1]) - - described_class.new.up - - expect(sidekiq_queue_length('pipeline_default:update_head_pipeline_for_merge_request')).to eq 0 - expect(sidekiq_queue_length('pipeline_processing:update_head_pipeline_for_merge_request')).to eq 2 - end - end - - it 'does not affect other queues under the same namespace' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'pipeline_default:build_coverage').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_default:build_trace_sections').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_default:pipeline_metrics').perform_async('Something', [1]) - stub_worker(queue: 'pipeline_default:pipeline_notification').perform_async('Something', [1]) - - described_class.new.up - - expect(sidekiq_queue_length('pipeline_default:build_coverage')).to eq 1 - expect(sidekiq_queue_length('pipeline_default:build_trace_sections')).to eq 1 - expect(sidekiq_queue_length('pipeline_default:pipeline_metrics')).to eq 1 - expect(sidekiq_queue_length('pipeline_default:pipeline_notification')).to eq 1 - end - end - - it 'correctly migrates queue when migrating down' do - Sidekiq::Testing.disable! do - stub_worker(queue: 'pipeline_processing:update_head_pipeline_for_merge_request').perform_async('Something', [1]) - - described_class.new.down - - expect(sidekiq_queue_length('pipeline_default:update_head_pipeline_for_merge_request')).to eq 1 - expect(sidekiq_queue_length('pipeline_processing:update_head_pipeline_for_merge_request')).to eq 0 - end - end - end - - context 'when there are no jobs in the queues' do - it 'does not raise error when migrating up' do - expect { described_class.new.up }.not_to raise_error - end - - it 'does not raise error when migrating down' do - expect { described_class.new.down }.not_to raise_error - end - end -end diff --git a/spec/migrations/remove_empty_extern_uid_auth0_identities_spec.rb b/spec/migrations/remove_empty_extern_uid_auth0_identities_spec.rb deleted file mode 100644 index 5be8706cacf..00000000000 --- a/spec/migrations/remove_empty_extern_uid_auth0_identities_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180220150310_remove_empty_extern_uid_auth0_identities.rb') - -describe RemoveEmptyExternUidAuth0Identities do - let(:identities) { table(:identities) } - - before do - identities.create(provider: 'auth0', extern_uid: '') - identities.create(provider: 'auth0', extern_uid: 'valid') - identities.create(provider: 'github', extern_uid: '') - - migrate! - end - - it 'leaves the correct auth0 identity' do - expect(identities.where(provider: 'auth0').pluck(:extern_uid)).to eq(['valid']) - end - - it 'leaves the correct github identity' do - expect(identities.where(provider: 'github').count).to eq(1) - end -end diff --git a/spec/migrations/remove_redundant_pipeline_stages_spec.rb b/spec/migrations/remove_redundant_pipeline_stages_spec.rb deleted file mode 100644 index 9bcbb6022a7..00000000000 --- a/spec/migrations/remove_redundant_pipeline_stages_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180119121225_remove_redundant_pipeline_stages.rb') - -describe RemoveRedundantPipelineStages do - let(:projects) { table(:projects) } - let(:pipelines) { table(:ci_pipelines) } - let(:stages) { table(:ci_stages) } - let(:builds) { table(:ci_builds) } - - before do - projects.create!(id: 123, name: 'gitlab', path: 'gitlab-ce') - pipelines.create!(id: 234, project_id: 123, ref: 'master', sha: 'adf43c3a') - - stages.create!(id: 6, project_id: 123, pipeline_id: 234, name: 'build') - stages.create!(id: 10, project_id: 123, pipeline_id: 234, name: 'build') - stages.create!(id: 21, project_id: 123, pipeline_id: 234, name: 'build') - stages.create!(id: 41, project_id: 123, pipeline_id: 234, name: 'test') - stages.create!(id: 62, project_id: 123, pipeline_id: 234, name: 'test') - stages.create!(id: 102, project_id: 123, pipeline_id: 234, name: 'deploy') - - builds.create!(id: 1, commit_id: 234, project_id: 123, stage_id: 10) - builds.create!(id: 2, commit_id: 234, project_id: 123, stage_id: 21) - builds.create!(id: 3, commit_id: 234, project_id: 123, stage_id: 21) - builds.create!(id: 4, commit_id: 234, project_id: 123, stage_id: 41) - builds.create!(id: 5, commit_id: 234, project_id: 123, stage_id: 62) - builds.create!(id: 6, commit_id: 234, project_id: 123, stage_id: 102) - end - - it 'removes ambiguous stages and preserves builds' do - expect(stages.all.count).to eq 6 - expect(builds.all.count).to eq 6 - - migrate! - - expect(stages.all.count).to eq 1 - expect(builds.all.count).to eq 6 - expect(builds.all.pluck(:stage_id).compact).to eq [102] - end - - it 'retries when incorrectly added index exception is caught' do - allow_any_instance_of(described_class) - .to receive(:remove_redundant_pipeline_stages!) - - expect_any_instance_of(described_class) - .to receive(:remove_outdated_index!) - .exactly(100).times.and_call_original - - expect { migrate! } - .to raise_error StandardError, /Failed to add an unique index/ - end - - it 'does not retry when unknown exception is being raised' do - allow(subject).to receive(:remove_outdated_index!) - expect(subject).to receive(:remove_redundant_pipeline_stages!).once - allow(subject).to receive(:add_unique_index!).and_raise(StandardError) - - expect { subject.up(attempts: 3) }.to raise_error StandardError - end -end diff --git a/spec/migrations/reschedule_builds_stages_migration_spec.rb b/spec/migrations/reschedule_builds_stages_migration_spec.rb deleted file mode 100644 index 18ea16f97bc..00000000000 --- a/spec/migrations/reschedule_builds_stages_migration_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180405101928_reschedule_builds_stages_migration') - -describe RescheduleBuildsStagesMigration do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:pipelines) { table(:ci_pipelines) } - let(:stages) { table(:ci_stages) } - let(:jobs) { table(:ci_builds) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - - namespaces.create(id: 12, name: 'gitlab-org', path: 'gitlab-org') - projects.create!(id: 123, namespace_id: 12, name: 'gitlab', path: 'gitlab') - pipelines.create!(id: 1, project_id: 123, ref: 'master', sha: 'adf43c3a') - stages.create!(id: 1, project_id: 123, pipeline_id: 1, name: 'test') - - jobs.create!(id: 11, commit_id: 1, project_id: 123, stage_id: nil) - jobs.create!(id: 206, commit_id: 1, project_id: 123, stage_id: nil) - jobs.create!(id: 3413, commit_id: 1, project_id: 123, stage_id: nil) - jobs.create!(id: 4109, commit_id: 1, project_id: 123, stage_id: 1) - end - - it 'schedules delayed background migrations in batches in bulk' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 11, 11) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 206, 206) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(15.minutes, 3413, 3413) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 - end - end - end -end diff --git a/spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb b/spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb deleted file mode 100644 index dcb31dff9b7..00000000000 --- a/spec/migrations/reschedule_commits_count_for_merge_request_diff_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'migrate', '20180309121820_reschedule_commits_count_for_merge_request_diff') - -describe RescheduleCommitsCountForMergeRequestDiff do - let(:merge_request_diffs) { table(:merge_request_diffs) } - let(:merge_requests) { table(:merge_requests) } - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 1) - - namespaces.create!(id: 1, name: 'gitlab', path: 'gitlab') - - projects.create!(id: 1, namespace_id: 1) - - 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) - merge_request_diffs.create!(id: 2, merge_request_id: 1) - merge_request_diffs.create!(id: 3, merge_request_id: 1, commits_count: 0) - merge_request_diffs.create!(id: 4, merge_request_id: 1) - 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 -end diff --git a/spec/migrations/schedule_digest_personal_access_tokens_spec.rb b/spec/migrations/schedule_digest_personal_access_tokens_spec.rb deleted file mode 100644 index d8e1b089d31..00000000000 --- a/spec/migrations/schedule_digest_personal_access_tokens_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180913142237_schedule_digest_personal_access_tokens.rb') - -describe ScheduleDigestPersonalAccessTokens do - let(:personal_access_tokens) { table(:personal_access_tokens) } - let(:users) { table(:users) } - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 4) - - users.create(id: 1, email: 'user@example.com', projects_limit: 10) - - personal_access_tokens.create!(id: 1, user_id: 1, name: 'pat-01', token: 'token-01') - personal_access_tokens.create!(id: 2, user_id: 1, name: 'pat-02', token: 'token-02') - personal_access_tokens.create!(id: 3, user_id: 1, name: 'pat-03', token_digest: 'token_digest') - personal_access_tokens.create!(id: 4, user_id: 1, name: 'pat-04', token: 'token-04') - personal_access_tokens.create!(id: 5, user_id: 1, name: 'pat-05', token: 'token-05') - personal_access_tokens.create!(id: 6, user_id: 1, name: 'pat-06', token: 'token-06') - end - - it 'correctly schedules background migrations' do - Sidekiq::Testing.fake! do - migrate! - - expect(described_class::MIGRATION).to( - be_scheduled_delayed_migration( - 5.minutes, 'PersonalAccessToken', 'token', 'token_digest', 1, 5)) - expect(described_class::MIGRATION).to( - be_scheduled_delayed_migration( - 10.minutes, 'PersonalAccessToken', 'token', 'token_digest', 6, 6)) - expect(BackgroundMigrationWorker.jobs.size).to eq 2 - end - end - - it 'schedules background migrations', :sidekiq_might_not_need_inline do - perform_enqueued_jobs do - plain_text_token = 'token IS NOT NULL' - - expect(personal_access_tokens.where(plain_text_token).count).to eq 5 - - migrate! - - expect(personal_access_tokens.where(plain_text_token).count).to eq 0 - end - end -end diff --git a/spec/migrations/schedule_runners_token_encryption_spec.rb b/spec/migrations/schedule_runners_token_encryption_spec.rb deleted file mode 100644 index 4121a8409b4..00000000000 --- a/spec/migrations/schedule_runners_token_encryption_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181121111200_schedule_runners_token_encryption') - -describe ScheduleRunnersTokenEncryption do - let(:settings) { table(:application_settings) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:runners) { table(:ci_runners) } - - before do - stub_const("#{described_class.name}::BATCH_SIZE", 1) - - settings.create!(id: 1, runners_registration_token: 'plain-text-token1') - namespaces.create!(id: 11, name: 'gitlab', path: 'gitlab-org', runners_token: 'my-token1') - namespaces.create!(id: 12, name: 'gitlab', path: 'gitlab-org', runners_token: 'my-token2') - projects.create!(id: 111, namespace_id: 11, name: 'gitlab', path: 'gitlab-ce', runners_token: 'my-token1') - projects.create!(id: 114, namespace_id: 11, name: 'gitlab', path: 'gitlab-ce', runners_token: 'my-token2') - runners.create!(id: 201, runner_type: 1, token: 'plain-text-token1') - runners.create!(id: 202, runner_type: 1, token: 'plain-text-token2') - end - - it 'schedules runners token encryption migration for multiple resources' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'settings', 1, 1) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'namespace', 11, 11) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(8.minutes, 'namespace', 12, 12) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'project', 111, 111) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(8.minutes, 'project', 114, 114) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 'runner', 201, 201) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(8.minutes, 'runner', 202, 202) - expect(BackgroundMigrationWorker.jobs.size).to eq 7 - end - end - end -end diff --git a/spec/migrations/schedule_set_confidential_note_events_on_webhooks_spec.rb b/spec/migrations/schedule_set_confidential_note_events_on_webhooks_spec.rb deleted file mode 100644 index ea1e16a0a35..00000000000 --- a/spec/migrations/schedule_set_confidential_note_events_on_webhooks_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180104131052_schedule_set_confidential_note_events_on_webhooks.rb') - -describe ScheduleSetConfidentialNoteEventsOnWebhooks do - let(:web_hooks_table) { table(:web_hooks) } - let(:migration_class) { Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnWebhooks } - let(:migration_name) { migration_class.to_s.demodulize } - - let!(:web_hook_1) { web_hooks_table.create!(confidential_note_events: nil, note_events: true) } - let!(:web_hook_2) { web_hooks_table.create!(confidential_note_events: nil, note_events: true) } - let!(:web_hook_migrated) { web_hooks_table.create!(confidential_note_events: true, note_events: true) } - let!(:web_hook_skip) { web_hooks_table.create!(confidential_note_events: nil, note_events: false) } - let!(:web_hook_new) { web_hooks_table.create!(confidential_note_events: false, note_events: true) } - let!(:web_hook_4) { web_hooks_table.create!(confidential_note_events: nil, note_events: true) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - end - - it 'schedules background migrations at correct time' do - Sidekiq::Testing.fake! do - Timecop.freeze do - migrate! - - expect(migration_name).to be_scheduled_delayed_migration(5.minutes, web_hook_1.id, web_hook_1.id) - expect(migration_name).to be_scheduled_delayed_migration(10.minutes, web_hook_2.id, web_hook_2.id) - expect(migration_name).to be_scheduled_delayed_migration(15.minutes, web_hook_4.id, web_hook_4.id) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 - end - end - end - - it 'correctly processes web hooks', :sidekiq_might_not_need_inline do - perform_enqueued_jobs do - expect(web_hooks_table.where(confidential_note_events: nil).count).to eq 4 - expect(web_hooks_table.where(confidential_note_events: true).count).to eq 1 - - migrate! - - expect(web_hooks_table.where(confidential_note_events: nil).count).to eq 1 - expect(web_hooks_table.where(confidential_note_events: true).count).to eq 4 - end - end -end diff --git a/spec/migrations/schedule_stages_index_migration_spec.rb b/spec/migrations/schedule_stages_index_migration_spec.rb deleted file mode 100644 index 5ca857087e7..00000000000 --- a/spec/migrations/schedule_stages_index_migration_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180420080616_schedule_stages_index_migration') - -describe ScheduleStagesIndexMigration do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:pipelines) { table(:ci_pipelines) } - let(:stages) { table(:ci_stages) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - - namespaces.create(id: 12, name: 'gitlab-org', path: 'gitlab-org') - projects.create!(id: 123, namespace_id: 12, name: 'gitlab', path: 'gitlab') - pipelines.create!(id: 1, project_id: 123, ref: 'master', sha: 'adf43c3a') - stages.create!(id: 121, project_id: 123, pipeline_id: 1, name: 'build') - stages.create!(id: 122, project_id: 123, pipeline_id: 1, name: 'test') - stages.create!(id: 123, project_id: 123, pipeline_id: 1, name: 'deploy') - end - - it 'schedules delayed background migrations in batches' do - Sidekiq::Testing.fake! do - Timecop.freeze do - expect(stages.all).to all(have_attributes(position: be_nil)) - - migrate! - - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 121, 121) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 122, 122) - expect(described_class::MIGRATION).to be_scheduled_delayed_migration(15.minutes, 123, 123) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 - end - end - end -end diff --git a/spec/migrations/schedule_to_archive_legacy_traces_spec.rb b/spec/migrations/schedule_to_archive_legacy_traces_spec.rb deleted file mode 100644 index 69c4b15a74f..00000000000 --- a/spec/migrations/schedule_to_archive_legacy_traces_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20180529152628_schedule_to_archive_legacy_traces') - -describe ScheduleToArchiveLegacyTraces do - include TraceHelpers - - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:builds) { table(:ci_builds) } - let(:job_artifacts) { table(:ci_job_artifacts) } - - before do - namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1') - projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 123) - @build_success = builds.create!(id: 1, project_id: 123, status: 'success', type: 'Ci::Build') - @build_failed = builds.create!(id: 2, project_id: 123, status: 'failed', type: 'Ci::Build') - @builds_canceled = builds.create!(id: 3, project_id: 123, status: 'canceled', type: 'Ci::Build') - @build_running = builds.create!(id: 4, project_id: 123, status: 'running', type: 'Ci::Build') - - create_legacy_trace(@build_success, 'This job is done') - create_legacy_trace(@build_failed, 'This job is done') - create_legacy_trace(@builds_canceled, 'This job is done') - create_legacy_trace(@build_running, 'This job is not done yet') - end - - it 'correctly archive legacy traces', :sidekiq_might_not_need_inline do - expect(job_artifacts.count).to eq(0) - expect(File.exist?(legacy_trace_path(@build_success))).to be_truthy - expect(File.exist?(legacy_trace_path(@build_failed))).to be_truthy - expect(File.exist?(legacy_trace_path(@builds_canceled))).to be_truthy - expect(File.exist?(legacy_trace_path(@build_running))).to be_truthy - - migrate! - - expect(job_artifacts.count).to eq(3) - expect(File.exist?(legacy_trace_path(@build_success))).to be_falsy - expect(File.exist?(legacy_trace_path(@build_failed))).to be_falsy - expect(File.exist?(legacy_trace_path(@builds_canceled))).to be_falsy - expect(File.exist?(legacy_trace_path(@build_running))).to be_truthy - expect(File.exist?(archived_trace_path(job_artifacts.find_by(job_id: @build_success.id)))).to be_truthy - expect(File.exist?(archived_trace_path(job_artifacts.find_by(job_id: @build_failed.id)))).to be_truthy - expect(File.exist?(archived_trace_path(job_artifacts.find_by(job_id: @builds_canceled.id)))).to be_truthy - expect(job_artifacts.where(job_id: @build_running.id)).not_to be_exist - end -end diff --git a/spec/migrations/seed_repository_storages_weighted_spec.rb b/spec/migrations/seed_repository_storages_weighted_spec.rb new file mode 100644 index 00000000000..9a68ff5fb2f --- /dev/null +++ b/spec/migrations/seed_repository_storages_weighted_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20200526000407_seed_repository_storages_weighted.rb') + +describe SeedRepositoryStoragesWeighted do + let(:storages) { { "foo" => {}, "baz" => {} } } + let(:application_settings) do + table(:application_settings).tap do |klass| + klass.class_eval do + serialize :repository_storages + end + end + end + + before do + allow(Gitlab.config.repositories).to receive(:storages).and_return(storages) + end + + let(:application_setting) { application_settings.create } + let(:repository_storages) { ["foo"] } + + it 'correctly schedules background migrations' do + application_setting.repository_storages = repository_storages + application_setting.save! + + migrate! + + expect(application_settings.find(application_setting.id).repository_storages_weighted).to eq({ "foo" => 100, "baz" => 0 }) + end +end diff --git a/spec/migrations/steal_fill_store_upload_spec.rb b/spec/migrations/steal_fill_store_upload_spec.rb deleted file mode 100644 index b5e3de1864c..00000000000 --- a/spec/migrations/steal_fill_store_upload_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181105201455_steal_fill_store_upload.rb') - -describe StealFillStoreUpload do - let(:uploads) { table(:uploads) } - - describe '#up' do - it 'steals the FillStoreUpload background migration' do - expect(Gitlab::BackgroundMigration).to receive(:steal).with('FillStoreUpload').and_call_original - - migrate! - end - - it 'does not run migration if not needed' do - uploads.create(size: 100.kilobytes, - uploader: 'AvatarUploader', - path: 'uploads/-/system/avatar.jpg', - store: 1) - - expect_any_instance_of(Gitlab::BackgroundMigration::FillStoreUpload).not_to receive(:perform) - - migrate! - end - - it 'ensures all rows are migrated' do - uploads.create(size: 100.kilobytes, - uploader: 'AvatarUploader', - path: 'uploads/-/system/avatar.jpg', - store: nil) - - expect_any_instance_of(Gitlab::BackgroundMigration::FillStoreUpload).to receive(:perform).and_call_original - - expect do - migrate! - end.to change { uploads.where(store: nil).count }.from(1).to(0) - end - end -end diff --git a/spec/migrations/update_project_import_visibility_level_spec.rb b/spec/migrations/update_project_import_visibility_level_spec.rb deleted file mode 100644 index f8439fc4204..00000000000 --- a/spec/migrations/update_project_import_visibility_level_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require Rails.root.join('db', 'post_migrate', '20181219130552_update_project_import_visibility_level.rb') - -describe UpdateProjectImportVisibilityLevel do - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - let(:project) { projects.find_by_name(name) } - - before do - stub_const("#{described_class}::BATCH_SIZE", 1) - end - - context 'private visibility level' do - let(:name) { 'private-public' } - - it 'updates the project visibility' do - create_namespace(name, Gitlab::VisibilityLevel::PRIVATE) - create_project(name, Gitlab::VisibilityLevel::PUBLIC) - - expect { migrate! }.to change { project.reload.visibility_level }.to(Gitlab::VisibilityLevel::PRIVATE) - end - end - - context 'internal visibility level' do - let(:name) { 'internal-public' } - - it 'updates the project visibility' do - create_namespace(name, Gitlab::VisibilityLevel::INTERNAL) - create_project(name, Gitlab::VisibilityLevel::PUBLIC) - - expect { migrate! }.to change { project.reload.visibility_level }.to(Gitlab::VisibilityLevel::INTERNAL) - end - end - - context 'public visibility level' do - let(:name) { 'public-public' } - - it 'does not update the project visibility' do - create_namespace(name, Gitlab::VisibilityLevel::PUBLIC) - create_project(name, Gitlab::VisibilityLevel::PUBLIC) - - expect { migrate! }.not_to change { project.reload.visibility_level } - end - end - - context 'private project visibility level' do - let(:name) { 'public-private' } - - it 'does not update the project visibility' do - create_namespace(name, Gitlab::VisibilityLevel::PUBLIC) - create_project(name, Gitlab::VisibilityLevel::PRIVATE) - - expect { migrate! }.not_to change { project.reload.visibility_level } - end - end - - context 'no namespace' do - let(:name) { 'no-namespace' } - - it 'does not update the project visibility' do - create_namespace(name, Gitlab::VisibilityLevel::PRIVATE, type: nil) - create_project(name, Gitlab::VisibilityLevel::PUBLIC) - - expect { migrate! }.not_to change { project.reload.visibility_level } - end - end - - def create_namespace(name, visibility, options = {}) - namespaces.create({ - name: name, - path: name, - type: 'Group', - visibility_level: visibility - }.merge(options)) - end - - def create_project(name, visibility) - projects.create!(namespace_id: namespaces.find_by_name(name).id, - name: name, - path: name, - import_type: 'gitlab_project', - visibility_level: visibility) - end -end diff --git a/spec/migrations/update_routes_for_lost_and_found_group_and_orphaned_projects_spec.rb b/spec/migrations/update_routes_for_lost_and_found_group_and_orphaned_projects_spec.rb new file mode 100644 index 00000000000..4cf096b9df6 --- /dev/null +++ b/spec/migrations/update_routes_for_lost_and_found_group_and_orphaned_projects_spec.rb @@ -0,0 +1,182 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require Rails.root.join('db', 'post_migrate', '20200602143020_update_routes_for_lost_and_found_group_and_orphaned_projects.rb') + +describe UpdateRoutesForLostAndFoundGroupAndOrphanedProjects, :migration do + let(:users) { table(:users) } + let(:namespaces) { table(:namespaces) } + let(:members) { table(:members) } + let(:projects) { table(:projects) } + let(:routes) { table(:routes) } + + before do + # Create a Ghost User and its namnespace, but skip the route + ghost_user = users.create!( + name: 'Ghost User', + username: 'ghost', + email: 'ghost@example.com', + user_type: described_class::User::USER_TYPE_GHOST, + projects_limit: 100, + state: :active, + bio: 'This is a "Ghost User"' + ) + + namespaces.create!( + name: 'Ghost User', + path: 'ghost', + owner_id: ghost_user.id, + visibility_level: 20 + ) + + # Create the 'lost-and-found', owned by the Ghost user, but with no route + lost_and_found_group = namespaces.create!( + name: described_class::User::LOST_AND_FOUND_GROUP, + path: described_class::User::LOST_AND_FOUND_GROUP, + type: 'Group', + description: 'Group to store orphaned projects', + visibility_level: 0 + ) + + members.create!( + type: 'GroupMember', + source_id: lost_and_found_group.id, + user_id: ghost_user.id, + source_type: 'Namespace', + access_level: described_class::User::ACCESS_LEVEL_OWNER, + notification_level: 3 + ) + + # Add an orphaned project under 'lost-and-found' but with the wrong path in its route + orphaned_project = projects.create!( + name: 'orphaned_project', + path: 'orphaned_project', + visibility_level: 20, + archived: false, + namespace_id: lost_and_found_group.id + ) + + routes.create!( + source_id: orphaned_project.id, + source_type: 'Project', + path: 'orphaned_project', + name: 'orphaned_project', + created_at: Time.zone.now, + updated_at: Time.zone.now + ) + + # Create another user named ghost which is not the Ghost User + # Also create a 'lost-and-found' group for them and add projects to it + # Purpose: test that the routes added for the 'lost-and-found' group and + # its projects are unique + fake_ghost_user = users.create!( + name: 'Ghost User', + username: 'ghost1', + email: 'ghost1@example.com', + user_type: nil, + projects_limit: 100, + state: :active, + bio: 'This is NOT a "Ghost User"' + ) + + fake_ghost_user_namespace = namespaces.create!( + name: 'Ghost User', + path: 'ghost1', + owner_id: fake_ghost_user.id, + visibility_level: 20 + ) + + routes.create!( + source_id: fake_ghost_user_namespace.id, + source_type: 'Namespace', + path: 'Ghost User', + name: 'ghost1', + created_at: Time.zone.now, + updated_at: Time.zone.now + ) + + fake_lost_and_found_group = namespaces.create!( + name: 'Lost and Found', + path: described_class::User::LOST_AND_FOUND_GROUP, # same path as the lost-and-found group + type: 'Group', + description: 'Fake lost and found group with the same path as the real one', + visibility_level: 20 + ) + + routes.create!( + source_id: fake_lost_and_found_group.id, + source_type: 'Namespace', + path: described_class::User::LOST_AND_FOUND_GROUP, # same path as the lost-and-found group + name: 'Lost and Found', + created_at: Time.zone.now, + updated_at: Time.zone.now + ) + + members.create!( + type: 'GroupMember', + source_id: fake_lost_and_found_group.id, + user_id: fake_ghost_user.id, + source_type: 'Namespace', + access_level: described_class::User::ACCESS_LEVEL_OWNER, + notification_level: 3 + ) + + normal_project = projects.create!( + name: 'normal_project', + path: 'normal_project', + visibility_level: 20, + archived: false, + namespace_id: fake_lost_and_found_group.id + ) + + routes.create!( + source_id: normal_project.id, + source_type: 'Project', + path: "#{described_class::User::LOST_AND_FOUND_GROUP}/normal_project", + name: 'Lost and Found / normal_project', + created_at: Time.zone.now, + updated_at: Time.zone.now + ) + end + + it 'creates the route for the ghost user namespace' do + expect(routes.where(path: 'ghost').count).to eq(0) + + disable_migrations_output { migrate! } + + expect(routes.where(path: 'ghost').count).to eq(1) + end + + it 'fixes the path for the lost-and-found group by generating a unique one' do + expect(namespaces.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(2) + + disable_migrations_output { migrate! } + + expect(namespaces.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(1) + + lost_and_found_group = namespaces.find_by(name: described_class::User::LOST_AND_FOUND_GROUP) + expect(lost_and_found_group.path).to eq('lost-and-found1') + end + + it 'creates the route for the lost-and-found group' do + expect(routes.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(1) + expect(routes.where(path: 'lost-and-found1').count).to eq(0) + + disable_migrations_output { migrate! } + + expect(routes.where(path: described_class::User::LOST_AND_FOUND_GROUP).count).to eq(1) + expect(routes.where(path: 'lost-and-found1').count).to eq(1) + end + + it 'updates the route for the orphaned project' do + orphaned_project_route = routes.find_by(path: 'orphaned_project') + expect(orphaned_project_route.name).to eq('orphaned_project') + + disable_migrations_output { migrate! } + + updated_route = routes.find_by(id: orphaned_project_route.id) + expect(updated_route.path).to eq('lost-and-found1/orphaned_project') + expect(updated_route.name).to eq("#{described_class::User::LOST_AND_FOUND_GROUP} / orphaned_project") + end +end |