200 lines
8.5 KiB
Ruby
200 lines
8.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rake_helper'
|
|
|
|
RSpec.describe 'gitlab:background_migrations namespace rake tasks', :suppress_gitlab_schemas_validate_connection,
|
|
feature_category: :database do
|
|
before do
|
|
Rake.application.rake_require 'tasks/gitlab/background_migrations'
|
|
end
|
|
|
|
describe 'finalize' do
|
|
subject(:finalize_task) { run_rake_task('gitlab:background_migrations:finalize', *arguments) }
|
|
|
|
let(:connection) { double(:connection) }
|
|
let(:main_model) { double(:model, connection: connection) }
|
|
let(:base_models) { { main: main_model } }
|
|
let(:databases) { [Gitlab::Database::MAIN_DATABASE_NAME] }
|
|
|
|
before do
|
|
allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
|
|
allow(Gitlab::Database).to receive(:db_config_names).and_return(databases)
|
|
end
|
|
|
|
context 'without the proper arguments' do
|
|
let(:arguments) { %w[CopyColumnUsingBackgroundMigrationJob events id] }
|
|
|
|
it 'exits without finalizing the migration' do
|
|
expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).not_to receive(:finalize)
|
|
|
|
expect { finalize_task }.to output(/Must specify job_arguments as an argument/).to_stdout
|
|
.and raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
|
|
end
|
|
end
|
|
|
|
context 'with the proper arguments' do
|
|
let(:arguments) { %w[CopyColumnUsingBackgroundMigrationJob events id [["id1"\,"id2"]]] }
|
|
|
|
it 'finalizes the matching migration' do
|
|
expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).to receive(:finalize)
|
|
.with('CopyColumnUsingBackgroundMigrationJob', 'events', 'id', [%w[id1 id2]], connection: connection)
|
|
|
|
expect { finalize_task }.to output(/Done/).to_stdout
|
|
end
|
|
end
|
|
|
|
context 'with a null parameter' do
|
|
let(:arguments) { %w[ProjectNamespaces::BackfillProjectNamespaces projects id] + ['[null\, "up"]'] }
|
|
|
|
it 'finalizes the matching migration' do
|
|
expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).to receive(:finalize)
|
|
.with('ProjectNamespaces::BackfillProjectNamespaces', 'projects', 'id', [nil, "up"], connection: connection)
|
|
|
|
expect { finalize_task }.to output(/Done/).to_stdout
|
|
end
|
|
end
|
|
|
|
context 'when multiple database feature is enabled' do
|
|
subject(:finalize_task) { run_rake_task("gitlab:background_migrations:finalize:#{ci_database_name}", *arguments) }
|
|
|
|
let(:ci_database_name) { Gitlab::Database::CI_DATABASE_NAME }
|
|
let(:ci_model) { double(:model, connection: connection) }
|
|
let(:base_models) { { 'main' => main_model, 'ci' => ci_model } }
|
|
let(:databases) { [Gitlab::Database::MAIN_DATABASE_NAME, ci_database_name] }
|
|
|
|
before do
|
|
skip_if_shared_database(:ci)
|
|
|
|
allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
|
|
end
|
|
|
|
it 'ignores geo' do
|
|
expect { run_rake_task('gitlab:background_migrations:finalize:geo}') }
|
|
.to raise_error(RuntimeError).with_message(/Don't know how to build task/)
|
|
end
|
|
|
|
context 'without the proper arguments' do
|
|
let(:arguments) { %w[CopyColumnUsingBackgroundMigrationJob events id] }
|
|
|
|
it 'exits without finalizing the migration' do
|
|
expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).not_to receive(:finalize)
|
|
|
|
expect { finalize_task }.to output(/Must specify job_arguments as an argument/).to_stdout
|
|
.and raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
|
|
end
|
|
end
|
|
|
|
context 'with the proper arguments' do
|
|
let(:arguments) { %w[CopyColumnUsingBackgroundMigrationJob events id [["id1"\,"id2"]]] }
|
|
|
|
it 'finalizes the matching migration' do
|
|
expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).to receive(:finalize)
|
|
.with('CopyColumnUsingBackgroundMigrationJob', 'events', 'id', [%w[id1 id2]], connection: connection)
|
|
|
|
expect { finalize_task }.to output(/Done/).to_stdout
|
|
end
|
|
end
|
|
|
|
context 'when database name is not passed' do
|
|
it 'aborts the rake task' do
|
|
expect { run_rake_task('gitlab:background_migrations:finalize') }.to output(/Please specify the database/).to_stdout
|
|
.and raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'status' do
|
|
subject(:status_task) { run_rake_task('gitlab:background_migrations:status') }
|
|
|
|
let(:migration1) { create(:batched_background_migration, :finished, job_arguments: [%w[id1 id2]]) }
|
|
let(:migration2) { create(:batched_background_migration, :failed, job_arguments: []) }
|
|
|
|
let(:main_database_name) { Gitlab::Database::MAIN_DATABASE_NAME }
|
|
let(:model) { Gitlab::Database.database_base_models[main_database_name] }
|
|
let(:connection) { double(:connection) }
|
|
let(:base_models) { { 'main' => model }.with_indifferent_access }
|
|
|
|
it 'outputs the status of background migrations' do
|
|
allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
|
|
|
|
expect { status_task }.to output(<<~OUTPUT).to_stdout
|
|
Database: #{main_database_name}
|
|
finished | #{migration1.job_class_name},#{migration1.table_name},#{migration1.column_name},[["id1","id2"]]
|
|
failed | #{migration2.job_class_name},#{migration2.table_name},#{migration2.column_name},[]
|
|
OUTPUT
|
|
end
|
|
|
|
context 'when running the rake task against one database in multiple databases setup' do
|
|
before do
|
|
skip_if_shared_database(:ci)
|
|
end
|
|
|
|
subject(:status_task) { run_rake_task("gitlab:background_migrations:status:#{main_database_name}") }
|
|
|
|
it 'outputs the status of background migrations' do
|
|
expect { status_task }.to output(<<~OUTPUT).to_stdout
|
|
Database: #{main_database_name}
|
|
finished | #{migration1.job_class_name},#{migration1.table_name},#{migration1.column_name},[["id1","id2"]]
|
|
failed | #{migration2.job_class_name},#{migration2.table_name},#{migration2.column_name},[]
|
|
OUTPUT
|
|
end
|
|
end
|
|
|
|
context 'when multiple databases are configured' do
|
|
before do
|
|
skip_if_multiple_databases_not_setup(:ci)
|
|
end
|
|
|
|
context 'with two connections sharing the same database' do
|
|
before do
|
|
skip_if_database_exists(:ci)
|
|
end
|
|
|
|
it 'skips the shared database' do
|
|
expect { status_task }.to output(<<~OUTPUT).to_stdout
|
|
Database: #{main_database_name}
|
|
finished | #{migration1.job_class_name},#{migration1.table_name},#{migration1.column_name},[["id1","id2"]]
|
|
failed | #{migration2.job_class_name},#{migration2.table_name},#{migration2.column_name},[]
|
|
OUTPUT
|
|
end
|
|
|
|
it 'ignores geo' do
|
|
expect { run_rake_task('gitlab:background_migrations:status:geo') }
|
|
.to raise_error(RuntimeError).with_message(/Don't know how to build task/)
|
|
end
|
|
end
|
|
|
|
context 'with multiple databases' do
|
|
before do
|
|
skip_if_shared_database(:ci)
|
|
end
|
|
|
|
subject(:status_task) { run_rake_task('gitlab:background_migrations:status') }
|
|
|
|
let(:base_models) { { main: main_model, ci: ci_model } }
|
|
let(:main_model) { double(:model, connection: connection) }
|
|
let(:ci_model) { double(:model, connection: connection) }
|
|
|
|
it 'outputs the status for each database' do
|
|
allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
|
|
allow(Gitlab::Database).to receive(:has_database?).with(:main).and_return(true)
|
|
allow(Gitlab::Database).to receive(:has_database?).with(:ci).and_return(true)
|
|
|
|
expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(main_model.connection).and_yield
|
|
expect(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:find_each).and_yield(migration1)
|
|
|
|
expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(ci_model.connection).and_yield
|
|
expect(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:find_each).and_yield(migration2)
|
|
|
|
expect { status_task }.to output(<<~OUTPUT).to_stdout
|
|
Database: main
|
|
finished | #{migration1.job_class_name},#{migration1.table_name},#{migration1.column_name},[["id1","id2"]]
|
|
Database: ci
|
|
failed | #{migration2.job_class_name},#{migration2.table_name},#{migration2.column_name},[]
|
|
OUTPUT
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|