diff options
Diffstat (limited to 'spec/lib/gitlab/database')
14 files changed, 337 insertions, 71 deletions
diff --git a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb index c39f6a78e93..a7b3670da7c 100644 --- a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb +++ b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb @@ -220,6 +220,12 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d expect(described_class.created_since(fixed_time)).to contain_exactly(stuck_job, failed_job, max_attempts_failed_job) end end + + describe '.blocked_by_max_attempts' do + it 'returns blocked jobs' do + expect(described_class.blocked_by_max_attempts).to contain_exactly(max_attempts_failed_job) + end + end end describe 'delegated batched_migration attributes' do diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb index 97459d4a7be..b8ff78be333 100644 --- a/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb +++ b/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb @@ -14,6 +14,11 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do end end + before do + allow(Gitlab::Database::BackgroundMigration::HealthStatus).to receive(:evaluate) + .and_return(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Normal) + end + describe '#run_migration_job' do shared_examples_for 'it has completed the migration' do it 'does not create and run a migration job' do @@ -59,13 +64,48 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do sub_batch_size: migration.sub_batch_size) end - it 'optimizes the migration after executing the job' do - migration.update!(min_value: event1.id, max_value: event2.id) + context 'migration health' do + let(:health_status) { Gitlab::Database::BackgroundMigration::HealthStatus } + let(:stop_signal) { health_status::Signals::Stop.new(:indicator, reason: 'Take a break') } + let(:normal_signal) { health_status::Signals::Normal.new(:indicator, reason: 'All good') } + let(:not_available_signal) { health_status::Signals::NotAvailable.new(:indicator, reason: 'Indicator is disabled') } + let(:unknown_signal) { health_status::Signals::Unknown.new(:indicator, reason: 'Something went wrong') } - expect(migration_wrapper).to receive(:perform).ordered - expect(migration).to receive(:optimize!).ordered + before do + migration.update!(min_value: event1.id, max_value: event2.id) + expect(migration_wrapper).to receive(:perform) + end - runner.run_migration_job(migration) + it 'puts migration on hold on stop signal' do + expect(health_status).to receive(:evaluate).and_return(stop_signal) + + expect { runner.run_migration_job(migration) }.to change { migration.on_hold? } + .from(false).to(true) + end + + it 'optimizes migration on normal signal' do + expect(health_status).to receive(:evaluate).and_return(normal_signal) + + expect(migration).to receive(:optimize!) + + expect { runner.run_migration_job(migration) }.not_to change { migration.on_hold? } + end + + it 'optimizes migration on no signal' do + expect(health_status).to receive(:evaluate).and_return(not_available_signal) + + expect(migration).to receive(:optimize!) + + expect { runner.run_migration_job(migration) }.not_to change { migration.on_hold? } + end + + it 'optimizes migration on unknown signal' do + expect(health_status).to receive(:evaluate).and_return(unknown_signal) + + expect(migration).to receive(:optimize!) + + expect { runner.run_migration_job(migration) }.not_to change { migration.on_hold? } + end end end @@ -362,6 +402,8 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do .with(gitlab_schemas, 'CopyColumnUsingBackgroundMigrationJob', table_name, column_name, job_arguments) .and_return(batched_migration) + expect(batched_migration).to receive(:reset_attempts_of_blocked_jobs!).and_call_original + expect(batched_migration).to receive(:finalize!).and_call_original expect do @@ -380,8 +422,15 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do end context 'when migration fails to complete' do + let(:error_message) do + "Batched migration #{batched_migration.job_class_name} could not be completed and a manual action is required."\ + "Check the admin panel at (`/admin/background_migrations`) for more details." + end + it 'raises an error' do - batched_migration.batched_jobs.with_status(:failed).update_all(attempts: Gitlab::Database::BackgroundMigration::BatchedJob::MAX_ATTEMPTS) + allow(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:find_for_configuration).and_return(batched_migration) + + allow(batched_migration).to receive(:finished?).and_return(false) expect do runner.finalize( @@ -390,7 +439,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do column_name, job_arguments ) - end.to raise_error described_class::FailedToFinalize + end.to raise_error(described_class::FailedToFinalize, error_message) end end end diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb index 8819171cfd0..55f607c0cb0 100644 --- a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb +++ b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb @@ -157,6 +157,27 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m end end + describe '#reset_attempts_of_blocked_jobs!' do + let!(:migration) { create(:batched_background_migration) } + let(:max_attempts) { Gitlab::Database::BackgroundMigration::BatchedJob::MAX_ATTEMPTS } + + before do + create(:batched_background_migration_job, attempts: max_attempts - 1, batched_migration: migration) + create(:batched_background_migration_job, attempts: max_attempts + 1, batched_migration: migration) + create(:batched_background_migration_job, attempts: max_attempts + 1, batched_migration: migration) + end + + it 'sets the number of attempts to zero for blocked jobs' do + migration.reset_attempts_of_blocked_jobs! + + expect(migration.batched_jobs.size).to eq(3) + + migration.batched_jobs.blocked_by_max_attempts.each do |job| + expect(job.attempts).to be_zero + end + end + end + describe '#interval_elapsed?' do context 'when the migration has no last_job' do let(:batched_migration) { build(:batched_background_migration) } @@ -322,6 +343,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m describe '#retry_failed_jobs!' do let(:batched_migration) { create(:batched_background_migration, status: 'failed') } + let(:job_class) { Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJob } subject(:retry_failed_jobs) { batched_migration.retry_failed_jobs! } @@ -335,7 +357,8 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m anything, batch_min_value: 6, batch_size: 5, - job_arguments: batched_migration.job_arguments + job_arguments: batched_migration.job_arguments, + job_class: job_class ).and_return([6, 10]) end end @@ -570,6 +593,30 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m end end + describe '#on_hold?', :freeze_time do + subject { migration.on_hold? } + + let(:migration) { create(:batched_background_migration) } + + it 'returns false if no on_hold_until is set' do + migration.on_hold_until = nil + + expect(subject).to be_falsey + end + + it 'returns false if on_hold_until has passed' do + migration.on_hold_until = 1.minute.ago + + expect(subject).to be_falsey + end + + it 'returns true if on_hold_until is in the future' do + migration.on_hold_until = 1.minute.from_now + + expect(subject).to be_truthy + end + end + describe '.for_configuration' do let!(:attributes) do { diff --git a/spec/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table_spec.rb b/spec/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table_spec.rb new file mode 100644 index 00000000000..21204814f17 --- /dev/null +++ b/spec/lib/gitlab/database/background_migration/health_status/indicators/autovacuum_active_on_table_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus::Indicators::AutovacuumActiveOnTable do + include Database::DatabaseHelpers + + let(:connection) { Gitlab::Database.database_base_models[:main].connection } + + around do |example| + Gitlab::Database::SharedModel.using_connection(connection) do + example.run + end + end + + describe '#evaluate' do + subject { described_class.new(context).evaluate } + + before do + swapout_view_for_table(:postgres_autovacuum_activity) + end + + let(:context) { Gitlab::Database::BackgroundMigration::HealthStatus::Context.new(tables) } + let(:tables) { [table] } + let(:table) { 'users' } + + context 'without autovacuum activity' do + it 'returns Normal signal' do + expect(subject).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Normal) + end + + it 'remembers the indicator class' do + expect(subject.indicator_class).to eq(described_class) + end + end + + context 'with autovacuum activity' do + before do + create(:postgres_autovacuum_activity, table: table, table_identifier: "public.#{table}") + end + + it 'returns Stop signal' do + expect(subject).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Stop) + end + + it 'explains why' do + expect(subject.reason).to include('autovacuum running on: table public.users') + end + + it 'remembers the indicator class' do + expect(subject.indicator_class).to eq(described_class) + end + + it 'returns NoSignal signal in case the feature flag is disabled' do + stub_feature_flags(batched_migrations_health_status_autovacuum: false) + + expect(subject).to be_a(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::NotAvailable) + end + end + end +end diff --git a/spec/lib/gitlab/database/background_migration/health_status_spec.rb b/spec/lib/gitlab/database/background_migration/health_status_spec.rb new file mode 100644 index 00000000000..6d0430dcbbb --- /dev/null +++ b/spec/lib/gitlab/database/background_migration/health_status_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::BackgroundMigration::HealthStatus do + let(:connection) { Gitlab::Database.database_base_models[:main].connection } + + around do |example| + Gitlab::Database::SharedModel.using_connection(connection) do + example.run + end + end + + describe '.evaluate' do + subject(:evaluate) { described_class.evaluate(migration, indicator_class) } + + let(:migration) { build(:batched_background_migration, :active) } + + let(:health_status) { 'Gitlab::Database::BackgroundMigration::HealthStatus' } + let(:indicator_class) { class_double("#{health_status}::Indicators::AutovacuumActiveOnTable") } + let(:indicator) { instance_double("#{health_status}::Indicators::AutovacuumActiveOnTable") } + + before do + allow(indicator_class).to receive(:new).with(migration.health_context).and_return(indicator) + end + + it 'returns a signal' do + signal = instance_double("#{health_status}::Signals::Normal", log_info?: false) + + expect(indicator).to receive(:evaluate).and_return(signal) + + expect(evaluate).to eq(signal) + end + + it 'logs interesting signals' do + signal = instance_double("#{health_status}::Signals::Stop", log_info?: true) + + expect(indicator).to receive(:evaluate).and_return(signal) + expect(described_class).to receive(:log_signal).with(signal, migration) + + evaluate + end + + it 'does not log signals of no interest' do + signal = instance_double("#{health_status}::Signals::Normal", log_info?: false) + + expect(indicator).to receive(:evaluate).and_return(signal) + expect(described_class).not_to receive(:log_signal) + + evaluate + end + + context 'on indicator error' do + let(:error) { RuntimeError.new('everything broken') } + + before do + expect(indicator).to receive(:evaluate).and_raise(error) + end + + it 'does not fail' do + expect { evaluate }.not_to raise_error + end + + it 'returns Unknown signal' do + expect(evaluate).to be_an_instance_of(Gitlab::Database::BackgroundMigration::HealthStatus::Signals::Unknown) + expect(evaluate.reason).to eq("unexpected error: everything broken (RuntimeError)") + end + + it 'reports the exception to error tracking' do + expect(Gitlab::ErrorTracking).to receive(:track_exception) + .with(error, migration_id: migration.id, job_class_name: migration.job_class_name) + + evaluate + end + end + end +end diff --git a/spec/lib/gitlab/database/each_database_spec.rb b/spec/lib/gitlab/database/each_database_spec.rb index 8345cdfb8fb..2a6eb8f779d 100644 --- a/spec/lib/gitlab/database/each_database_spec.rb +++ b/spec/lib/gitlab/database/each_database_spec.rb @@ -4,9 +4,10 @@ require 'spec_helper' RSpec.describe Gitlab::Database::EachDatabase do describe '.each_database_connection', :add_ci_connection do + let(:database_base_models) { { main: ActiveRecord::Base, ci: Ci::ApplicationRecord }.with_indifferent_access } + before do - allow(Gitlab::Database).to receive(:database_base_models) - .and_return({ main: ActiveRecord::Base, ci: Ci::ApplicationRecord }.with_indifferent_access) + allow(Gitlab::Database).to receive(:database_base_models_with_gitlab_shared).and_return(database_base_models) end it 'yields each connection after connecting SharedModel' do @@ -60,12 +61,20 @@ RSpec.describe Gitlab::Database::EachDatabase do end context 'when shared connections are not included' do + def clear_memoization(key) + Gitlab::Database.remove_instance_variable(key) if Gitlab::Database.instance_variable_defined?(key) + end + + before do + allow(Gitlab::Database).to receive(:database_base_models).and_return(database_base_models) + + # Clear the memoization because the return of Gitlab::Database#schemas_to_base_models depends stubbed value + clear_memoization(:@schemas_to_base_models) + clear_memoization(:@schemas_to_base_models_ee) + end + it 'only yields the unshared connections' do - if Gitlab::Database.has_config?(:ci) - expect(Gitlab::Database).to receive(:db_config_share_with).exactly(3).times.and_return(nil, 'main', 'main') - else - expect(Gitlab::Database).to receive(:db_config_share_with).twice.and_return(nil, 'main') - end + expect(Gitlab::Database).to receive(:db_config_share_with).exactly(3).times.and_return(nil, 'main', 'main') expect { |b| described_class.each_database_connection(include_shared: false, &b) } .to yield_successive_args([ActiveRecord::Base.connection, 'main']) @@ -79,7 +88,7 @@ RSpec.describe Gitlab::Database::EachDatabase do let(:model2) { Class.new(Gitlab::Database::SharedModel) } before do - allow(Gitlab::Database).to receive(:database_base_models) + allow(Gitlab::Database).to receive(:database_base_models_with_gitlab_shared) .and_return({ main: ActiveRecord::Base, ci: Ci::ApplicationRecord }.with_indifferent_access) end @@ -136,7 +145,7 @@ RSpec.describe Gitlab::Database::EachDatabase do let(:ci_model) { Class.new(Ci::ApplicationRecord) } before do - allow(Gitlab::Database).to receive(:database_base_models) + allow(Gitlab::Database).to receive(:database_base_models_with_gitlab_shared) .and_return({ main: ActiveRecord::Base, ci: Ci::ApplicationRecord }.with_indifferent_access) allow(main_model).to receive_message_chain('connection_db_config.name').and_return('main') diff --git a/spec/lib/gitlab/database/gitlab_schema_spec.rb b/spec/lib/gitlab/database/gitlab_schema_spec.rb index 611b2fbad72..72950895022 100644 --- a/spec/lib/gitlab/database/gitlab_schema_spec.rb +++ b/spec/lib/gitlab/database/gitlab_schema_spec.rb @@ -3,26 +3,27 @@ require 'spec_helper' RSpec.describe Gitlab::Database::GitlabSchema do describe '.tables_to_schema' do - subject { described_class.tables_to_schema } - it 'all tables have assigned a known gitlab_schema' do - is_expected.to all( - match([be_a(String), be_in([:gitlab_internal, :gitlab_shared, :gitlab_main, :gitlab_ci])]) + expect(described_class.tables_to_schema).to all( + match([be_a(String), be_in(Gitlab::Database.schemas_to_base_models.keys.map(&:to_sym))]) ) end # This being run across different databases indirectly also tests # a general consistency of structure across databases - Gitlab::Database.database_base_models.each do |db_config_name, db_class| - let(:db_data_sources) { db_class.connection.data_sources } - + Gitlab::Database.database_base_models.select { |k, _| k != 'geo' }.each do |db_config_name, db_class| context "for #{db_config_name} using #{db_class}" do + let(:db_data_sources) { db_class.connection.data_sources } + + # The Geo database does not share the same structure as all decomposed databases + subject { described_class.tables_to_schema.select { |_, v| v != :gitlab_geo } } + it 'new data sources are added' do missing_tables = db_data_sources.to_set - subject.keys expect(missing_tables).to be_empty, \ "Missing table(s) #{missing_tables.to_a} not found in #{described_class}.tables_to_schema. " \ - "Any new tables must be added to lib/gitlab/database/gitlab_schemas.yml." + "Any new tables must be added to #{described_class::GITLAB_SCHEMAS_FILE}." end it 'non-existing data sources are removed' do @@ -30,7 +31,7 @@ RSpec.describe Gitlab::Database::GitlabSchema do expect(extra_tables).to be_empty, \ "Extra table(s) #{extra_tables.to_a} found in #{described_class}.tables_to_schema. " \ - "Any removed or renamed tables must be removed from lib/gitlab/database/gitlab_schemas.yml." + "Any removed or renamed tables must be removed from #{described_class::GITLAB_SCHEMAS_FILE}." end end end diff --git a/spec/lib/gitlab/database/loose_foreign_keys_spec.rb b/spec/lib/gitlab/database/loose_foreign_keys_spec.rb index ed11699e494..87a3e0f81e4 100644 --- a/spec/lib/gitlab/database/loose_foreign_keys_spec.rb +++ b/spec/lib/gitlab/database/loose_foreign_keys_spec.rb @@ -63,19 +63,22 @@ RSpec.describe Gitlab::Database::LooseForeignKeys do Gitlab::Database.schemas_to_base_models.fetch(parent_table_schema) end - it 'all `to_table` tables are present' do + it 'all `to_table` tables are present', :aggregate_failures do definitions.each do |definition| base_models_for(definition.to_table).each do |model| - expect(model.connection).to be_table_exist(definition.to_table) + expect(model.connection).to be_table_exist(definition.to_table), + "Table #{definition.from_table} does not exist" end end end - it 'all `from_table` tables are present' do + it 'all `from_table` tables are present', :aggregate_failures do definitions.each do |definition| base_models_for(definition.from_table).each do |model| - expect(model.connection).to be_table_exist(definition.from_table) - expect(model.connection).to be_column_exist(definition.from_table, definition.column) + expect(model.connection).to be_table_exist(definition.from_table), + "Table #{definition.from_table} does not exist" + expect(model.connection).to be_column_exist(definition.from_table, definition.column), + "Column #{definition.column} in #{definition.from_table} does not exist" end end end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index e09016b2b2b..3ccc3a17862 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -2477,6 +2477,9 @@ RSpec.describe Gitlab::Database::MigrationHelpers do describe '#backfill_iids' do include MigrationsHelpers + let_it_be(:issue_base_type_enum) { 0 } + let_it_be(:issue_type) { table(:work_item_types).find_by(base_type: issue_base_type_enum) } + let(:issue_class) do Class.new(ActiveRecord::Base) do include AtomicInternalId @@ -2490,6 +2493,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers do scope: :project, init: ->(s, _scope) { s&.project&.issues&.maximum(:iid) }, presence: false + + before_validation -> { self.work_item_type_id = ::WorkItems::Type.default_issue_type.id } end end @@ -2515,7 +2520,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do it 'generates iids properly for models created after the migration when iids are backfilled' do project = setup - issue_a = issues.create!(project_id: project.id) + issue_a = issues.create!(project_id: project.id, work_item_type_id: issue_type.id) model.backfill_iids('issues') @@ -2528,14 +2533,14 @@ RSpec.describe Gitlab::Database::MigrationHelpers do it 'generates iids properly for models created after the migration across multiple projects' do project_a = setup project_b = setup - issues.create!(project_id: project_a.id) - issues.create!(project_id: project_b.id) - issues.create!(project_id: project_b.id) + issues.create!(project_id: project_a.id, work_item_type_id: issue_type.id) + issues.create!(project_id: project_b.id, work_item_type_id: issue_type.id) + issues.create!(project_id: project_b.id, work_item_type_id: issue_type.id) model.backfill_iids('issues') - issue_a = issue_class.create!(project_id: project_a.id) - issue_b = issue_class.create!(project_id: project_b.id) + issue_a = issue_class.create!(project_id: project_a.id, work_item_type_id: issue_type.id) + issue_b = issue_class.create!(project_id: project_b.id, work_item_type_id: issue_type.id) expect(issue_a.iid).to eq(2) expect(issue_b.iid).to eq(3) @@ -2545,7 +2550,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do it 'generates an iid' do project_a = setup project_b = setup - issue_a = issues.create!(project_id: project_a.id) + issue_a = issues.create!(project_id: project_a.id, work_item_type_id: issue_type.id) model.backfill_iids('issues') @@ -2559,8 +2564,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers do context 'when a row already has an iid set in the database' do it 'backfills iids' do project = setup - issue_a = issues.create!(project_id: project.id, iid: 1) - issue_b = issues.create!(project_id: project.id, iid: 2) + issue_a = issues.create!(project_id: project.id, work_item_type_id: issue_type.id, iid: 1) + issue_b = issues.create!(project_id: project.id, work_item_type_id: issue_type.id, iid: 2) model.backfill_iids('issues') @@ -2571,9 +2576,9 @@ RSpec.describe Gitlab::Database::MigrationHelpers do it 'backfills for multiple projects' do project_a = setup project_b = setup - issue_a = issues.create!(project_id: project_a.id, iid: 1) - issue_b = issues.create!(project_id: project_b.id, iid: 1) - issue_c = issues.create!(project_id: project_a.id, iid: 2) + issue_a = issues.create!(project_id: project_a.id, work_item_type_id: issue_type.id, iid: 1) + issue_b = issues.create!(project_id: project_b.id, work_item_type_id: issue_type.id, iid: 1) + issue_c = issues.create!(project_id: project_a.id, work_item_type_id: issue_type.id, iid: 2) model.backfill_iids('issues') diff --git a/spec/lib/gitlab/database/migrations/batched_background_migration_helpers_spec.rb b/spec/lib/gitlab/database/migrations/batched_background_migration_helpers_spec.rb index f3414727245..5bfb2516ba1 100644 --- a/spec/lib/gitlab/database/migrations/batched_background_migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migrations/batched_background_migration_helpers_spec.rb @@ -173,17 +173,6 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d expect(Gitlab::Database::BackgroundMigration::BatchedMigration.last).to be_finished end - - context 'when within transaction' do - before do - allow(migration).to receive(:transaction_open?).and_return(true) - end - - it 'does raise an exception' do - expect { migration.queue_batched_background_migration('MyJobClass', :events, :id, job_interval: 5.minutes)} - .to raise_error /`queue_batched_background_migration` cannot be run inside a transaction./ - end - end end end @@ -301,12 +290,8 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d end describe '#delete_batched_background_migration' do - let(:transaction_open) { false } - before do expect(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas).to receive(:require_dml_mode!) - - allow(migration).to receive(:transaction_open?).and_return(transaction_open) end context 'when migration exists' do @@ -360,15 +345,6 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d end.not_to change { Gitlab::Database::BackgroundMigration::BatchedMigration.count } end end - - context 'when within transaction' do - let(:transaction_open) { true } - - it 'raises an exception' do - expect { migration.delete_batched_background_migration('MyJobClass', :projects, :id, [[:id], [:id_convert_to_bigint]]) } - .to raise_error /`#delete_batched_background_migration` cannot be run inside a transaction./ - end - end end describe '#gitlab_schema_from_context' do diff --git a/spec/lib/gitlab/database/migrations/reestablished_connection_stack_spec.rb b/spec/lib/gitlab/database/migrations/reestablished_connection_stack_spec.rb index d197f39be40..c6327de98d1 100644 --- a/spec/lib/gitlab/database/migrations/reestablished_connection_stack_spec.rb +++ b/spec/lib/gitlab/database/migrations/reestablished_connection_stack_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Gitlab::Database::Migrations::ReestablishedConnectionStack do end describe '#with_restored_connection_stack' do - Gitlab::Database.database_base_models.each do |db_config_name, _| + Gitlab::Database.database_base_models_with_gitlab_shared.each do |db_config_name, _| context db_config_name do it_behaves_like "reconfigures connection stack", db_config_name do it 'does restore connection hierarchy' do diff --git a/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb b/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb index 2f3d44f6f8f..f1f72d71e1a 100644 --- a/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb +++ b/spec/lib/gitlab/database/migrations/test_batched_background_runner_spec.rb @@ -68,10 +68,10 @@ RSpec.describe Gitlab::Database::Migrations::TestBatchedBackgroundRunner, :freez end context 'with multiple jobs to run' do - it 'runs all jobs created within the last 48 hours' do + it 'runs all jobs created within the last 3 hours' do old_migration = define_background_migration(migration_name) - travel 3.days + travel 4.hours new_migration = define_background_migration('NewMigration') { travel 1.second } migration.queue_batched_background_migration('NewMigration', table_name, :id, diff --git a/spec/lib/gitlab/database/postgres_autovacuum_activity_spec.rb b/spec/lib/gitlab/database/postgres_autovacuum_activity_spec.rb new file mode 100644 index 00000000000..c1ac8f0c9cd --- /dev/null +++ b/spec/lib/gitlab/database/postgres_autovacuum_activity_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::PostgresAutovacuumActivity, type: :model do + include Database::DatabaseHelpers + + it { is_expected.to be_a Gitlab::Database::SharedModel } + + describe '.for_tables' do + subject { described_class.for_tables(tables) } + + let(:tables) { %w[foo test] } + + before do + swapout_view_for_table(:postgres_autovacuum_activity) + + # unrelated + create(:postgres_autovacuum_activity, table: 'bar') + + tables.each do |table| + create(:postgres_autovacuum_activity, table: table) + end + + expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary).and_yield + end + + it 'returns autovacuum activity for queries tables' do + expect(subject.map(&:table).sort).to eq(tables) + end + end +end diff --git a/spec/lib/gitlab/database/reindexing_spec.rb b/spec/lib/gitlab/database/reindexing_spec.rb index 0c576505e07..976b9896dfa 100644 --- a/spec/lib/gitlab/database/reindexing_spec.rb +++ b/spec/lib/gitlab/database/reindexing_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Gitlab::Database::Reindexing do include Database::DatabaseHelpers describe '.invoke' do - let(:databases) { Gitlab::Database.database_base_models } + let(:databases) { Gitlab::Database.database_base_models_with_gitlab_shared } let(:databases_count) { databases.count } it 'cleans up any leftover indexes' do |