Remove migration specs from 201[4567]
Since the migrations are gone, we don't need these specs either
This commit is contained in:
parent
2f66a7bb81
commit
876d415116
|
@ -1,39 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20170713104829_add_foreign_key_to_merge_requests.rb')
|
||||
|
||||
describe AddForeignKeyToMergeRequests, :migration do
|
||||
let(:projects) { table(:projects) }
|
||||
let(:merge_requests) { table(:merge_requests) }
|
||||
let(:pipelines) { table(:ci_pipelines) }
|
||||
|
||||
before do
|
||||
projects.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce')
|
||||
pipelines.create!(project_id: projects.first.id,
|
||||
ref: 'some-branch',
|
||||
sha: 'abc12345')
|
||||
|
||||
# merge request without a pipeline
|
||||
create_merge_request(head_pipeline_id: nil)
|
||||
|
||||
# merge request with non-existent pipeline
|
||||
create_merge_request(head_pipeline_id: 1234)
|
||||
|
||||
# merge reqeust with existing pipeline assigned
|
||||
create_merge_request(head_pipeline_id: pipelines.first.id)
|
||||
end
|
||||
|
||||
it 'correctly adds a foreign key to head_pipeline_id' do
|
||||
migrate!
|
||||
|
||||
expect(merge_requests.first.head_pipeline_id).to be_nil
|
||||
expect(merge_requests.second.head_pipeline_id).to be_nil
|
||||
expect(merge_requests.third.head_pipeline_id).to eq pipelines.first.id
|
||||
end
|
||||
|
||||
def create_merge_request(**opts)
|
||||
merge_requests.create!(source_project_id: projects.first.id,
|
||||
target_project_id: projects.first.id,
|
||||
source_branch: 'some-branch',
|
||||
target_branch: 'master', **opts)
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170508170547_add_head_pipeline_for_each_merge_request.rb')
|
||||
|
||||
describe AddHeadPipelineForEachMergeRequest, :migration do
|
||||
let(:migration) { described_class.new }
|
||||
|
||||
let!(:project) { table(:projects).create! }
|
||||
let!(:other_project) { table(:projects).create! }
|
||||
|
||||
let!(:pipeline_1) { table(:ci_pipelines).create!(project_id: project.id, ref: "branch_1") }
|
||||
let!(:pipeline_2) { table(:ci_pipelines).create!(project_id: other_project.id, ref: "branch_1") }
|
||||
let!(:pipeline_3) { table(:ci_pipelines).create!(project_id: other_project.id, ref: "branch_1") }
|
||||
let!(:pipeline_4) { table(:ci_pipelines).create!(project_id: project.id, ref: "branch_2") }
|
||||
|
||||
let!(:mr_1) { table(:merge_requests).create!(source_project_id: project.id, target_project_id: project.id, source_branch: "branch_1", target_branch: "target_1") }
|
||||
let!(:mr_2) { table(:merge_requests).create!(source_project_id: other_project.id, target_project_id: project.id, source_branch: "branch_1", target_branch: "target_2") }
|
||||
let!(:mr_3) { table(:merge_requests).create!(source_project_id: project.id, target_project_id: project.id, source_branch: "branch_2", target_branch: "master") }
|
||||
let!(:mr_4) { table(:merge_requests).create!(source_project_id: project.id, target_project_id: project.id, source_branch: "branch_3", target_branch: "master") }
|
||||
|
||||
context "#up" do
|
||||
context "when source_project and source_branch of pipeline are the same of merge request" do
|
||||
it "sets head_pipeline_id of given merge requests" do
|
||||
migration.up
|
||||
|
||||
expect(mr_1.reload.head_pipeline_id).to eq(pipeline_1.id)
|
||||
expect(mr_2.reload.head_pipeline_id).to eq(pipeline_3.id)
|
||||
expect(mr_3.reload.head_pipeline_id).to eq(pipeline_4.id)
|
||||
expect(mr_4.reload.head_pipeline_id).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,59 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170803090603_calculate_conv_dev_index_percentages.rb')
|
||||
|
||||
describe CalculateConvDevIndexPercentages, :migration do
|
||||
let(:migration) { described_class.new }
|
||||
let!(:conv_dev_index) do
|
||||
table(:conversational_development_index_metrics).create!(
|
||||
leader_issues: 9.256,
|
||||
leader_notes: 0,
|
||||
leader_milestones: 16.2456,
|
||||
leader_boards: 5.2123,
|
||||
leader_merge_requests: 1.2,
|
||||
leader_ci_pipelines: 12.1234,
|
||||
leader_environments: 3.3333,
|
||||
leader_deployments: 1.200,
|
||||
leader_projects_prometheus_active: 0.111,
|
||||
leader_service_desk_issues: 15.891,
|
||||
instance_issues: 1.234,
|
||||
instance_notes: 28.123,
|
||||
instance_milestones: 0,
|
||||
instance_boards: 3.254,
|
||||
instance_merge_requests: 0.6,
|
||||
instance_ci_pipelines: 2.344,
|
||||
instance_environments: 2.2222,
|
||||
instance_deployments: 0.771,
|
||||
instance_projects_prometheus_active: 0.109,
|
||||
instance_service_desk_issues: 13.345,
|
||||
percentage_issues: 0,
|
||||
percentage_notes: 0,
|
||||
percentage_milestones: 0,
|
||||
percentage_boards: 0,
|
||||
percentage_merge_requests: 0,
|
||||
percentage_ci_pipelines: 0,
|
||||
percentage_environments: 0,
|
||||
percentage_deployments: 0,
|
||||
percentage_projects_prometheus_active: 0,
|
||||
percentage_service_desk_issues: 0)
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
it 'calculates percentages correctly' do
|
||||
migration.up
|
||||
conv_dev_index.reload
|
||||
|
||||
expect(conv_dev_index.percentage_issues).to be_within(0.1).of(13.3)
|
||||
expect(conv_dev_index.percentage_notes).to be_zero # leader 0
|
||||
expect(conv_dev_index.percentage_milestones).to be_zero # instance 0
|
||||
expect(conv_dev_index.percentage_boards).to be_within(0.1).of(62.4)
|
||||
expect(conv_dev_index.percentage_merge_requests).to eq(50.0)
|
||||
expect(conv_dev_index.percentage_ci_pipelines).to be_within(0.1).of(19.3)
|
||||
expect(conv_dev_index.percentage_environments).to be_within(0.1).of(66.7)
|
||||
expect(conv_dev_index.percentage_deployments).to be_within(0.1).of(64.2)
|
||||
expect(conv_dev_index.percentage_projects_prometheus_active).to be_within(0.1).of(98.2)
|
||||
expect(conv_dev_index.percentage_service_desk_issues).to be_within(0.1).of(84.0)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,46 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170613111224_clean_appearance_symlinks.rb')
|
||||
|
||||
describe CleanAppearanceSymlinks do
|
||||
let(:migration) { described_class.new }
|
||||
let(:test_dir) { File.join(Rails.root, "tmp", "tests", "clean_appearance_test") }
|
||||
let(:uploads_dir) { File.join(test_dir, "public", "uploads") }
|
||||
let(:new_uploads_dir) { File.join(uploads_dir, "system") }
|
||||
let(:original_path) { File.join(new_uploads_dir, 'appearance') }
|
||||
let(:symlink_path) { File.join(uploads_dir, 'appearance') }
|
||||
|
||||
before do
|
||||
FileUtils.remove_dir(test_dir) if File.directory?(test_dir)
|
||||
FileUtils.mkdir_p(uploads_dir)
|
||||
allow(migration).to receive(:base_directory).and_return(test_dir)
|
||||
allow(migration).to receive(:say)
|
||||
end
|
||||
|
||||
describe "#up" do
|
||||
before do
|
||||
FileUtils.mkdir_p(original_path)
|
||||
FileUtils.ln_s(original_path, symlink_path)
|
||||
end
|
||||
|
||||
it 'removes the symlink' do
|
||||
migration.up
|
||||
|
||||
expect(File.symlink?(symlink_path)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
before do
|
||||
FileUtils.mkdir_p(File.join(original_path))
|
||||
FileUtils.touch(File.join(original_path, 'dummy.file'))
|
||||
end
|
||||
|
||||
it 'creates a symlink' do
|
||||
expected_path = File.join(symlink_path, "dummy.file")
|
||||
migration.down
|
||||
|
||||
expect(File.exist?(expected_path)).to be(true)
|
||||
expect(File.symlink?(symlink_path)).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20170710083355_clean_stage_id_reference_migration.rb')
|
||||
|
||||
describe CleanStageIdReferenceMigration, :migration, :sidekiq, :redis do
|
||||
let(:migration_class) { 'MigrateBuildStageIdReference' }
|
||||
let(:migration) { spy('migration') }
|
||||
|
||||
before do
|
||||
allow(Gitlab::BackgroundMigration.const_get(migration_class))
|
||||
.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, migration_class, [1, 1])
|
||||
BackgroundMigrationWorker.perform_async(migration_class, [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
|
||||
end
|
|
@ -1,51 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20170912113435_clean_stages_statuses_migration.rb')
|
||||
|
||||
describe CleanStagesStatusesMigration, :migration, :sidekiq, :redis do
|
||||
let(:migration) { spy('migration') }
|
||||
|
||||
before do
|
||||
allow(Gitlab::BackgroundMigration::MigrateStageStatus)
|
||||
.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, 'MigrateStageStatus', [1, 1])
|
||||
BackgroundMigrationWorker
|
||||
.perform_async('MigrateStageStatus', [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 afterwards' do
|
||||
let(:stages) { table('ci_stages') }
|
||||
|
||||
before do
|
||||
stages.create!(status: nil, name: 'build')
|
||||
stages.create!(status: nil, name: 'test')
|
||||
end
|
||||
|
||||
it 'migrates statuses sequentially in batches' do
|
||||
migrate!
|
||||
|
||||
expect(migration).to have_received(:perform).once
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,46 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170406111121_clean_upload_symlinks.rb')
|
||||
|
||||
describe CleanUploadSymlinks do
|
||||
let(:migration) { described_class.new }
|
||||
let(:test_dir) { File.join(Rails.root, "tmp", "tests", "move_uploads_test") }
|
||||
let(:uploads_dir) { File.join(test_dir, "public", "uploads") }
|
||||
let(:new_uploads_dir) { File.join(uploads_dir, "-", "system") }
|
||||
let(:original_path) { File.join(new_uploads_dir, 'user') }
|
||||
let(:symlink_path) { File.join(uploads_dir, 'user') }
|
||||
|
||||
before do
|
||||
FileUtils.remove_dir(test_dir) if File.directory?(test_dir)
|
||||
FileUtils.mkdir_p(uploads_dir)
|
||||
allow(migration).to receive(:base_directory).and_return(test_dir)
|
||||
allow(migration).to receive(:say)
|
||||
end
|
||||
|
||||
describe "#up" do
|
||||
before do
|
||||
FileUtils.mkdir_p(original_path)
|
||||
FileUtils.ln_s(original_path, symlink_path)
|
||||
end
|
||||
|
||||
it 'removes the symlink' do
|
||||
migration.up
|
||||
|
||||
expect(File.symlink?(symlink_path)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
before do
|
||||
FileUtils.mkdir_p(File.join(original_path))
|
||||
FileUtils.touch(File.join(original_path, 'dummy.file'))
|
||||
end
|
||||
|
||||
it 'creates a symlink' do
|
||||
expected_path = File.join(symlink_path, "dummy.file")
|
||||
migration.down
|
||||
|
||||
expect(File.exist?(expected_path)).to be(true)
|
||||
expect(File.symlink?(symlink_path)).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join("db", "post_migrate", "20170717111152_cleanup_move_system_upload_folder_symlink.rb")
|
||||
|
||||
describe CleanupMoveSystemUploadFolderSymlink do
|
||||
let(:migration) { described_class.new }
|
||||
let(:test_base) { File.join(Rails.root, 'tmp', 'tests', 'move-system-upload-folder') }
|
||||
let(:test_folder) { File.join(test_base, '-', 'system') }
|
||||
|
||||
before do
|
||||
allow(migration).to receive(:base_directory).and_return(test_base)
|
||||
FileUtils.rm_rf(test_base)
|
||||
FileUtils.mkdir_p(test_folder)
|
||||
allow(migration).to receive(:say)
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
before do
|
||||
FileUtils.ln_s(test_folder, File.join(test_base, 'system'))
|
||||
end
|
||||
|
||||
it 'removes the symlink' do
|
||||
migration.up
|
||||
|
||||
expect(File.exist?(File.join(test_base, 'system'))).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'creates the symlink' do
|
||||
migration.down
|
||||
|
||||
expect(File.symlink?(File.join(test_base, 'system'))).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,29 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170816102555_cleanup_nonexisting_namespace_pending_delete_projects.rb')
|
||||
|
||||
describe CleanupNonexistingNamespacePendingDeleteProjects, :migration do
|
||||
let(:projects) { table(:projects) }
|
||||
let(:namespaces) { table(:namespaces) }
|
||||
|
||||
describe '#up' do
|
||||
let!(:some_project) { projects.create! }
|
||||
let(:namespace) { namespaces.create!(name: 'test', path: 'test') }
|
||||
|
||||
it 'only cleans up when namespace does not exist' do
|
||||
projects.create!(pending_delete: true, namespace_id: namespace.id)
|
||||
project = projects.create!(pending_delete: true, namespace_id: 0)
|
||||
|
||||
expect(NamespacelessProjectDestroyWorker).to receive(:bulk_perform_async).with([[project.id]])
|
||||
|
||||
described_class.new.up
|
||||
end
|
||||
|
||||
it 'does nothing when no pending delete projects without namespace found' do
|
||||
projects.create!(pending_delete: true, namespace_id: namespace.id)
|
||||
|
||||
expect(NamespacelessProjectDestroyWorker).not_to receive(:bulk_perform_async)
|
||||
|
||||
described_class.new.up
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,120 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170607121233_convert_custom_notification_settings_to_columns')
|
||||
|
||||
describe ConvertCustomNotificationSettingsToColumns, :migration do
|
||||
let(:user_class) { table(:users) }
|
||||
|
||||
let(:settings_params) do
|
||||
[
|
||||
{ level: 0, events: [:new_note] }, # disabled, single event
|
||||
{ level: 3, events: [:new_issue, :reopen_issue, :close_issue, :reassign_issue] }, # global, multiple events
|
||||
{ level: 5, events: described_class::EMAIL_EVENTS }, # custom, all events
|
||||
{ level: 5, events: [] } # custom, no events
|
||||
]
|
||||
end
|
||||
|
||||
let(:notification_settings_before) do
|
||||
settings_params.map do |params|
|
||||
events = {}
|
||||
|
||||
params[:events].each do |event|
|
||||
events[event] = true
|
||||
end
|
||||
|
||||
user = user_class.create!(email: "user-#{SecureRandom.hex}@example.org", username: "user-#{SecureRandom.hex}", encrypted_password: '12345678')
|
||||
create_params = { user_id: user.id, level: params[:level], events: events }
|
||||
notification_setting = described_class::NotificationSetting.create(create_params)
|
||||
|
||||
[notification_setting, params]
|
||||
end
|
||||
end
|
||||
|
||||
let(:notification_settings_after) do
|
||||
settings_params.map do |params|
|
||||
events = {}
|
||||
|
||||
params[:events].each do |event|
|
||||
events[event] = true
|
||||
end
|
||||
|
||||
user = user_class.create!(email: "user-#{SecureRandom.hex}@example.org", username: "user-#{SecureRandom.hex}", encrypted_password: '12345678')
|
||||
create_params = events.merge(user_id: user.id, level: params[:level])
|
||||
notification_setting = described_class::NotificationSetting.create(create_params)
|
||||
|
||||
[notification_setting, params]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
it 'migrates all settings where a custom event is enabled, even if they are not currently using the custom level' do
|
||||
notification_settings_before
|
||||
|
||||
described_class.new.up
|
||||
|
||||
notification_settings_before.each do |(notification_setting, params)|
|
||||
notification_setting.reload
|
||||
|
||||
expect(notification_setting.read_attribute_before_type_cast(:events)).to be_nil
|
||||
expect(notification_setting.level).to eq(params[:level])
|
||||
|
||||
described_class::EMAIL_EVENTS.each do |event|
|
||||
# We don't set the others to false, just let them default to nil
|
||||
expected = params[:events].include?(event) || nil
|
||||
|
||||
expect(notification_setting.read_attribute(event)).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'creates a custom events hash for all settings where at least one event is enabled' do
|
||||
notification_settings_after
|
||||
|
||||
described_class.new.down
|
||||
|
||||
notification_settings_after.each do |(notification_setting, params)|
|
||||
notification_setting.reload
|
||||
|
||||
expect(notification_setting.level).to eq(params[:level])
|
||||
|
||||
if params[:events].empty?
|
||||
# We don't migrate empty settings
|
||||
expect(notification_setting.events).to eq({})
|
||||
else
|
||||
described_class::EMAIL_EVENTS.each do |event|
|
||||
expected = params[:events].include?(event)
|
||||
|
||||
expect(notification_setting.events[event]).to eq(expected)
|
||||
expect(notification_setting.read_attribute(event)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'reverts the database to the state it was in before' do
|
||||
notification_settings_before
|
||||
|
||||
described_class.new.up
|
||||
described_class.new.down
|
||||
|
||||
notification_settings_before.each do |(notification_setting, params)|
|
||||
notification_setting.reload
|
||||
|
||||
expect(notification_setting.level).to eq(params[:level])
|
||||
|
||||
if params[:events].empty?
|
||||
# We don't migrate empty settings
|
||||
expect(notification_setting.events).to eq({})
|
||||
else
|
||||
described_class::EMAIL_EVENTS.each do |event|
|
||||
expected = params[:events].include?(event)
|
||||
|
||||
expect(notification_setting.events[event]).to eq(expected)
|
||||
expect(notification_setting.read_attribute(event)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,42 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170907170235_delete_conflicting_redirect_routes')
|
||||
|
||||
describe DeleteConflictingRedirectRoutes, :migration, :sidekiq do
|
||||
let!(:redirect_routes) { table(:redirect_routes) }
|
||||
let!(:routes) { table(:routes) }
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze { example.run }
|
||||
end
|
||||
|
||||
before do
|
||||
routes.create!(id: 1, source_id: 1, source_type: 'Namespace', path: 'foo1')
|
||||
routes.create!(id: 2, source_id: 2, source_type: 'Namespace', path: 'foo2')
|
||||
routes.create!(id: 3, source_id: 3, source_type: 'Namespace', path: 'foo3')
|
||||
routes.create!(id: 4, source_id: 4, source_type: 'Namespace', path: 'foo4')
|
||||
routes.create!(id: 5, source_id: 5, source_type: 'Namespace', path: 'foo5')
|
||||
|
||||
# Valid redirects
|
||||
redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'bar')
|
||||
redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'bar2')
|
||||
redirect_routes.create!(source_id: 2, source_type: 'Namespace', path: 'bar3')
|
||||
|
||||
# Conflicting redirects
|
||||
redirect_routes.create!(source_id: 2, source_type: 'Namespace', path: 'foo1')
|
||||
redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'foo2')
|
||||
redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'foo3')
|
||||
redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'foo4')
|
||||
redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'foo5')
|
||||
end
|
||||
|
||||
# No-op. See https://gitlab.com/gitlab-com/infrastructure/issues/3460#note_53223252
|
||||
it 'NO-OP: does not schedule any background migrations' do
|
||||
Sidekiq::Testing.fake! do
|
||||
Timecop.freeze do
|
||||
migrate!
|
||||
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,86 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170518231126_fix_wrongly_renamed_routes.rb')
|
||||
|
||||
describe FixWronglyRenamedRoutes, :migration do
|
||||
let(:subject) { described_class.new }
|
||||
let(:namespaces_table) { table(:namespaces) }
|
||||
let(:projects_table) { table(:projects) }
|
||||
let(:routes_table) { table(:routes) }
|
||||
let(:broken_namespace) do
|
||||
namespaces_table.create!(name: 'apiis', path: 'apiis').tap do |namespace|
|
||||
routes_table.create!(source_type: 'Namespace', source_id: namespace.id, name: 'api0is', path: 'api0is')
|
||||
end
|
||||
end
|
||||
let(:broken_namespace_route) { routes_table.where(source_type: 'Namespace', source_id: broken_namespace.id).first }
|
||||
|
||||
describe '#wrongly_renamed' do
|
||||
it "includes routes that have names that don't match their namespace" do
|
||||
broken_namespace
|
||||
other_namespace = namespaces_table.create!(name: 'api0', path: 'api0')
|
||||
routes_table.create!(source_type: 'Namespace', source_id: other_namespace.id, name: 'api0', path: 'api0')
|
||||
|
||||
expect(subject.wrongly_renamed.map(&:id))
|
||||
.to contain_exactly(broken_namespace_route.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#paths_and_corrections" do
|
||||
it 'finds the wrong path and gets the correction from the namespace' do
|
||||
broken_namespace
|
||||
namespaces_table.create!(name: 'uploads-test', path: 'uploads-test').tap do |namespace|
|
||||
routes_table.create!(source_type: 'Namespace', source_id: namespace.id, name: 'uploads-test', path: 'uploads0-test')
|
||||
end
|
||||
|
||||
expected_result = [
|
||||
{ 'namespace_path' => 'apiis', 'path' => 'api0is' },
|
||||
{ 'namespace_path' => 'uploads-test', 'path' => 'uploads0-test' }
|
||||
]
|
||||
|
||||
expect(subject.paths_and_corrections).to include(*expected_result)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#routes_in_namespace_query' do
|
||||
it 'includes only the required routes' do
|
||||
namespace = namespaces_table.create!(name: 'hello', path: 'hello')
|
||||
namespace_route = routes_table.create!(source_type: 'Namespace', source_id: namespace.id, name: 'hello', path: 'hello')
|
||||
project = projects_table.new(name: 'my-project', path: 'my-project', namespace_id: namespace.id).tap do |project|
|
||||
project.save!(validate: false)
|
||||
end
|
||||
routes_table.create!(source_type: 'Project', source_id: project.id, name: 'my-project', path: 'hello/my-project')
|
||||
_other_namespace = namespaces_table.create!(name: 'hello0', path: 'hello0')
|
||||
|
||||
result = routes_table.where(subject.routes_in_namespace_query('hello'))
|
||||
project_route = routes_table.where(source_type: 'Project', source_id: project.id).first
|
||||
|
||||
expect(result).to contain_exactly(namespace_route, project_route)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
it 'renames incorrectly named routes' do
|
||||
broken_project =
|
||||
projects_table.new(name: 'broken-project', path: 'broken-project', namespace_id: broken_namespace.id).tap do |project|
|
||||
project.save!(validate: false)
|
||||
routes_table.create!(source_type: 'Project', source_id: project.id, name: 'broken-project', path: 'api0is/broken-project')
|
||||
end
|
||||
|
||||
subject.up
|
||||
|
||||
broken_project_route = routes_table.where(source_type: 'Project', source_id: broken_project.id).first
|
||||
|
||||
expect(broken_project_route.path).to eq('apiis/broken-project')
|
||||
expect(broken_namespace_route.reload.path).to eq('apiis')
|
||||
end
|
||||
|
||||
it "doesn't touch namespaces that look like something that should be renamed" do
|
||||
namespaces_table.create!(name: 'apiis', path: 'apiis')
|
||||
namespace = namespaces_table.create!(name: 'hello', path: 'api0')
|
||||
namespace_route = routes_table.create!(source_type: 'Namespace', source_id: namespace.id, name: 'hello', path: 'api0')
|
||||
|
||||
subject.up
|
||||
|
||||
expect(namespace_route.reload.path).to eq('api0')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,24 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20171106151218_issues_moved_to_id_foreign_key.rb')
|
||||
|
||||
describe IssuesMovedToIdForeignKey, :migration do
|
||||
let(:issues) { table(:issues) }
|
||||
|
||||
let!(:issue_third) { issues.create! }
|
||||
let!(:issue_second) { issues.create!(moved_to_id: issue_third.id) }
|
||||
let!(:issue_first) { issues.create!(moved_to_id: issue_second.id) }
|
||||
|
||||
subject { described_class.new }
|
||||
|
||||
it 'removes the orphaned moved_to_id' do
|
||||
subject.down
|
||||
|
||||
issue_third.update!(moved_to_id: 0)
|
||||
|
||||
subject.up
|
||||
|
||||
expect(issue_first.reload.moved_to_id).to eq(issue_second.id)
|
||||
expect(issue_second.reload.moved_to_id).to eq(issue_third.id)
|
||||
expect(issue_third.reload.moved_to_id).to be_nil
|
||||
end
|
||||
end
|
|
@ -1,62 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170526190000_migrate_build_stage_reference_again.rb')
|
||||
|
||||
describe MigrateBuildStageReferenceAgain, :migration do
|
||||
##
|
||||
# Create test data - pipeline and CI/CD jobs.
|
||||
#
|
||||
|
||||
let(:jobs) { table(:ci_builds) }
|
||||
let(:stages) { table(:ci_stages) }
|
||||
let(:pipelines) { table(:ci_pipelines) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
||||
before do
|
||||
# Create projects
|
||||
#
|
||||
projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
|
||||
projects.create!(id: 456, name: 'gitlab2', path: 'gitlab2')
|
||||
|
||||
# Create CI/CD pipelines
|
||||
#
|
||||
pipelines.create!(id: 1, project_id: 123, ref: 'master', sha: 'adf43c3a')
|
||||
pipelines.create!(id: 2, project_id: 456, ref: 'feature', sha: '21a3deb')
|
||||
|
||||
# Create CI/CD jobs
|
||||
#
|
||||
jobs.create!(id: 1, commit_id: 1, project_id: 123, stage_idx: 2, stage: 'build')
|
||||
jobs.create!(id: 2, commit_id: 1, project_id: 123, stage_idx: 2, stage: 'build')
|
||||
jobs.create!(id: 3, commit_id: 1, project_id: 123, stage_idx: 1, stage: 'test')
|
||||
jobs.create!(id: 4, commit_id: 1, project_id: 123, stage_idx: 3, stage: 'deploy')
|
||||
jobs.create!(id: 5, commit_id: 2, project_id: 456, stage_idx: 2, stage: 'test:2')
|
||||
jobs.create!(id: 6, commit_id: 2, project_id: 456, stage_idx: 1, stage: 'test:1')
|
||||
jobs.create!(id: 7, commit_id: 2, project_id: 456, stage_idx: 1, stage: 'test:1')
|
||||
jobs.create!(id: 8, commit_id: 3, project_id: 789, stage_idx: 3, stage: 'deploy')
|
||||
|
||||
# Create CI/CD stages
|
||||
#
|
||||
stages.create(id: 101, pipeline_id: 1, project_id: 123, name: 'test')
|
||||
stages.create(id: 102, pipeline_id: 1, project_id: 123, name: 'build')
|
||||
stages.create(id: 103, pipeline_id: 1, project_id: 123, name: 'deploy')
|
||||
stages.create(id: 104, pipeline_id: 2, project_id: 456, name: 'test:1')
|
||||
stages.create(id: 105, pipeline_id: 2, project_id: 456, name: 'test:2')
|
||||
stages.create(id: 106, pipeline_id: 2, project_id: 456, name: 'deploy')
|
||||
end
|
||||
|
||||
it 'correctly migrate build stage references' do
|
||||
expect(jobs.where(stage_id: nil).count).to eq 8
|
||||
|
||||
migrate!
|
||||
|
||||
expect(jobs.where(stage_id: nil).count).to eq 1
|
||||
|
||||
expect(jobs.find(1).stage_id).to eq 102
|
||||
expect(jobs.find(2).stage_id).to eq 102
|
||||
expect(jobs.find(3).stage_id).to eq 101
|
||||
expect(jobs.find(4).stage_id).to eq 103
|
||||
expect(jobs.find(5).stage_id).to eq 105
|
||||
expect(jobs.find(6).stage_id).to eq 104
|
||||
expect(jobs.find(7).stage_id).to eq 104
|
||||
expect(jobs.find(8).stage_id).to eq nil
|
||||
end
|
||||
end
|
|
@ -1,181 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20171013104327_migrate_gcp_clusters_to_new_clusters_architectures.rb')
|
||||
|
||||
describe MigrateGcpClustersToNewClustersArchitectures, :migration do
|
||||
let(:projects) { table(:projects) }
|
||||
let(:project) { projects.create }
|
||||
let(:users) { table(:users) }
|
||||
let(:user) { users.create! }
|
||||
let(:service) { GcpMigrationSpec::KubernetesService.create!(project_id: project.id) }
|
||||
|
||||
module GcpMigrationSpec
|
||||
class KubernetesService < ActiveRecord::Base
|
||||
self.table_name = 'services'
|
||||
|
||||
serialize :properties, JSON
|
||||
|
||||
default_value_for :active, true
|
||||
default_value_for :type, 'KubernetesService'
|
||||
default_value_for :properties, {
|
||||
api_url: 'https://kubernetes.example.com',
|
||||
token: 'a' * 40
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'when cluster is being created' do
|
||||
let(:project_id) { project.id }
|
||||
let(:user_id) { user.id }
|
||||
let(:service_id) { service.id }
|
||||
let(:status) { 2 } # creating
|
||||
let(:gcp_cluster_size) { 1 }
|
||||
let(:created_at) { "'2017-10-17 20:24:02'" }
|
||||
let(:updated_at) { "'2017-10-17 20:28:44'" }
|
||||
let(:enabled) { true }
|
||||
let(:status_reason) { "''" }
|
||||
let(:project_namespace) { "'sample-app'" }
|
||||
let(:endpoint) { 'NULL' }
|
||||
let(:ca_cert) { 'NULL' }
|
||||
let(:encrypted_kubernetes_token) { 'NULL' }
|
||||
let(:encrypted_kubernetes_token_iv) { 'NULL' }
|
||||
let(:username) { 'NULL' }
|
||||
let(:encrypted_password) { 'NULL' }
|
||||
let(:encrypted_password_iv) { 'NULL' }
|
||||
let(:gcp_project_id) { "'gcp_project_id'" }
|
||||
let(:gcp_cluster_zone) { "'gcp_cluster_zone'" }
|
||||
let(:gcp_cluster_name) { "'gcp_cluster_name'" }
|
||||
let(:gcp_machine_type) { "'gcp_machine_type'" }
|
||||
let(:gcp_operation_id) { 'NULL' }
|
||||
let(:encrypted_gcp_token) { "'encrypted_gcp_token'" }
|
||||
let(:encrypted_gcp_token_iv) { "'encrypted_gcp_token_iv'" }
|
||||
|
||||
let(:cluster) { described_class::Cluster.last }
|
||||
let(:cluster_id) { cluster.id }
|
||||
|
||||
before do
|
||||
ActiveRecord::Base.connection.execute <<-SQL
|
||||
INSERT INTO gcp_clusters (project_id, user_id, service_id, status, gcp_cluster_size, created_at, updated_at, enabled, status_reason, project_namespace, endpoint, ca_cert, encrypted_kubernetes_token, encrypted_kubernetes_token_iv, username, encrypted_password, encrypted_password_iv, gcp_project_id, gcp_cluster_zone, gcp_cluster_name, gcp_machine_type, gcp_operation_id, encrypted_gcp_token, encrypted_gcp_token_iv)
|
||||
VALUES (#{project_id}, #{user_id}, #{service_id}, #{status}, #{gcp_cluster_size}, #{created_at}, #{updated_at}, #{enabled}, #{status_reason}, #{project_namespace}, #{endpoint}, #{ca_cert}, #{encrypted_kubernetes_token}, #{encrypted_kubernetes_token_iv}, #{username}, #{encrypted_password}, #{encrypted_password_iv}, #{gcp_project_id}, #{gcp_cluster_zone}, #{gcp_cluster_name}, #{gcp_machine_type}, #{gcp_operation_id}, #{encrypted_gcp_token}, #{encrypted_gcp_token_iv});
|
||||
SQL
|
||||
end
|
||||
|
||||
it 'correctly migrate to new clusters architectures' do
|
||||
migrate!
|
||||
|
||||
expect(described_class::Cluster.count).to eq(1)
|
||||
expect(described_class::ClustersProject.count).to eq(1)
|
||||
expect(described_class::ProvidersGcp.count).to eq(1)
|
||||
expect(described_class::PlatformsKubernetes.count).to eq(1)
|
||||
|
||||
expect(cluster.user_id).to eq(user.id)
|
||||
expect(cluster.enabled).to be_truthy
|
||||
expect(cluster.name).to eq(gcp_cluster_name.delete!("'"))
|
||||
expect(cluster.provider_type).to eq('gcp')
|
||||
expect(cluster.platform_type).to eq('kubernetes')
|
||||
|
||||
expect(cluster.project_ids).to include(project.id)
|
||||
|
||||
expect(cluster.provider_gcp.cluster_id).to eq(cluster.id)
|
||||
expect(cluster.provider_gcp.status).to eq(status)
|
||||
expect(cluster.provider_gcp.status_reason).to eq(tr(status_reason))
|
||||
expect(cluster.provider_gcp.gcp_project_id).to eq(tr(gcp_project_id))
|
||||
expect(cluster.provider_gcp.zone).to eq(tr(gcp_cluster_zone))
|
||||
expect(cluster.provider_gcp.num_nodes).to eq(gcp_cluster_size)
|
||||
expect(cluster.provider_gcp.machine_type).to eq(tr(gcp_machine_type))
|
||||
expect(cluster.provider_gcp.operation_id).to be_nil
|
||||
expect(cluster.provider_gcp.endpoint).to be_nil
|
||||
expect(cluster.provider_gcp.encrypted_access_token).to eq(tr(encrypted_gcp_token))
|
||||
expect(cluster.provider_gcp.encrypted_access_token_iv).to eq(tr(encrypted_gcp_token_iv))
|
||||
|
||||
expect(cluster.platform_kubernetes.cluster_id).to eq(cluster.id)
|
||||
expect(cluster.platform_kubernetes.api_url).to be_nil
|
||||
expect(cluster.platform_kubernetes.ca_cert).to be_nil
|
||||
expect(cluster.platform_kubernetes.namespace).to eq(tr(project_namespace))
|
||||
expect(cluster.platform_kubernetes.username).to be_nil
|
||||
expect(cluster.platform_kubernetes.encrypted_password).to be_nil
|
||||
expect(cluster.platform_kubernetes.encrypted_password_iv).to be_nil
|
||||
expect(cluster.platform_kubernetes.encrypted_token).to be_nil
|
||||
expect(cluster.platform_kubernetes.encrypted_token_iv).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when cluster has been created' do
|
||||
let(:project_id) { project.id }
|
||||
let(:user_id) { user.id }
|
||||
let(:service_id) { service.id }
|
||||
let(:status) { 3 } # created
|
||||
let(:gcp_cluster_size) { 1 }
|
||||
let(:created_at) { "'2017-10-17 20:24:02'" }
|
||||
let(:updated_at) { "'2017-10-17 20:28:44'" }
|
||||
let(:enabled) { true }
|
||||
let(:status_reason) { "'general error'" }
|
||||
let(:project_namespace) { "'sample-app'" }
|
||||
let(:endpoint) { "'111.111.111.111'" }
|
||||
let(:ca_cert) { "'ca_cert'" }
|
||||
let(:encrypted_kubernetes_token) { "'encrypted_kubernetes_token'" }
|
||||
let(:encrypted_kubernetes_token_iv) { "'encrypted_kubernetes_token_iv'" }
|
||||
let(:username) { "'username'" }
|
||||
let(:encrypted_password) { "'encrypted_password'" }
|
||||
let(:encrypted_password_iv) { "'encrypted_password_iv'" }
|
||||
let(:gcp_project_id) { "'gcp_project_id'" }
|
||||
let(:gcp_cluster_zone) { "'gcp_cluster_zone'" }
|
||||
let(:gcp_cluster_name) { "'gcp_cluster_name'" }
|
||||
let(:gcp_machine_type) { "'gcp_machine_type'" }
|
||||
let(:gcp_operation_id) { "'gcp_operation_id'" }
|
||||
let(:encrypted_gcp_token) { "'encrypted_gcp_token'" }
|
||||
let(:encrypted_gcp_token_iv) { "'encrypted_gcp_token_iv'" }
|
||||
|
||||
let(:cluster) { described_class::Cluster.last }
|
||||
let(:cluster_id) { cluster.id }
|
||||
|
||||
before do
|
||||
ActiveRecord::Base.connection.execute <<-SQL
|
||||
INSERT INTO gcp_clusters (project_id, user_id, service_id, status, gcp_cluster_size, created_at, updated_at, enabled, status_reason, project_namespace, endpoint, ca_cert, encrypted_kubernetes_token, encrypted_kubernetes_token_iv, username, encrypted_password, encrypted_password_iv, gcp_project_id, gcp_cluster_zone, gcp_cluster_name, gcp_machine_type, gcp_operation_id, encrypted_gcp_token, encrypted_gcp_token_iv)
|
||||
VALUES (#{project_id}, #{user_id}, #{service_id}, #{status}, #{gcp_cluster_size}, #{created_at}, #{updated_at}, #{enabled}, #{status_reason}, #{project_namespace}, #{endpoint}, #{ca_cert}, #{encrypted_kubernetes_token}, #{encrypted_kubernetes_token_iv}, #{username}, #{encrypted_password}, #{encrypted_password_iv}, #{gcp_project_id}, #{gcp_cluster_zone}, #{gcp_cluster_name}, #{gcp_machine_type}, #{gcp_operation_id}, #{encrypted_gcp_token}, #{encrypted_gcp_token_iv});
|
||||
SQL
|
||||
end
|
||||
|
||||
it 'correctly migrate to new clusters architectures' do
|
||||
migrate!
|
||||
|
||||
expect(described_class::Cluster.count).to eq(1)
|
||||
expect(described_class::ClustersProject.count).to eq(1)
|
||||
expect(described_class::ProvidersGcp.count).to eq(1)
|
||||
expect(described_class::PlatformsKubernetes.count).to eq(1)
|
||||
|
||||
expect(cluster.user_id).to eq(user.id)
|
||||
expect(cluster.enabled).to be_truthy
|
||||
expect(cluster.name).to eq(tr(gcp_cluster_name))
|
||||
expect(cluster.provider_type).to eq('gcp')
|
||||
expect(cluster.platform_type).to eq('kubernetes')
|
||||
|
||||
expect(cluster.project_ids).to include(project.id)
|
||||
|
||||
expect(cluster.provider_gcp.cluster_id).to eq(cluster.id)
|
||||
expect(cluster.provider_gcp.status).to eq(status)
|
||||
expect(cluster.provider_gcp.status_reason).to eq(tr(status_reason))
|
||||
expect(cluster.provider_gcp.gcp_project_id).to eq(tr(gcp_project_id))
|
||||
expect(cluster.provider_gcp.zone).to eq(tr(gcp_cluster_zone))
|
||||
expect(cluster.provider_gcp.num_nodes).to eq(gcp_cluster_size)
|
||||
expect(cluster.provider_gcp.machine_type).to eq(tr(gcp_machine_type))
|
||||
expect(cluster.provider_gcp.operation_id).to eq(tr(gcp_operation_id))
|
||||
expect(cluster.provider_gcp.endpoint).to eq(tr(endpoint))
|
||||
expect(cluster.provider_gcp.encrypted_access_token).to eq(tr(encrypted_gcp_token))
|
||||
expect(cluster.provider_gcp.encrypted_access_token_iv).to eq(tr(encrypted_gcp_token_iv))
|
||||
|
||||
expect(cluster.platform_kubernetes.cluster_id).to eq(cluster.id)
|
||||
expect(cluster.platform_kubernetes.api_url).to eq('https://' + tr(endpoint))
|
||||
expect(cluster.platform_kubernetes.ca_cert).to eq(tr(ca_cert))
|
||||
expect(cluster.platform_kubernetes.namespace).to eq(tr(project_namespace))
|
||||
expect(cluster.platform_kubernetes.username).to eq(tr(username))
|
||||
expect(cluster.platform_kubernetes.encrypted_password).to eq(tr(encrypted_password))
|
||||
expect(cluster.platform_kubernetes.encrypted_password_iv).to eq(tr(encrypted_password_iv))
|
||||
expect(cluster.platform_kubernetes.encrypted_token).to eq(tr(encrypted_kubernetes_token))
|
||||
expect(cluster.platform_kubernetes.encrypted_token_iv).to eq(tr(encrypted_kubernetes_token_iv))
|
||||
end
|
||||
end
|
||||
|
||||
def tr(str)
|
||||
str.delete("'")
|
||||
end
|
||||
end
|
|
@ -1,51 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20170825104051_migrate_issues_to_ghost_user.rb')
|
||||
|
||||
describe MigrateIssuesToGhostUser, :migration do
|
||||
describe '#up' do
|
||||
let(:projects) { table(:projects) }
|
||||
let(:issues) { table(:issues) }
|
||||
let(:users) { table(:users) }
|
||||
|
||||
before do
|
||||
project = projects.create!(name: 'gitlab', namespace_id: 1)
|
||||
user = users.create(email: 'test@example.com')
|
||||
issues.create(title: 'Issue 1', author_id: nil, project_id: project.id)
|
||||
issues.create(title: 'Issue 2', author_id: user.id, project_id: project.id)
|
||||
end
|
||||
|
||||
context 'when ghost user exists' do
|
||||
let!(:ghost) { users.create(ghost: true, email: 'ghost@example.com') }
|
||||
|
||||
it 'does not create a new user' do
|
||||
expect { migrate! }.not_to change { User.count }
|
||||
end
|
||||
|
||||
it 'migrates issues where author = nil to the ghost user' do
|
||||
migrate!
|
||||
|
||||
expect(issues.first.reload.author_id).to eq(ghost.id)
|
||||
end
|
||||
|
||||
it 'does not change issues authored by an existing user' do
|
||||
expect { migrate! }.not_to change { issues.second.reload.author_id}
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ghost user does not exist' do
|
||||
it 'creates a new user' do
|
||||
expect { migrate! }.to change { User.count }.by(1)
|
||||
end
|
||||
|
||||
it 'migrates issues where author = nil to the ghost user' do
|
||||
migrate!
|
||||
|
||||
expect(issues.first.reload.author_id).to eq(User.ghost.id)
|
||||
end
|
||||
|
||||
it 'does not change issues authored by an existing user' do
|
||||
expect { migrate! }.not_to change { issues.second.reload.author_id}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,312 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb')
|
||||
|
||||
describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
|
||||
context 'when unique KubernetesService exists' do
|
||||
shared_examples 'KubernetesService migration' do
|
||||
let(:sample_num) { 2 }
|
||||
|
||||
let(:projects) do
|
||||
(1..sample_num).each_with_object([]) do |n, array|
|
||||
array << MigrateKubernetesServiceToNewClustersArchitectures::Project.create!
|
||||
end
|
||||
end
|
||||
|
||||
let!(:kubernetes_services) do
|
||||
projects.map do |project|
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
active: active,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"namespace\":\"prod\",\"api_url\":\"https://kubernetes#{project.id}.com\",\"ca_pem\":\"ca_pem#{project.id}\",\"token\":\"token#{project.id}\"}")
|
||||
end
|
||||
end
|
||||
|
||||
it 'migrates the KubernetesService to Platform::Kubernetes' do
|
||||
expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(sample_num)
|
||||
|
||||
projects.each do |project|
|
||||
project.clusters.last.tap do |cluster|
|
||||
expect(cluster.enabled).to eq(active)
|
||||
expect(cluster.platform_kubernetes.api_url).to eq(project.kubernetes_service.api_url)
|
||||
expect(cluster.platform_kubernetes.ca_cert).to eq(project.kubernetes_service.ca_pem)
|
||||
expect(cluster.platform_kubernetes.token).to eq(project.kubernetes_service.token)
|
||||
expect(project.kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when KubernetesService is active' do
|
||||
let(:active) { true }
|
||||
|
||||
it_behaves_like 'KubernetesService migration'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unique KubernetesService spawned from Service Template' do
|
||||
let(:sample_num) { 2 }
|
||||
|
||||
let(:projects) do
|
||||
(1..sample_num).each_with_object([]) do |n, array|
|
||||
array << MigrateKubernetesServiceToNewClustersArchitectures::Project.create!
|
||||
end
|
||||
end
|
||||
|
||||
let!(:kubernetes_service_template) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
template: true,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"namespace\":\"prod\",\"api_url\":\"https://sample.kubernetes.com\",\"ca_pem\":\"ca_pem-sample\",\"token\":\"token-sample\"}")
|
||||
end
|
||||
|
||||
let!(:kubernetes_services) do
|
||||
projects.map do |project|
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"namespace\":\"prod\",\"api_url\":\"#{kubernetes_service_template.api_url}\",\"ca_pem\":\"#{kubernetes_service_template.ca_pem}\",\"token\":\"#{kubernetes_service_template.token}\"}")
|
||||
end
|
||||
end
|
||||
|
||||
it 'migrates the KubernetesService to Platform::Kubernetes without template' do
|
||||
expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(sample_num)
|
||||
|
||||
projects.each do |project|
|
||||
project.clusters.last.tap do |cluster|
|
||||
expect(cluster.platform_kubernetes.api_url).to eq(project.kubernetes_service.api_url)
|
||||
expect(cluster.platform_kubernetes.ca_cert).to eq(project.kubernetes_service.ca_pem)
|
||||
expect(cluster.platform_kubernetes.token).to eq(project.kubernetes_service.token)
|
||||
expect(project.kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when managed KubernetesService exists' do
|
||||
let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! }
|
||||
|
||||
let(:cluster) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!(
|
||||
projects: [project],
|
||||
name: 'sample-cluster',
|
||||
platform_type: :kubernetes,
|
||||
provider_type: :user,
|
||||
platform_kubernetes_attributes: {
|
||||
api_url: 'https://sample.kubernetes.com',
|
||||
ca_cert: 'ca_pem-sample',
|
||||
token: 'token-sample'
|
||||
} )
|
||||
end
|
||||
|
||||
let!(:kubernetes_service) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
active: cluster.enabled,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"api_url\":\"#{cluster.platform_kubernetes.api_url}\"}")
|
||||
end
|
||||
|
||||
it 'does not migrate the KubernetesService and disables the kubernetes_service' do # Because the corresponding Platform::Kubernetes already exists
|
||||
expect { migrate! }.not_to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }
|
||||
|
||||
kubernetes_service.reload
|
||||
expect(kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
|
||||
context 'when production cluster has already been existed' do # i.e. There are no environment_scope conflicts
|
||||
let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! }
|
||||
|
||||
let(:cluster) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!(
|
||||
projects: [project],
|
||||
name: 'sample-cluster',
|
||||
platform_type: :kubernetes,
|
||||
provider_type: :user,
|
||||
environment_scope: 'production/*',
|
||||
platform_kubernetes_attributes: {
|
||||
api_url: 'https://sample.kubernetes.com',
|
||||
ca_cert: 'ca_pem-sample',
|
||||
token: 'token-sample'
|
||||
} )
|
||||
end
|
||||
|
||||
let!(:kubernetes_service) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
active: true,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"api_url\":\"https://debug.kube.com\"}")
|
||||
end
|
||||
|
||||
it 'migrates the KubernetesService to Platform::Kubernetes' do
|
||||
expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(1)
|
||||
|
||||
kubernetes_service.reload
|
||||
project.clusters.last.tap do |cluster|
|
||||
expect(cluster.environment_scope).to eq('*')
|
||||
expect(cluster.platform_kubernetes.api_url).to eq(kubernetes_service.api_url)
|
||||
expect(cluster.platform_kubernetes.ca_cert).to eq(kubernetes_service.ca_pem)
|
||||
expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token)
|
||||
expect(kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default cluster has already been existed' do
|
||||
let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! }
|
||||
|
||||
let!(:cluster) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!(
|
||||
projects: [project],
|
||||
name: 'sample-cluster',
|
||||
platform_type: :kubernetes,
|
||||
provider_type: :user,
|
||||
environment_scope: '*',
|
||||
platform_kubernetes_attributes: {
|
||||
api_url: 'https://sample.kubernetes.com',
|
||||
ca_cert: 'ca_pem-sample',
|
||||
token: 'token-sample'
|
||||
} )
|
||||
end
|
||||
|
||||
let!(:kubernetes_service) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
active: true,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"api_url\":\"https://debug.kube.com\"}")
|
||||
end
|
||||
|
||||
it 'migrates the KubernetesService to Platform::Kubernetes with dedicated environment_scope' do # Because environment_scope is duplicated
|
||||
expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(1)
|
||||
|
||||
kubernetes_service.reload
|
||||
project.clusters.last.tap do |cluster|
|
||||
expect(cluster.environment_scope).to eq('migrated/*')
|
||||
expect(cluster.platform_kubernetes.api_url).to eq(kubernetes_service.api_url)
|
||||
expect(cluster.platform_kubernetes.ca_cert).to eq(kubernetes_service.ca_pem)
|
||||
expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token)
|
||||
expect(kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default cluster and migrated cluster has already been existed' do
|
||||
let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! }
|
||||
|
||||
let!(:cluster) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!(
|
||||
projects: [project],
|
||||
name: 'sample-cluster',
|
||||
platform_type: :kubernetes,
|
||||
provider_type: :user,
|
||||
environment_scope: '*',
|
||||
platform_kubernetes_attributes: {
|
||||
api_url: 'https://sample.kubernetes.com',
|
||||
ca_cert: 'ca_pem-sample',
|
||||
token: 'token-sample'
|
||||
} )
|
||||
end
|
||||
|
||||
let!(:migrated_cluster) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!(
|
||||
projects: [project],
|
||||
name: 'sample-cluster',
|
||||
platform_type: :kubernetes,
|
||||
provider_type: :user,
|
||||
environment_scope: 'migrated/*',
|
||||
platform_kubernetes_attributes: {
|
||||
api_url: 'https://sample.kubernetes.com',
|
||||
ca_cert: 'ca_pem-sample',
|
||||
token: 'token-sample'
|
||||
} )
|
||||
end
|
||||
|
||||
let!(:kubernetes_service) do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
active: true,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"api_url\":\"https://debug.kube.com\"}")
|
||||
end
|
||||
|
||||
it 'migrates the KubernetesService to Platform::Kubernetes with dedicated environment_scope' do # Because environment_scope is duplicated
|
||||
expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(1)
|
||||
|
||||
kubernetes_service.reload
|
||||
project.clusters.last.tap do |cluster|
|
||||
expect(cluster.environment_scope).to eq('migrated0/*')
|
||||
expect(cluster.platform_kubernetes.api_url).to eq(kubernetes_service.api_url)
|
||||
expect(cluster.platform_kubernetes.ca_cert).to eq(kubernetes_service.ca_pem)
|
||||
expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token)
|
||||
expect(kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when KubernetesService has nullified parameters' do
|
||||
let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! }
|
||||
|
||||
before do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
active: false,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{}")
|
||||
end
|
||||
|
||||
it 'does not migrate the KubernetesService and disables the kubernetes_service' do
|
||||
expect { migrate! }.not_to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }
|
||||
|
||||
expect(project.kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
|
||||
# Platforms::Kubernetes validates `token` reagdless of the activeness,
|
||||
# whereas KubernetesService validates `token` if only it's activated
|
||||
# However, in this migration file, there are no validations because of the re-defined model class
|
||||
# therefore, we should safely add this raw to Platform::Kubernetes
|
||||
context 'when KubernetesService has empty token' do
|
||||
let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! }
|
||||
|
||||
before do
|
||||
MigrateKubernetesServiceToNewClustersArchitectures::Service.create!(
|
||||
project: project,
|
||||
active: false,
|
||||
category: 'deployment',
|
||||
type: 'KubernetesService',
|
||||
properties: "{\"namespace\":\"prod\",\"api_url\":\"http://111.111.111.111\",\"ca_pem\":\"a\",\"token\":\"\"}")
|
||||
end
|
||||
|
||||
it 'does not migrate the KubernetesService and disables the kubernetes_service' do
|
||||
expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(1)
|
||||
|
||||
project.clusters.last.tap do |cluster|
|
||||
expect(cluster.environment_scope).to eq('*')
|
||||
expect(cluster.platform_kubernetes.namespace).to eq('prod')
|
||||
expect(cluster.platform_kubernetes.api_url).to eq('http://111.111.111.111')
|
||||
expect(cluster.platform_kubernetes.ca_cert).to eq('a')
|
||||
expect(cluster.platform_kubernetes.token).to be_empty
|
||||
expect(project.kubernetes_service).not_to be_active
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when KubernetesService does not exist' do
|
||||
let!(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! }
|
||||
|
||||
it 'does not migrate the KubernetesService' do
|
||||
expect { migrate! }.not_to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,140 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170523083112_migrate_old_artifacts.rb')
|
||||
|
||||
# Adding the ci_job_artifacts table (from the 20170918072948 schema)
|
||||
# makes the use of model code below easier.
|
||||
describe MigrateOldArtifacts, :migration, schema: 20170918072948 do
|
||||
let(:migration) { described_class.new }
|
||||
let!(:directory) { Dir.mktmpdir }
|
||||
|
||||
before do
|
||||
allow(Gitlab.config.artifacts).to receive(:path).and_return(directory)
|
||||
end
|
||||
|
||||
after do
|
||||
FileUtils.remove_entry_secure(directory)
|
||||
end
|
||||
|
||||
context 'with migratable data' do
|
||||
let(:projects) { table(:projects) }
|
||||
let(:ci_pipelines) { table(:ci_pipelines) }
|
||||
let(:ci_builds) { table(:ci_builds) }
|
||||
|
||||
let!(:project1) { projects.create!(ci_id: 2) }
|
||||
let!(:project2) { projects.create!(ci_id: 3) }
|
||||
let!(:project3) { projects.create! }
|
||||
|
||||
let!(:pipeline1) { ci_pipelines.create!(project_id: project1.id) }
|
||||
let!(:pipeline2) { ci_pipelines.create!(project_id: project2.id) }
|
||||
let!(:pipeline3) { ci_pipelines.create!(project_id: project3.id) }
|
||||
|
||||
let!(:build_with_legacy_artifacts) { ci_builds.create!(commit_id: pipeline1.id, project_id: project1.id, type: 'Ci::Build').becomes(Ci::Build) }
|
||||
let!(:build_without_artifacts) { ci_builds.create!(commit_id: pipeline1.id, project_id: project1.id, type: 'Ci::Build').becomes(Ci::Build) }
|
||||
let!(:build2) { ci_builds.create!(commit_id: pipeline2.id, project_id: project2.id, type: 'Ci::Build').becomes(Ci::Build) }
|
||||
let!(:build3) { ci_builds.create!(commit_id: pipeline3.id, project_id: project3.id, type: 'Ci::Build').becomes(Ci::Build) }
|
||||
|
||||
before do
|
||||
setup_builds(build2, build3)
|
||||
|
||||
store_artifacts_in_legacy_path(build_with_legacy_artifacts)
|
||||
end
|
||||
|
||||
it "legacy artifacts are not accessible" do
|
||||
expect(build_with_legacy_artifacts.artifacts?).to be_falsey
|
||||
end
|
||||
|
||||
describe '#min_id' do
|
||||
subject { migration.send(:min_id) }
|
||||
|
||||
it 'returns the newest build for which ci_id is not defined' do
|
||||
is_expected.to eq(build3.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#builds_with_artifacts' do
|
||||
subject { migration.send(:builds_with_artifacts).map(&:id) }
|
||||
|
||||
it 'returns a list of builds that has artifacts and could be migrated' do
|
||||
is_expected.to contain_exactly(build_with_legacy_artifacts.id, build2.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
context 'when migrating artifacts' do
|
||||
before do
|
||||
migration.up
|
||||
end
|
||||
|
||||
it 'all files do have artifacts' do
|
||||
Ci::Build.with_artifacts_archive do |build|
|
||||
expect(build).to have_artifacts
|
||||
end
|
||||
end
|
||||
|
||||
it 'artifacts are no longer present on legacy path' do
|
||||
expect(File.exist?(legacy_path(build_with_legacy_artifacts))).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are artifacts in old and new directory' do
|
||||
before do
|
||||
store_artifacts_in_legacy_path(build2)
|
||||
|
||||
migration.up
|
||||
end
|
||||
|
||||
it 'does not move old files' do
|
||||
expect(File.exist?(legacy_path(build2))).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def store_artifacts_in_legacy_path(build)
|
||||
FileUtils.mkdir_p(legacy_path(build))
|
||||
|
||||
FileUtils.copy(
|
||||
Rails.root.join('spec/fixtures/ci_build_artifacts.zip'),
|
||||
File.join(legacy_path(build), "ci_build_artifacts.zip"))
|
||||
|
||||
FileUtils.copy(
|
||||
Rails.root.join('spec/fixtures/ci_build_artifacts_metadata.gz'),
|
||||
File.join(legacy_path(build), "ci_build_artifacts_metadata.gz"))
|
||||
|
||||
build.update_columns(
|
||||
artifacts_file: 'ci_build_artifacts.zip',
|
||||
artifacts_metadata: 'ci_build_artifacts_metadata.gz')
|
||||
|
||||
build.reload
|
||||
end
|
||||
|
||||
def legacy_path(build)
|
||||
File.join(directory,
|
||||
build.created_at.utc.strftime('%Y_%m'),
|
||||
build.project.ci_id.to_s,
|
||||
build.id.to_s)
|
||||
end
|
||||
|
||||
def new_legacy_path(build)
|
||||
File.join(directory,
|
||||
build.created_at.utc.strftime('%Y_%m'),
|
||||
build.project_id.to_s,
|
||||
build.id.to_s)
|
||||
end
|
||||
|
||||
def setup_builds(*builds)
|
||||
builds.each do |build|
|
||||
FileUtils.mkdir_p(new_legacy_path(build))
|
||||
|
||||
build.update_columns(
|
||||
artifacts_file: 'ci_build_artifacts.zip',
|
||||
artifacts_metadata: 'ci_build_artifacts_metadata.gz')
|
||||
|
||||
build.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,49 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170822101017_migrate_pipeline_sidekiq_queues.rb')
|
||||
|
||||
describe MigratePipelineSidekiqQueues, :sidekiq, :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).perform_async('Something', [1])
|
||||
stub_worker(queue: :build).perform_async('Something', [1])
|
||||
|
||||
described_class.new.up
|
||||
|
||||
expect(sidekiq_queue_length('pipeline')).to eq 0
|
||||
expect(sidekiq_queue_length('build')).to eq 0
|
||||
expect(sidekiq_queue_length('pipeline_default')).to eq 2
|
||||
end
|
||||
end
|
||||
|
||||
it 'correctly migrates queue when migrating down' do
|
||||
Sidekiq::Testing.disable! do
|
||||
stub_worker(queue: :pipeline_default).perform_async('Class', [1])
|
||||
stub_worker(queue: :pipeline_processing).perform_async('Class', [2])
|
||||
stub_worker(queue: :pipeline_hooks).perform_async('Class', [3])
|
||||
stub_worker(queue: :pipeline_cache).perform_async('Class', [4])
|
||||
|
||||
described_class.new.down
|
||||
|
||||
expect(sidekiq_queue_length('pipeline')).to eq 4
|
||||
expect(sidekiq_queue_length('pipeline_default')).to eq 0
|
||||
expect(sidekiq_queue_length('pipeline_processing')).to eq 0
|
||||
expect(sidekiq_queue_length('pipeline_hooks')).to eq 0
|
||||
expect(sidekiq_queue_length('pipeline_cache')).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
|
|
@ -1,56 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170526185842_migrate_pipeline_stages.rb')
|
||||
|
||||
describe MigratePipelineStages, :migration do
|
||||
##
|
||||
# Create test data - pipeline and CI/CD jobs.
|
||||
#
|
||||
|
||||
let(:jobs) { table(:ci_builds) }
|
||||
let(:stages) { table(:ci_stages) }
|
||||
let(:pipelines) { table(:ci_pipelines) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
||||
before do
|
||||
# Create projects
|
||||
#
|
||||
projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
|
||||
projects.create!(id: 456, name: 'gitlab2', path: 'gitlab2')
|
||||
|
||||
# Create CI/CD pipelines
|
||||
#
|
||||
pipelines.create!(id: 1, project_id: 123, ref: 'master', sha: 'adf43c3a')
|
||||
pipelines.create!(id: 2, project_id: 456, ref: 'feature', sha: '21a3deb')
|
||||
|
||||
# Create CI/CD jobs
|
||||
#
|
||||
jobs.create!(id: 1, commit_id: 1, project_id: 123, stage_idx: 2, stage: 'build')
|
||||
jobs.create!(id: 2, commit_id: 1, project_id: 123, stage_idx: 2, stage: 'build')
|
||||
jobs.create!(id: 3, commit_id: 1, project_id: 123, stage_idx: 1, stage: 'test')
|
||||
jobs.create!(id: 4, commit_id: 1, project_id: 123, stage_idx: 1, stage: 'test')
|
||||
jobs.create!(id: 5, commit_id: 1, project_id: 123, stage_idx: 3, stage: 'deploy')
|
||||
jobs.create!(id: 6, commit_id: 2, project_id: 456, stage_idx: 3, stage: 'deploy')
|
||||
jobs.create!(id: 7, commit_id: 2, project_id: 456, stage_idx: 2, stage: 'test:2')
|
||||
jobs.create!(id: 8, commit_id: 2, project_id: 456, stage_idx: 1, stage: 'test:1')
|
||||
jobs.create!(id: 9, commit_id: 2, project_id: 456, stage_idx: 1, stage: 'test:1')
|
||||
jobs.create!(id: 10, commit_id: 2, project_id: 456, stage_idx: 2, stage: 'test:2')
|
||||
jobs.create!(id: 11, commit_id: 3, project_id: 456, stage_idx: 3, stage: 'deploy')
|
||||
jobs.create!(id: 12, commit_id: 2, project_id: 789, stage_idx: 3, stage: 'deploy')
|
||||
end
|
||||
|
||||
it 'correctly migrates pipeline stages' do
|
||||
expect(stages.count).to be_zero
|
||||
|
||||
migrate!
|
||||
|
||||
expect(stages.count).to eq 6
|
||||
expect(stages.all.pluck(:name))
|
||||
.to match_array %w[test build deploy test:1 test:2 deploy]
|
||||
expect(stages.where(pipeline_id: 1).order(:id).pluck(:name))
|
||||
.to eq %w[test build deploy]
|
||||
expect(stages.where(pipeline_id: 2).order(:id).pluck(:name))
|
||||
.to eq %w[test:1 test:2 deploy]
|
||||
expect(stages.where(pipeline_id: 3).count).to be_zero
|
||||
expect(stages.where(project_id: 789).count).to be_zero
|
||||
end
|
||||
end
|
|
@ -1,197 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20161124141322_migrate_process_commit_worker_jobs.rb')
|
||||
|
||||
describe MigrateProcessCommitWorkerJobs do
|
||||
set(:project) { create(:project, :legacy_storage, :repository) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
set(:user) { create(:user) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let(:commit) do
|
||||
Gitlab::Git::Commit.last(project.repository.raw)
|
||||
end
|
||||
|
||||
describe 'Project' do
|
||||
describe 'find_including_path' do
|
||||
it 'returns Project instances' do
|
||||
expect(described_class::Project.find_including_path(project.id))
|
||||
.to be_an_instance_of(described_class::Project)
|
||||
end
|
||||
|
||||
it 'selects the full path for every Project' do
|
||||
migration_project = described_class::Project
|
||||
.find_including_path(project.id)
|
||||
|
||||
expect(migration_project[:path_with_namespace])
|
||||
.to eq(project.full_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#repository' do
|
||||
it 'returns a mock implemention of ::Repository' do
|
||||
migration_project = described_class::Project
|
||||
.find_including_path(project.id)
|
||||
|
||||
expect(migration_project.repository).to respond_to(:storage)
|
||||
expect(migration_project.repository).to respond_to(:gitaly_repository)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#up', :clean_gitlab_redis_shared_state do
|
||||
let(:migration) { described_class.new }
|
||||
|
||||
def job_count
|
||||
Sidekiq.redis { |r| r.llen('queue:process_commit') }
|
||||
end
|
||||
|
||||
def pop_job
|
||||
JSON.parse(Sidekiq.redis { |r| r.lpop('queue:process_commit') })
|
||||
end
|
||||
|
||||
before do
|
||||
Sidekiq.redis do |redis|
|
||||
job = JSON.dump(args: [project.id, user.id, commit.id])
|
||||
redis.lpush('queue:process_commit', job)
|
||||
end
|
||||
end
|
||||
|
||||
it 'skips jobs using a project that no longer exists' do
|
||||
allow(described_class::Project).to receive(:find_including_path)
|
||||
.with(project.id)
|
||||
.and_return(nil)
|
||||
|
||||
migration.up
|
||||
|
||||
expect(job_count).to eq(0)
|
||||
end
|
||||
|
||||
it 'skips jobs using commits that no longer exist' do
|
||||
allow_any_instance_of(Gitlab::GitalyClient::CommitService)
|
||||
.to receive(:find_commit)
|
||||
.with(commit.id)
|
||||
.and_return(nil)
|
||||
|
||||
migration.up
|
||||
|
||||
expect(job_count).to eq(0)
|
||||
end
|
||||
|
||||
it 'inserts migrated jobs back into the queue' do
|
||||
migration.up
|
||||
|
||||
expect(job_count).to eq(1)
|
||||
end
|
||||
|
||||
it 'encodes data to UTF-8' do
|
||||
allow(commit).to receive(:body)
|
||||
.and_return('김치'.force_encoding('BINARY'))
|
||||
|
||||
migration.up
|
||||
|
||||
job = pop_job
|
||||
|
||||
# We don't care so much about what is being stored, instead we just want
|
||||
# to make sure the encoding is right so that JSON encoding the data
|
||||
# doesn't produce any errors.
|
||||
expect(job['args'][2]['message'].encoding).to eq(Encoding::UTF_8)
|
||||
end
|
||||
|
||||
context 'a migrated job' do
|
||||
let(:job) do
|
||||
migration.up
|
||||
pop_job
|
||||
end
|
||||
|
||||
let(:commit_hash) do
|
||||
job['args'][2]
|
||||
end
|
||||
|
||||
it 'includes the project ID' do
|
||||
expect(job['args'][0]).to eq(project.id)
|
||||
end
|
||||
|
||||
it 'includes the user ID' do
|
||||
expect(job['args'][1]).to eq(user.id)
|
||||
end
|
||||
|
||||
it 'includes the commit ID' do
|
||||
expect(commit_hash['id']).to eq(commit.id)
|
||||
end
|
||||
|
||||
it 'includes the commit message' do
|
||||
expect(commit_hash['message']).to eq(commit.message)
|
||||
end
|
||||
|
||||
it 'includes the parent IDs' do
|
||||
expect(commit_hash['parent_ids']).to eq(commit.parent_ids)
|
||||
end
|
||||
|
||||
it 'includes the author date' do
|
||||
expect(commit_hash['authored_date']).to eq(commit.authored_date.to_s)
|
||||
end
|
||||
|
||||
it 'includes the author name' do
|
||||
expect(commit_hash['author_name']).to eq(commit.author_name)
|
||||
end
|
||||
|
||||
it 'includes the author Email' do
|
||||
expect(commit_hash['author_email']).to eq(commit.author_email)
|
||||
end
|
||||
|
||||
it 'includes the commit date' do
|
||||
expect(commit_hash['committed_date']).to eq(commit.committed_date.to_s)
|
||||
end
|
||||
|
||||
it 'includes the committer name' do
|
||||
expect(commit_hash['committer_name']).to eq(commit.committer_name)
|
||||
end
|
||||
|
||||
it 'includes the committer Email' do
|
||||
expect(commit_hash['committer_email']).to eq(commit.committer_email)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down', :clean_gitlab_redis_shared_state do
|
||||
let(:migration) { described_class.new }
|
||||
|
||||
def job_count
|
||||
Sidekiq.redis { |r| r.llen('queue:process_commit') }
|
||||
end
|
||||
|
||||
before do
|
||||
Sidekiq.redis do |redis|
|
||||
job = JSON.dump(args: [project.id, user.id, commit.id])
|
||||
redis.lpush('queue:process_commit', job)
|
||||
|
||||
migration.up
|
||||
end
|
||||
end
|
||||
|
||||
it 'pushes migrated jobs back into the queue' do
|
||||
migration.down
|
||||
|
||||
expect(job_count).to eq(1)
|
||||
end
|
||||
|
||||
context 'a migrated job' do
|
||||
let(:job) do
|
||||
migration.down
|
||||
|
||||
JSON.parse(Sidekiq.redis { |r| r.lpop('queue:process_commit') })
|
||||
end
|
||||
|
||||
it 'includes the project ID' do
|
||||
expect(job['args'][0]).to eq(project.id)
|
||||
end
|
||||
|
||||
it 'includes the user ID' do
|
||||
expect(job['args'][1]).to eq(user.id)
|
||||
end
|
||||
|
||||
it 'includes the commit SHA' do
|
||||
expect(job['args'][2]).to eq(commit.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,55 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170628080858_migrate_stage_id_reference_in_background')
|
||||
|
||||
describe MigrateStageIdReferenceInBackground, :migration, :sidekiq do
|
||||
let(:jobs) { table(:ci_builds) }
|
||||
let(:stages) { table(:ci_stages) }
|
||||
let(:pipelines) { table(:ci_pipelines) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
||||
before do
|
||||
stub_const("#{described_class.name}::BATCH_SIZE", 3)
|
||||
stub_const("#{described_class.name}::RANGE_SIZE", 2)
|
||||
|
||||
projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
|
||||
projects.create!(id: 345, name: 'gitlab2', path: 'gitlab2')
|
||||
|
||||
pipelines.create!(id: 1, project_id: 123, ref: 'master', sha: 'adf43c3a')
|
||||
pipelines.create!(id: 2, project_id: 345, ref: 'feature', sha: 'cdf43c3c')
|
||||
|
||||
jobs.create!(id: 1, commit_id: 1, project_id: 123, stage_idx: 2, stage: 'build')
|
||||
jobs.create!(id: 2, commit_id: 1, project_id: 123, stage_idx: 2, stage: 'build')
|
||||
jobs.create!(id: 3, commit_id: 1, project_id: 123, stage_idx: 1, stage: 'test')
|
||||
jobs.create!(id: 4, commit_id: 1, project_id: 123, stage_idx: 3, stage: 'deploy')
|
||||
jobs.create!(id: 5, commit_id: 2, project_id: 345, stage_idx: 1, stage: 'test')
|
||||
|
||||
stages.create(id: 101, pipeline_id: 1, project_id: 123, name: 'test')
|
||||
stages.create(id: 102, pipeline_id: 1, project_id: 123, name: 'build')
|
||||
stages.create(id: 103, pipeline_id: 1, project_id: 123, name: 'deploy')
|
||||
|
||||
jobs.create!(id: 6, commit_id: 2, project_id: 345, stage_id: 101, stage_idx: 1, stage: 'test')
|
||||
end
|
||||
|
||||
it 'correctly schedules background migrations' do
|
||||
Sidekiq::Testing.fake! do
|
||||
Timecop.freeze do
|
||||
migrate!
|
||||
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 2)
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 3, 3)
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, 4, 5)
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'schedules background migrations' do
|
||||
perform_enqueued_jobs do
|
||||
expect(jobs.where(stage_id: nil).count).to eq 5
|
||||
|
||||
migrate!
|
||||
|
||||
expect(jobs.where(stage_id: nil).count).to eq 1
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,68 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170711145558_migrate_stages_statuses.rb')
|
||||
|
||||
describe MigrateStagesStatuses, :sidekiq, :migration do
|
||||
let(:jobs) { table(:ci_builds) }
|
||||
let(:stages) { table(:ci_stages) }
|
||||
let(:pipelines) { table(:ci_pipelines) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
||||
STATUSES = { created: 0, pending: 1, running: 2, success: 3,
|
||||
failed: 4, canceled: 5, skipped: 6, manual: 7 }.freeze
|
||||
|
||||
before do
|
||||
stub_const("#{described_class.name}::BATCH_SIZE", 2)
|
||||
stub_const("#{described_class.name}::RANGE_SIZE", 1)
|
||||
|
||||
projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1')
|
||||
projects.create!(id: 2, name: 'gitlab2', path: 'gitlab2')
|
||||
|
||||
pipelines.create!(id: 1, project_id: 1, ref: 'master', sha: 'adf43c3a')
|
||||
pipelines.create!(id: 2, project_id: 2, ref: 'feature', sha: '21a3deb')
|
||||
|
||||
create_job(project: 1, pipeline: 1, stage: 'test', status: 'success')
|
||||
create_job(project: 1, pipeline: 1, stage: 'test', status: 'running')
|
||||
create_job(project: 1, pipeline: 1, stage: 'build', status: 'success')
|
||||
create_job(project: 1, pipeline: 1, stage: 'build', status: 'failed')
|
||||
create_job(project: 2, pipeline: 2, stage: 'test', status: 'success')
|
||||
create_job(project: 2, pipeline: 2, stage: 'test', status: 'success')
|
||||
create_job(project: 2, pipeline: 2, stage: 'test', status: 'failed', retried: true)
|
||||
|
||||
stages.create!(id: 1, pipeline_id: 1, project_id: 1, name: 'test', status: nil)
|
||||
stages.create!(id: 2, pipeline_id: 1, project_id: 1, name: 'build', status: nil)
|
||||
stages.create!(id: 3, pipeline_id: 2, project_id: 2, name: 'test', status: nil)
|
||||
end
|
||||
|
||||
it 'correctly migrates stages statuses' do
|
||||
perform_enqueued_jobs do
|
||||
expect(stages.where(status: nil).count).to eq 3
|
||||
|
||||
migrate!
|
||||
|
||||
expect(stages.where(status: nil)).to be_empty
|
||||
expect(stages.all.order('id ASC').pluck(:status))
|
||||
.to eq [STATUSES[:running], STATUSES[:failed], STATUSES[:success]]
|
||||
end
|
||||
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(5.minutes, 2, 2)
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, 3, 3)
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_job(project:, pipeline:, stage:, status:, **opts)
|
||||
stages = { test: 1, build: 2, deploy: 3 }
|
||||
|
||||
jobs.create!(project_id: project, commit_id: pipeline,
|
||||
stage_idx: stages[stage.to_sym], stage: stage,
|
||||
status: status, **opts)
|
||||
end
|
||||
end
|
|
@ -1,49 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170324160416_migrate_user_activities_to_users_last_activity_on.rb')
|
||||
|
||||
describe MigrateUserActivitiesToUsersLastActivityOn, :clean_gitlab_redis_shared_state, :migration do
|
||||
let(:migration) { described_class.new }
|
||||
let!(:user_active_1) { table(:users).create!(email: 'test1', username: 'test1') }
|
||||
let!(:user_active_2) { table(:users).create!(email: 'test2', username: 'test2') }
|
||||
|
||||
def record_activity(user, time)
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.zadd(described_class::USER_ACTIVITY_SET_KEY, time.to_i, user.username)
|
||||
end
|
||||
end
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze { example.run }
|
||||
end
|
||||
|
||||
before do
|
||||
record_activity(user_active_1, described_class::TIME_WHEN_ACTIVITY_SET_WAS_INTRODUCED + 2.months)
|
||||
record_activity(user_active_2, described_class::TIME_WHEN_ACTIVITY_SET_WAS_INTRODUCED + 3.months)
|
||||
mute_stdout { migration.up }
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
it 'fills last_activity_on from the legacy Redis Sorted Set' do
|
||||
expect(user_active_1.reload.last_activity_on).to eq((described_class::TIME_WHEN_ACTIVITY_SET_WAS_INTRODUCED + 2.months).to_date)
|
||||
expect(user_active_2.reload.last_activity_on).to eq((described_class::TIME_WHEN_ACTIVITY_SET_WAS_INTRODUCED + 3.months).to_date)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'sets last_activity_on to NULL for all users' do
|
||||
mute_stdout { migration.down }
|
||||
|
||||
expect(user_active_1.reload.last_activity_on).to be_nil
|
||||
expect(user_active_2.reload.last_activity_on).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
def mute_stdout
|
||||
orig_stdout = $stdout
|
||||
$stdout = StringIO.new
|
||||
yield
|
||||
$stdout = orig_stdout
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20171012125712_migrate_user_authentication_token_to_personal_access_token.rb')
|
||||
|
||||
describe MigrateUserAuthenticationTokenToPersonalAccessToken, :migration do
|
||||
let(:users) { table(:users) }
|
||||
let(:personal_access_tokens) { table(:personal_access_tokens) }
|
||||
|
||||
let!(:user) { users.create!(id: 1, email: 'user@example.com', authentication_token: 'user-token', admin: false) }
|
||||
let!(:admin) { users.create!(id: 2, email: 'admin@example.com', authentication_token: 'admin-token', admin: true) }
|
||||
|
||||
it 'migrates private tokens to Personal Access Tokens' do
|
||||
migrate!
|
||||
|
||||
expect(personal_access_tokens.count).to eq(2)
|
||||
|
||||
user_token = personal_access_tokens.find_by(user_id: user.id)
|
||||
admin_token = personal_access_tokens.find_by(user_id: admin.id)
|
||||
|
||||
expect(user_token.token).to eq('user-token')
|
||||
expect(admin_token.token).to eq('admin-token')
|
||||
|
||||
expect(user_token.scopes).to eq(%w[api].to_yaml)
|
||||
expect(admin_token.scopes).to eq(%w[api sudo].to_yaml)
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170406142253_migrate_user_project_view.rb')
|
||||
|
||||
describe MigrateUserProjectView, :migration do
|
||||
let(:migration) { described_class.new }
|
||||
let!(:user) { table(:users).create!(project_view: User.project_views['readme']) }
|
||||
|
||||
describe '#up' do
|
||||
it 'updates project view setting with new value' do
|
||||
migration.up
|
||||
|
||||
expect(user.reload.project_view).to eq(User.project_views['files'])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,197 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170612071012_move_personal_snippets_files.rb')
|
||||
|
||||
describe MovePersonalSnippetsFiles, :migration do
|
||||
let(:migration) { described_class.new }
|
||||
let(:test_dir) { File.join(Rails.root, "tmp", "tests", "move_snippet_files_test") }
|
||||
let(:uploads_dir) { File.join(test_dir, 'uploads') }
|
||||
let(:new_uploads_dir) { File.join(uploads_dir, '-', 'system') }
|
||||
|
||||
let(:notes) { table(:notes) }
|
||||
let(:snippets) { table(:snippets) }
|
||||
let(:uploads) { table(:uploads) }
|
||||
|
||||
let(:user) { table(:users).create!(email: 'user@example.com', projects_limit: 10) }
|
||||
let(:project) { table(:projects).create!(name: 'gitlab', namespace_id: 1) }
|
||||
|
||||
before do
|
||||
allow(CarrierWave).to receive(:root).and_return(test_dir)
|
||||
allow(migration).to receive(:base_directory).and_return(test_dir)
|
||||
FileUtils.remove_dir(test_dir) if File.directory?(test_dir)
|
||||
allow(migration).to receive(:say)
|
||||
end
|
||||
|
||||
describe "#up" do
|
||||
let(:snippet) do
|
||||
snippet = snippets.create!(author_id: user.id)
|
||||
create_upload('picture.jpg', snippet)
|
||||
snippet.update(description: markdown_linking_file('picture.jpg', snippet))
|
||||
snippet
|
||||
end
|
||||
|
||||
let(:snippet_with_missing_file) do
|
||||
snippet = snippets.create!(author_id: user.id, project_id: project.id)
|
||||
create_upload('picture.jpg', snippet, create_file: false)
|
||||
snippet.update(description: markdown_linking_file('picture.jpg', snippet))
|
||||
snippet
|
||||
end
|
||||
|
||||
it 'moves the files' do
|
||||
source_path = File.join(uploads_dir, model_file_path('picture.jpg', snippet))
|
||||
destination_path = File.join(new_uploads_dir, model_file_path('picture.jpg', snippet))
|
||||
|
||||
migration.up
|
||||
|
||||
expect(File.exist?(source_path)).to be_falsy
|
||||
expect(File.exist?(destination_path)).to be_truthy
|
||||
end
|
||||
|
||||
describe 'updating the markdown' do
|
||||
it 'includes the new path when the file exists' do
|
||||
secret = "secret#{snippet.id}"
|
||||
file_location = "/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
|
||||
|
||||
migration.up
|
||||
|
||||
expect(snippet.reload.description).to include(file_location)
|
||||
end
|
||||
|
||||
it 'does not update the markdown when the file is missing' do
|
||||
secret = "secret#{snippet_with_missing_file.id}"
|
||||
file_location = "/uploads/personal_snippet/#{snippet_with_missing_file.id}/#{secret}/picture.jpg"
|
||||
|
||||
migration.up
|
||||
|
||||
expect(snippet_with_missing_file.reload.description).to include(file_location)
|
||||
end
|
||||
|
||||
it 'updates the note markdown' do
|
||||
secret = "secret#{snippet.id}"
|
||||
file_location = "/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
|
||||
markdown = markdown_linking_file('picture.jpg', snippet)
|
||||
note = notes.create!(noteable_id: snippet.id,
|
||||
noteable_type: Snippet,
|
||||
note: "with #{markdown}",
|
||||
author_id: user.id)
|
||||
|
||||
migration.up
|
||||
|
||||
expect(note.reload.note).to include(file_location)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#down" do
|
||||
let(:snippet) do
|
||||
snippet = snippets.create!(author_id: user.id)
|
||||
create_upload('picture.jpg', snippet, in_new_path: true)
|
||||
snippet.update(description: markdown_linking_file('picture.jpg', snippet, in_new_path: true))
|
||||
snippet
|
||||
end
|
||||
|
||||
let(:snippet_with_missing_file) do
|
||||
snippet = snippets.create!(author_id: user.id)
|
||||
create_upload('picture.jpg', snippet, create_file: false, in_new_path: true)
|
||||
snippet.update(description: markdown_linking_file('picture.jpg', snippet, in_new_path: true))
|
||||
snippet
|
||||
end
|
||||
|
||||
it 'moves the files' do
|
||||
source_path = File.join(new_uploads_dir, model_file_path('picture.jpg', snippet))
|
||||
destination_path = File.join(uploads_dir, model_file_path('picture.jpg', snippet))
|
||||
|
||||
migration.down
|
||||
|
||||
expect(File.exist?(source_path)).to be_falsey
|
||||
expect(File.exist?(destination_path)).to be_truthy
|
||||
end
|
||||
|
||||
describe 'updating the markdown' do
|
||||
it 'includes the new path when the file exists' do
|
||||
secret = "secret#{snippet.id}"
|
||||
file_location = "/uploads/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
|
||||
|
||||
migration.down
|
||||
|
||||
expect(snippet.reload.description).to include(file_location)
|
||||
end
|
||||
|
||||
it 'keeps the markdown as is when the file is missing' do
|
||||
secret = "secret#{snippet_with_missing_file.id}"
|
||||
file_location = "/uploads/-/system/personal_snippet/#{snippet_with_missing_file.id}/#{secret}/picture.jpg"
|
||||
|
||||
migration.down
|
||||
|
||||
expect(snippet_with_missing_file.reload.description).to include(file_location)
|
||||
end
|
||||
|
||||
it 'updates the note markdown' do
|
||||
markdown = markdown_linking_file('picture.jpg', snippet, in_new_path: true)
|
||||
secret = "secret#{snippet.id}"
|
||||
file_location = "/uploads/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
|
||||
note = notes.create!(noteable_id: snippet.id,
|
||||
noteable_type: Snippet,
|
||||
note: "with #{markdown}",
|
||||
author_id: user.id)
|
||||
|
||||
migration.down
|
||||
|
||||
expect(note.reload.note).to include(file_location)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update_markdown' do
|
||||
it 'escapes sql in the snippet description' do
|
||||
migration.instance_variable_set('@source_relative_location', '/uploads/personal_snippet')
|
||||
migration.instance_variable_set('@destination_relative_location', '/uploads/system/personal_snippet')
|
||||
|
||||
secret = '123456789'
|
||||
filename = 'hello.jpg'
|
||||
snippet = snippets.create!(author_id: user.id)
|
||||
|
||||
path_before = "/uploads/personal_snippet/#{snippet.id}/#{secret}/#{filename}"
|
||||
path_after = "/uploads/system/personal_snippet/#{snippet.id}/#{secret}/#{filename}"
|
||||
description_before = "Hello world; ![image](#{path_before})'; select * from users;"
|
||||
description_after = "Hello world; ![image](#{path_after})'; select * from users;"
|
||||
|
||||
migration.update_markdown(snippet.id, secret, filename, description_before)
|
||||
|
||||
expect(snippet.reload.description).to eq(description_after)
|
||||
end
|
||||
end
|
||||
|
||||
def create_upload(filename, snippet, create_file: true, in_new_path: false)
|
||||
secret = "secret#{snippet.id}"
|
||||
absolute_path = if in_new_path
|
||||
File.join(new_uploads_dir, model_file_path(filename, snippet))
|
||||
else
|
||||
File.join(uploads_dir, model_file_path(filename, snippet))
|
||||
end
|
||||
|
||||
if create_file
|
||||
FileUtils.mkdir_p(File.dirname(absolute_path))
|
||||
FileUtils.touch(absolute_path)
|
||||
end
|
||||
|
||||
uploads.create!(model_id: snippet.id,
|
||||
model_type: snippet.class,
|
||||
path: "#{secret}/#{filename}",
|
||||
uploader: PersonalFileUploader,
|
||||
size: 100.kilobytes)
|
||||
end
|
||||
|
||||
def markdown_linking_file(filename, snippet, in_new_path: false)
|
||||
markdown = "![#{filename.split('.')[0]}]"
|
||||
markdown += '(/uploads'
|
||||
markdown += '/-/system' if in_new_path
|
||||
markdown += "/#{model_file_path(filename, snippet)})"
|
||||
markdown
|
||||
end
|
||||
|
||||
def model_file_path(filename, snippet)
|
||||
secret = "secret#{snippet.id}"
|
||||
|
||||
File.join('personal_snippet', snippet.id.to_s, secret, filename)
|
||||
end
|
||||
end
|
|
@ -1,80 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join("db", "migrate", "20170717074009_move_system_upload_folder.rb")
|
||||
|
||||
describe MoveSystemUploadFolder do
|
||||
let(:migration) { described_class.new }
|
||||
let(:test_base) { File.join(Rails.root, 'tmp', 'tests', 'move-system-upload-folder') }
|
||||
|
||||
before do
|
||||
allow(migration).to receive(:base_directory).and_return(test_base)
|
||||
FileUtils.rm_rf(test_base)
|
||||
FileUtils.mkdir_p(test_base)
|
||||
allow(migration).to receive(:say)
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
let(:test_folder) { File.join(test_base, 'system') }
|
||||
let(:test_file) { File.join(test_folder, 'file') }
|
||||
|
||||
before do
|
||||
FileUtils.mkdir_p(test_folder)
|
||||
FileUtils.touch(test_file)
|
||||
end
|
||||
|
||||
it 'moves the related folder' do
|
||||
migration.up
|
||||
|
||||
expect(File.exist?(File.join(test_base, '-', 'system', 'file'))).to be_truthy
|
||||
end
|
||||
|
||||
it 'creates a symlink linking making the new folder available on the old path' do
|
||||
migration.up
|
||||
|
||||
expect(File.symlink?(File.join(test_base, 'system'))).to be_truthy
|
||||
expect(File.exist?(File.join(test_base, 'system', 'file'))).to be_truthy
|
||||
end
|
||||
|
||||
it 'does not move if the target directory already exists' do
|
||||
FileUtils.mkdir_p(File.join(test_base, '-', 'system'))
|
||||
|
||||
expect(FileUtils).not_to receive(:mv)
|
||||
expect(migration).to receive(:say).with(/already exists. No need to redo the move/)
|
||||
|
||||
migration.up
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
let(:test_folder) { File.join(test_base, '-', 'system') }
|
||||
let(:test_file) { File.join(test_folder, 'file') }
|
||||
|
||||
before do
|
||||
FileUtils.mkdir_p(test_folder)
|
||||
FileUtils.touch(test_file)
|
||||
end
|
||||
|
||||
it 'moves the system folder back to the old location' do
|
||||
migration.down
|
||||
|
||||
expect(File.exist?(File.join(test_base, 'system', 'file'))).to be_truthy
|
||||
end
|
||||
|
||||
it 'removes the symlink if it existed' do
|
||||
FileUtils.ln_s(test_folder, File.join(test_base, 'system'))
|
||||
|
||||
migration.down
|
||||
|
||||
expect(File.directory?(File.join(test_base, 'system'))).to be_truthy
|
||||
expect(File.symlink?(File.join(test_base, 'system'))).to be_falsey
|
||||
end
|
||||
|
||||
it 'does not move if the old directory already exists' do
|
||||
FileUtils.mkdir_p(File.join(test_base, 'system'))
|
||||
|
||||
expect(FileUtils).not_to receive(:mv)
|
||||
expect(migration).to receive(:say).with(/already exists and is not a symlink, no need to revert/)
|
||||
|
||||
migration.down
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,68 +0,0 @@
|
|||
require "spec_helper"
|
||||
require Rails.root.join("db", "migrate", "20170316163845_move_uploads_to_system_dir.rb")
|
||||
|
||||
describe MoveUploadsToSystemDir do
|
||||
let(:migration) { described_class.new }
|
||||
let(:test_dir) { File.join(Rails.root, "tmp", "move_uploads_test") }
|
||||
let(:uploads_dir) { File.join(test_dir, "public", "uploads") }
|
||||
let(:new_uploads_dir) { File.join(uploads_dir, "-", "system") }
|
||||
|
||||
before do
|
||||
FileUtils.remove_dir(test_dir) if File.directory?(test_dir)
|
||||
FileUtils.mkdir_p(uploads_dir)
|
||||
allow(migration).to receive(:base_directory).and_return(test_dir)
|
||||
allow(migration).to receive(:say)
|
||||
end
|
||||
|
||||
describe "#up" do
|
||||
before do
|
||||
FileUtils.mkdir_p(File.join(uploads_dir, 'user'))
|
||||
FileUtils.touch(File.join(uploads_dir, 'user', 'dummy.file'))
|
||||
end
|
||||
|
||||
it 'moves the directory to the new path' do
|
||||
expected_path = File.join(new_uploads_dir, 'user', 'dummy.file')
|
||||
|
||||
migration.up
|
||||
|
||||
expect(File.exist?(expected_path)).to be(true)
|
||||
end
|
||||
|
||||
it 'creates a symlink in the old location' do
|
||||
symlink_path = File.join(uploads_dir, 'user')
|
||||
expected_path = File.join(symlink_path, 'dummy.file')
|
||||
|
||||
migration.up
|
||||
|
||||
expect(File.exist?(expected_path)).to be(true)
|
||||
expect(File.symlink?(symlink_path)).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#down" do
|
||||
before do
|
||||
FileUtils.mkdir_p(File.join(new_uploads_dir, 'user'))
|
||||
FileUtils.touch(File.join(new_uploads_dir, 'user', 'dummy.file'))
|
||||
end
|
||||
|
||||
it 'moves the directory to the old path' do
|
||||
expected_path = File.join(uploads_dir, 'user', 'dummy.file')
|
||||
|
||||
migration.down
|
||||
|
||||
expect(File.exist?(expected_path)).to be(true)
|
||||
end
|
||||
|
||||
it 'removes the symlink if it existed' do
|
||||
FileUtils.ln_s(File.join(new_uploads_dir, 'user'), File.join(uploads_dir, 'user'))
|
||||
|
||||
directory = File.join(uploads_dir, 'user')
|
||||
expected_path = File.join(directory, 'dummy.file')
|
||||
|
||||
migration.down
|
||||
|
||||
expect(File.exist?(expected_path)).to be(true)
|
||||
expect(File.symlink?(directory)).to be(false)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,56 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170921101004_normalize_ldap_extern_uids')
|
||||
|
||||
describe NormalizeLdapExternUids, :migration, :sidekiq do
|
||||
let!(:identities) { table(:identities) }
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze { example.run }
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const("Gitlab::Database::MigrationHelpers::BACKGROUND_MIGRATION_BATCH_SIZE", 2)
|
||||
stub_const("Gitlab::Database::MigrationHelpers::BACKGROUND_MIGRATION_JOB_BUFFER_SIZE", 2)
|
||||
|
||||
# LDAP identities
|
||||
(1..4).each do |i|
|
||||
identities.create!(id: i, provider: 'ldapmain', extern_uid: " uid = foo #{i}, ou = People, dc = example, dc = com ", user_id: i)
|
||||
end
|
||||
|
||||
# Non-LDAP identity
|
||||
identities.create!(id: 5, provider: 'foo', extern_uid: " uid = foo 5, ou = People, dc = example, dc = com ", user_id: 5)
|
||||
end
|
||||
|
||||
it 'correctly schedules background migrations' do
|
||||
Sidekiq::Testing.fake! do
|
||||
Timecop.freeze do
|
||||
migrate!
|
||||
|
||||
expect(BackgroundMigrationWorker.jobs[0]['args']).to eq([described_class::MIGRATION, [1, 2]])
|
||||
expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(2.minutes.from_now.to_f)
|
||||
expect(BackgroundMigrationWorker.jobs[1]['args']).to eq([described_class::MIGRATION, [3, 4]])
|
||||
expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(4.minutes.from_now.to_f)
|
||||
expect(BackgroundMigrationWorker.jobs[2]['args']).to eq([described_class::MIGRATION, [5, 5]])
|
||||
expect(BackgroundMigrationWorker.jobs[2]['at']).to eq(6.minutes.from_now.to_f)
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'migrates the LDAP identities' do
|
||||
perform_enqueued_jobs do
|
||||
migrate!
|
||||
identities.where(id: 1..4).each do |identity|
|
||||
expect(identity.extern_uid).to eq("uid=foo #{identity.id},ou=people,dc=example,dc=com")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not modify non-LDAP identities' do
|
||||
perform_enqueued_jobs do
|
||||
migrate!
|
||||
identity = identities.last
|
||||
expect(identity.extern_uid).to eq(" uid = foo 5, ou = People, dc = example, dc = com ")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,43 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20171215113714_populate_can_push_from_deploy_keys_projects.rb')
|
||||
|
||||
describe PopulateCanPushFromDeployKeysProjects, :migration do
|
||||
let(:migration) { described_class.new }
|
||||
let(:deploy_keys) { table(:keys) }
|
||||
let(:deploy_keys_projects) { table(:deploy_keys_projects) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
||||
before do
|
||||
deploy_keys.inheritance_column = nil
|
||||
|
||||
projects.create!(id: 1, name: 'gitlab1', path: 'gitlab1')
|
||||
(1..10).each do |index|
|
||||
deploy_keys.create!(id: index, title: 'dummy', type: 'DeployKey', key: Spec::Support::Helpers::KeyGeneratorHelper.new(1024).generate + ' dummy@gitlab.com')
|
||||
deploy_keys_projects.create!(id: index, deploy_key_id: index, project_id: 1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
it 'migrates can_push from deploy_keys to deploy_keys_projects' do
|
||||
deploy_keys.limit(5).update_all(can_push: true)
|
||||
|
||||
expected = deploy_keys.order(:id).pluck(:id, :can_push)
|
||||
|
||||
migration.up
|
||||
|
||||
expect(deploy_keys_projects.order(:id).pluck(:deploy_key_id, :can_push)).to eq expected
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'migrates can_push from deploy_keys_projects to deploy_keys' do
|
||||
deploy_keys_projects.limit(5).update_all(can_push: true)
|
||||
|
||||
expected = deploy_keys_projects.order(:id).pluck(:deploy_key_id, :can_push)
|
||||
|
||||
migration.down
|
||||
|
||||
expect(deploy_keys.order(:id).pluck(:id, :can_push)).to eq expected
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170523073948_remove_assignee_id_from_issue.rb')
|
||||
|
||||
describe RemoveAssigneeIdFromIssue, :migration do
|
||||
let(:issues) { table(:issues) }
|
||||
let(:issue_assignees) { table(:issue_assignees) }
|
||||
let(:users) { table(:users) }
|
||||
|
||||
let!(:user_1) { users.create(email: 'email1@example.com') }
|
||||
let!(:user_2) { users.create(email: 'email2@example.com') }
|
||||
let!(:user_3) { users.create(email: 'email3@example.com') }
|
||||
|
||||
def create_issue(assignees:)
|
||||
issues.create.tap do |issue|
|
||||
assignees.each do |assignee|
|
||||
issue_assignees.create(issue_id: issue.id, user_id: assignee.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let!(:issue_single_assignee) { create_issue(assignees: [user_1]) }
|
||||
let!(:issue_no_assignee) { create_issue(assignees: []) }
|
||||
let!(:issue_multiple_assignees) { create_issue(assignees: [user_2, user_3]) }
|
||||
|
||||
describe '#down' do
|
||||
it 'sets the assignee_id to a random matching assignee from the assignees table' do
|
||||
migrate!
|
||||
disable_migrations_output { described_class.new.down }
|
||||
|
||||
expect(issue_single_assignee.reload.assignee_id).to eq(user_1.id)
|
||||
expect(issue_no_assignee.reload.assignee_id).to be_nil
|
||||
expect(issue_multiple_assignees.reload.assignee_id).to eq(user_2.id).or(user_3.id)
|
||||
|
||||
disable_migrations_output { described_class.new.up }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,58 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20161226122833_remove_dot_git_from_usernames.rb')
|
||||
|
||||
describe RemoveDotGitFromUsernames do
|
||||
let(:user) { create(:user) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let(:migration) { described_class.new }
|
||||
|
||||
describe '#up' do
|
||||
before do
|
||||
update_namespace(user, 'test.git')
|
||||
end
|
||||
|
||||
it 'renames user with .git in username' do
|
||||
migration.up
|
||||
|
||||
expect(user.reload.username).to eq('test_git')
|
||||
expect(user.namespace.reload.path).to eq('test_git')
|
||||
expect(user.namespace.route.path).to eq('test_git')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when new path exists already' do
|
||||
describe '#up' do
|
||||
let(:user2) { create(:user) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
|
||||
before do
|
||||
update_namespace(user, 'test.git')
|
||||
update_namespace(user2, 'test_git')
|
||||
|
||||
default_hash = Gitlab.config.repositories.storages.default.to_h
|
||||
default_hash['path'] = 'tmp/tests/custom_repositories'
|
||||
storages = { 'default' => Gitlab::GitalyClient::StorageSettings.new(default_hash) }
|
||||
|
||||
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
|
||||
allow(migration).to receive(:route_exists?).with('test_git').and_return(true)
|
||||
allow(migration).to receive(:route_exists?).with('test_git1').and_return(false)
|
||||
end
|
||||
|
||||
it 'renames user with .git in username' do
|
||||
migration.up
|
||||
|
||||
expect(user.reload.username).to eq('test_git1')
|
||||
expect(user.namespace.reload.path).to eq('test_git1')
|
||||
expect(user.namespace.route.path).to eq('test_git1')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_namespace(user, path)
|
||||
namespace = user.namespace
|
||||
namespace.path = path
|
||||
namespace.save!(validate: false)
|
||||
|
||||
user.update_column(:username, path)
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170815060945_remove_duplicate_mr_events.rb')
|
||||
|
||||
describe RemoveDuplicateMrEvents, :delete do
|
||||
let(:migration) { described_class.new }
|
||||
|
||||
describe '#up' do
|
||||
let(:user) { create(:user) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let(:merge_requests) { create_list(:merge_request, 2) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let(:issue) { create(:issue) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let!(:events) do
|
||||
[
|
||||
create(:event, :created, author: user, target: merge_requests.first), # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
create(:event, :created, author: user, target: merge_requests.first), # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
create(:event, :updated, author: user, target: merge_requests.first), # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
create(:event, :created, author: user, target: merge_requests.second), # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
create(:event, :created, author: user, target: issue), # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
create(:event, :created, author: user, target: issue) # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
]
|
||||
end
|
||||
|
||||
it 'removes duplicated merge request create records' do
|
||||
expect { migration.up }.to change { Event.count }.from(6).to(5)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20171114104051_remove_empty_fork_networks.rb')
|
||||
|
||||
describe RemoveEmptyForkNetworks, :migration do
|
||||
let!(:fork_networks) { table(:fork_networks) }
|
||||
let!(:projects) { table(:projects) }
|
||||
let!(:fork_network_members) { table(:fork_network_members) }
|
||||
|
||||
let(:deleted_project) { projects.create! }
|
||||
let!(:empty_network) { fork_networks.create!(id: 1, root_project_id: deleted_project.id) }
|
||||
let!(:other_network) { fork_networks.create!(id: 2, root_project_id: projects.create.id) }
|
||||
|
||||
before do
|
||||
fork_network_members.create(fork_network_id: empty_network.id,
|
||||
project_id: empty_network.root_project_id)
|
||||
fork_network_members.create(fork_network_id: other_network.id,
|
||||
project_id: other_network.root_project_id)
|
||||
|
||||
deleted_project.destroy!
|
||||
end
|
||||
|
||||
after do
|
||||
Upload.reset_column_information
|
||||
end
|
||||
|
||||
it 'deletes only the fork network without members' do
|
||||
expect(fork_networks.count).to eq(2)
|
||||
|
||||
migrate!
|
||||
|
||||
expect(fork_networks.find_by(id: empty_network.id)).to be_nil
|
||||
expect(fork_networks.find_by(id: other_network.id)).not_to be_nil
|
||||
expect(fork_networks.count).to eq(1)
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20170622135451_rename_duplicated_variable_key.rb')
|
||||
|
||||
describe RenameDuplicatedVariableKey, :migration do
|
||||
let(:variables) { table(:ci_variables) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
||||
before do
|
||||
projects.create!(id: 1)
|
||||
variables.create!(id: 1, key: 'key1', project_id: 1)
|
||||
variables.create!(id: 2, key: 'key2', project_id: 1)
|
||||
variables.create!(id: 3, key: 'keyX', project_id: 1)
|
||||
variables.create!(id: 4, key: 'keyX', project_id: 1)
|
||||
variables.create!(id: 5, key: 'keyY', project_id: 1)
|
||||
variables.create!(id: 6, key: 'keyX', project_id: 1)
|
||||
variables.create!(id: 7, key: 'key7', project_id: 1)
|
||||
variables.create!(id: 8, key: 'keyY', project_id: 1)
|
||||
end
|
||||
|
||||
it 'correctly remove duplicated records with smaller id' do
|
||||
migrate!
|
||||
|
||||
expect(variables.pluck(:id, :key)).to contain_exactly(
|
||||
[1, 'key1'],
|
||||
[2, 'key2'],
|
||||
[3, 'keyX_3'],
|
||||
[4, 'keyX_4'],
|
||||
[5, 'keyY_5'],
|
||||
[6, 'keyX'],
|
||||
[7, 'key7'],
|
||||
[8, 'keyY']
|
||||
)
|
||||
end
|
||||
end
|
|
@ -1,57 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170313133418_rename_more_reserved_project_names.rb')
|
||||
|
||||
# This migration uses multiple threads, and thus different transactions. This
|
||||
# means data created in this spec may not be visible to some threads. To work
|
||||
# around this we use the DELETE cleaning strategy.
|
||||
describe RenameMoreReservedProjectNames, :delete do
|
||||
let(:migration) { described_class.new }
|
||||
let!(:project) { create(:project) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
|
||||
before do
|
||||
project.path = 'artifacts'
|
||||
project.save!(validate: false)
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
context 'when project repository exists' do
|
||||
before do
|
||||
project.create_repository
|
||||
end
|
||||
|
||||
context 'when no exception is raised' do
|
||||
it 'renames project with reserved names' do
|
||||
migration.up
|
||||
|
||||
expect(project.reload.path).to eq('artifacts0')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when exception is raised during rename' do
|
||||
before do
|
||||
service = instance_double('service')
|
||||
|
||||
allow(service)
|
||||
.to receive(:execute)
|
||||
.and_raise(Projects::AfterRenameService::RenameFailedError)
|
||||
|
||||
expect(migration)
|
||||
.to receive(:after_rename_service)
|
||||
.and_return(service)
|
||||
end
|
||||
|
||||
it 'captures exception from project rename' do
|
||||
expect { migration.up }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project repository does not exist' do
|
||||
it 'does not raise error' do
|
||||
expect { migration.up }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,61 +0,0 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20161221153951_rename_reserved_project_names.rb')
|
||||
|
||||
# This migration is using factories, which set fields that don't actually
|
||||
# exist in the DB schema previous to 20161221153951. Thus we just use the
|
||||
# latest schema when testing this migration.
|
||||
# This is ok-ish because:
|
||||
# 1. This migration is a data migration
|
||||
# 2. It only relies on very stable DB fields: routes.id, routes.path, namespaces.id, projects.namespace_id
|
||||
# Ideally, the test should not use factories and rely on the `table` helper instead.
|
||||
describe RenameReservedProjectNames, :migration, schema: :latest do
|
||||
let(:migration) { described_class.new }
|
||||
let!(:project) { create(:project) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
|
||||
before do
|
||||
project.path = 'projects'
|
||||
project.save!(validate: false)
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
context 'when project repository exists' do
|
||||
before do
|
||||
project.create_repository
|
||||
end
|
||||
|
||||
context 'when no exception is raised' do
|
||||
it 'renames project with reserved names' do
|
||||
migration.up
|
||||
|
||||
expect(project.reload.path).to eq('projects0')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when exception is raised during rename' do
|
||||
before do
|
||||
service = instance_double('service')
|
||||
|
||||
allow(service)
|
||||
.to receive(:execute)
|
||||
.and_raise(Projects::AfterRenameService::RenameFailedError)
|
||||
|
||||
expect(migration)
|
||||
.to receive(:after_rename_service)
|
||||
.and_return(service)
|
||||
end
|
||||
|
||||
it 'captures exception from project rename' do
|
||||
expect { migration.up }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project repository does not exist' do
|
||||
it 'does not raise error' do
|
||||
expect { migration.up }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170518200835_rename_users_with_renamed_namespace.rb')
|
||||
|
||||
describe RenameUsersWithRenamedNamespace, :delete do
|
||||
it 'renames a user that had their namespace renamed to the namespace path' do
|
||||
other_user = create(:user, username: 'kodingu') # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
other_user1 = create(:user, username: 'api0') # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
|
||||
user = create(:user, username: "Users0") # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
user.update_column(:username, 'Users')
|
||||
user1 = create(:user, username: "import0") # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
user1.update_column(:username, 'import')
|
||||
|
||||
described_class.new.up
|
||||
|
||||
expect(user.reload.username).to eq('Users0')
|
||||
expect(user1.reload.username).to eq('import0')
|
||||
|
||||
expect(other_user.reload.username).to eq('kodingu')
|
||||
expect(other_user1.reload.username).to eq('api0')
|
||||
end
|
||||
end
|
|
@ -1,64 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20171026082505_schedule_merge_request_latest_merge_request_diff_id_migrations')
|
||||
|
||||
describe ScheduleMergeRequestLatestMergeRequestDiffIdMigrations, :migration, :sidekiq do
|
||||
let(:projects_table) { table(:projects) }
|
||||
let(:merge_requests_table) { table(:merge_requests) }
|
||||
let(:merge_request_diffs_table) { table(:merge_request_diffs) }
|
||||
|
||||
let(:project) { projects_table.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce') }
|
||||
|
||||
let!(:merge_request_1) { create_mr!('mr_1', diffs: 1) }
|
||||
let!(:merge_request_2) { create_mr!('mr_2', diffs: 2) }
|
||||
let!(:merge_request_migrated) { create_mr!('merge_request_migrated', diffs: 3) }
|
||||
let!(:merge_request_4) { create_mr!('mr_4', diffs: 3) }
|
||||
|
||||
def create_mr!(name, diffs: 0)
|
||||
merge_request =
|
||||
merge_requests_table.create!(target_project_id: project.id,
|
||||
target_branch: 'master',
|
||||
source_project_id: project.id,
|
||||
source_branch: name,
|
||||
title: name)
|
||||
|
||||
diffs.times do
|
||||
merge_request_diffs_table.create!(merge_request_id: merge_request.id)
|
||||
end
|
||||
|
||||
merge_request
|
||||
end
|
||||
|
||||
def diffs_for(merge_request)
|
||||
merge_request_diffs_table.where(merge_request_id: merge_request.id)
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const("#{described_class.name}::BATCH_SIZE", 1)
|
||||
|
||||
diff_id = diffs_for(merge_request_migrated).minimum(:id)
|
||||
merge_request_migrated.update!(latest_merge_request_diff_id: diff_id)
|
||||
end
|
||||
|
||||
it 'correctly schedules background migrations' do
|
||||
Sidekiq::Testing.fake! do
|
||||
Timecop.freeze do
|
||||
migrate!
|
||||
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, merge_request_1.id, merge_request_1.id)
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(10.minutes, merge_request_2.id, merge_request_2.id)
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(15.minutes, merge_request_4.id, merge_request_4.id)
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'schedules background migrations' do
|
||||
perform_enqueued_jobs do
|
||||
expect(merge_requests_table.where(latest_merge_request_diff_id: nil).count).to eq 3
|
||||
|
||||
migrate!
|
||||
|
||||
expect(merge_requests_table.where(latest_merge_request_diff_id: nil).count).to eq 0
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20171103140253_track_untracked_uploads')
|
||||
|
||||
describe TrackUntrackedUploads, :migration, :sidekiq do
|
||||
include MigrationsHelpers::TrackUntrackedUploadsHelpers
|
||||
|
||||
it 'correctly schedules the follow-up background migration' do
|
||||
Sidekiq::Testing.fake! do
|
||||
migrate!
|
||||
|
||||
expect(described_class::MIGRATION).to be_scheduled_migration
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,70 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20170503140202_turn_nested_groups_into_regular_groups_for_mysql.rb')
|
||||
|
||||
describe TurnNestedGroupsIntoRegularGroupsForMysql do
|
||||
let!(:parent_group) { create(:group) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let!(:child_group) { create(:group, parent: parent_group) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let!(:project) { create(:project, :legacy_storage, :empty_repo, namespace: child_group) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let!(:member) { create(:user) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let(:migration) { described_class.new }
|
||||
|
||||
before do
|
||||
parent_group.add_developer(member)
|
||||
|
||||
allow(migration).to receive(:run_migration?).and_return(true)
|
||||
allow(migration).to receive(:verbose).and_return(false)
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
let(:updated_project) do
|
||||
# path_with_namespace is memoized in an instance variable so we retrieve a
|
||||
# new row here to work around that.
|
||||
Project.find(project.id)
|
||||
end
|
||||
|
||||
before do
|
||||
migration.up
|
||||
end
|
||||
|
||||
it 'unsets the parent_id column' do
|
||||
expect(Namespace.where('parent_id IS NOT NULL').any?).to eq(false)
|
||||
end
|
||||
|
||||
it 'adds members of parent groups as members to the migrated group' do
|
||||
is_member = child_group.members
|
||||
.where(user_id: member, access_level: Gitlab::Access::DEVELOPER).any?
|
||||
|
||||
expect(is_member).to eq(true)
|
||||
end
|
||||
|
||||
it 'update the path of the nested group' do
|
||||
child_group.reload
|
||||
|
||||
expect(child_group.path).to eq("#{parent_group.name}-#{child_group.name}")
|
||||
end
|
||||
|
||||
it 'renames projects of the nested group' do
|
||||
expect(updated_project.full_path)
|
||||
.to eq("#{parent_group.name}-#{child_group.name}/#{updated_project.path}")
|
||||
end
|
||||
|
||||
it 'renames the repository of any projects' do
|
||||
repo_path = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
|
||||
updated_project.repository.path
|
||||
end
|
||||
|
||||
expect(repo_path)
|
||||
.to end_with("#{parent_group.name}-#{child_group.name}/#{updated_project.path}.git")
|
||||
|
||||
expect(File.directory?(repo_path)).to eq(true)
|
||||
end
|
||||
|
||||
it 'creates a redirect route for renamed projects' do
|
||||
exists = RedirectRoute
|
||||
.where(source_type: 'Project', source_id: project.id)
|
||||
.any?
|
||||
|
||||
expect(exists).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170927112318_update_legacy_diff_notes_type_for_import.rb')
|
||||
|
||||
describe UpdateLegacyDiffNotesTypeForImport, :migration do
|
||||
let(:notes) { table(:notes) }
|
||||
|
||||
before do
|
||||
notes.inheritance_column = nil
|
||||
|
||||
notes.create(type: 'Note')
|
||||
notes.create(type: 'LegacyDiffNote')
|
||||
notes.create(type: 'Github::Import::Note')
|
||||
notes.create(type: 'Github::Import::LegacyDiffNote')
|
||||
end
|
||||
|
||||
it 'updates the notes type' do
|
||||
migrate!
|
||||
|
||||
expect(notes.pluck(:type))
|
||||
.to contain_exactly('Note', 'Github::Import::Note', 'LegacyDiffNote', 'LegacyDiffNote')
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170927112319_update_notes_type_for_import.rb')
|
||||
|
||||
describe UpdateNotesTypeForImport, :migration do
|
||||
let(:notes) { table(:notes) }
|
||||
|
||||
before do
|
||||
notes.inheritance_column = nil
|
||||
|
||||
notes.create(type: 'Note')
|
||||
notes.create(type: 'LegacyDiffNote')
|
||||
notes.create(type: 'Github::Import::Note')
|
||||
notes.create(type: 'Github::Import::LegacyDiffNote')
|
||||
end
|
||||
|
||||
it 'updates the notes type' do
|
||||
migrate!
|
||||
|
||||
expect(notes.pluck(:type))
|
||||
.to contain_exactly('Note', 'Note', 'LegacyDiffNote', 'Github::Import::LegacyDiffNote')
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170503004427_update_retried_for_ci_build.rb')
|
||||
|
||||
describe UpdateRetriedForCiBuild, :delete do
|
||||
let(:pipeline) { create(:ci_pipeline) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let!(:build_old) { create(:ci_build, pipeline: pipeline, name: 'test') } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
let!(:build_new) { create(:ci_build, pipeline: pipeline, name: 'test') } # rubocop:disable RSpec/FactoriesInMigrationSpecs
|
||||
|
||||
before do
|
||||
described_class.new.up
|
||||
end
|
||||
|
||||
it 'updates ci_builds.is_retried' do
|
||||
expect(build_old.reload).to be_retried
|
||||
expect(build_new.reload).not_to be_retried
|
||||
end
|
||||
end
|
|
@ -1,59 +0,0 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20170317162059_update_upload_paths_to_system.rb')
|
||||
|
||||
describe UpdateUploadPathsToSystem, :migration do
|
||||
let(:migration) { described_class.new }
|
||||
let(:uploads_table) { table(:uploads) }
|
||||
let(:base_upload_attributes) { { size: 42, uploader: 'John Doe' } }
|
||||
|
||||
before do
|
||||
allow(migration).to receive(:say)
|
||||
end
|
||||
|
||||
describe '#uploads_to_switch_to_new_path' do
|
||||
it 'contains only uploads with the old path for the correct models' do
|
||||
_upload_for_other_type = create_upload('Pipeline', 'uploads/ci_pipeline/avatar.jpg')
|
||||
_upload_with_system_path = create_upload('Project', 'uploads/-/system/project/avatar.jpg')
|
||||
_upload_with_other_path = create_upload('Project', 'thelongsecretforafileupload/avatar.jpg')
|
||||
old_upload = create_upload('Project', 'uploads/project/avatar.jpg')
|
||||
group_upload = create_upload('Namespace', 'uploads/group/avatar.jpg')
|
||||
|
||||
expect(uploads_table.where(migration.uploads_to_switch_to_new_path)).to contain_exactly(old_upload, group_upload)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#uploads_to_switch_to_old_path' do
|
||||
it 'contains only uploads with the new path for the correct models' do
|
||||
_upload_for_other_type = create_upload('Pipeline', 'uploads/ci_pipeline/avatar.jpg')
|
||||
upload_with_system_path = create_upload('Project', 'uploads/-/system/project/avatar.jpg')
|
||||
_upload_with_other_path = create_upload('Project', 'thelongsecretforafileupload/avatar.jpg')
|
||||
_old_upload = create_upload('Project', 'uploads/project/avatar.jpg')
|
||||
|
||||
expect(uploads_table.where(migration.uploads_to_switch_to_old_path)).to contain_exactly(upload_with_system_path)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#up' do
|
||||
it 'updates old upload records to the new path' do
|
||||
old_upload = create_upload('Project', 'uploads/project/avatar.jpg')
|
||||
|
||||
migration.up
|
||||
|
||||
expect(old_upload.reload.path).to eq('uploads/-/system/project/avatar.jpg')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'updates the new system patsh to the old paths' do
|
||||
new_upload = create_upload('Project', 'uploads/-/system/project/avatar.jpg')
|
||||
|
||||
migration.down
|
||||
|
||||
expect(new_upload.reload.path).to eq('uploads/project/avatar.jpg')
|
||||
end
|
||||
end
|
||||
|
||||
def create_upload(type, path)
|
||||
uploads_table.create(base_upload_attributes.merge(model_type: type, path: path))
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue