spec/lib/support/bootstrap_rails_spec.rb (159 lines of code) (raw):

# frozen_string_literal: true require_relative '../../../lib/support/bootstrap_rails' RSpec.describe Support::BootstrapRails do let(:instance) { described_class.new } describe '#execute' do let(:geo_secondary) { nil } subject { instance.execute } before do stub_no_color_env('true') allow_any_instance_of(GDK::Config).to receive_message_chain('geo.secondary?').and_return(geo_secondary) end context 'embedding db' do let(:embedding_enabled) { nil } before do allow_any_instance_of(GDK::Config).to receive_message_chain('gitlab.rails.databases.embedding.enabled').and_return(embedding_enabled) allow_any_instance_of(GDK::Postgresql).to receive(:ready?).and_return(true) allow(instance).to receive(:try_connect!) allow(instance).to receive_messages(bootstrap_main_db: true, bootstrap_ci_db: true, bootstrap_sec_db: true) end context 'is not enabled' do it 'skips bootstrapping' do stub_rake_tasks('db:reset:embedding', success: false, retry_attempts: 3) expect_any_instance_of(GDK::Postgresql).not_to receive(:db_exists?).with('gitlabhq_development_embedding') expect { subject }.not_to raise_error end end context 'is enabled' do let(:embedding_enabled) { true } it 'tries to run bootstrapping' do stub_rake_tasks('db:reset:embedding', success: true, retry_attempts: 3) expect_any_instance_of(GDK::Postgresql).to receive(:db_exists?).with('gitlabhq_development_embedding') expect { subject }.not_to raise_error end end end context 'sec db' do let(:sec_enabled) { nil } let(:use_main_database) { nil } before do allow_any_instance_of(GDK::Config).to receive_message_chain('gitlab.rails.databases.sec.__enabled').and_return(sec_enabled) allow_any_instance_of(GDK::Config).to receive_message_chain('gitlab.rails.databases.sec.__use_main_database').and_return(use_main_database) allow_any_instance_of(GDK::Postgresql).to receive(:ready?).and_return(true) allow(instance).to receive(:try_connect!) allow(instance).to receive_messages(bootstrap_main_db: true, bootstrap_ci_db: true, bootstrap_embedding_db: true) end context 'is not enabled' do it 'skips bootstrapping' do stub_rake_tasks('dev:copy_db:sec', success: false, retry_attempts: 3) expect_any_instance_of(GDK::Postgresql).not_to receive(:db_exists?).with('gitlabhq_development_sec') expect { subject }.not_to raise_error end end context 'is use_main_database enabled' do let(:use_main_database) { true } it 'skips bootstrapping' do stub_rake_tasks('dev:copy_db:sec', success: false, retry_attempts: 3) expect_any_instance_of(GDK::Postgresql).not_to receive(:db_exists?).with('gitlabhq_development_sec') expect { subject }.not_to raise_error end end context 'when enabled' do let(:sec_enabled) { true } it 'tries to run bootstrapping' do stub_rake_tasks('dev:copy_db:sec', success: true, retry_attempts: 3) expect_any_instance_of(GDK::Postgresql).to receive(:db_exists?).with('gitlabhq_development_sec') expect { subject }.not_to raise_error end context 'when use_main_database enabled' do let(:use_main_database) { true } it 'skips bootstrapping' do stub_rake_tasks('dev:copy_db:sec', success: false, retry_attempts: 3) expect_any_instance_of(GDK::Postgresql).not_to receive(:db_exists?).with('gitlabhq_development_sec') expect { subject }.not_to raise_error end end end end context 'where we are a Geo secondary' do let(:geo_secondary) { true } it 'advises and exits' do expect(GDK::Output).to receive(:info).with("Exiting as we're a Geo secondary.") expect { subject }.to raise_error(SystemExit) end end context 'where we are not a Geo secondary' do let(:geo_secondary) { false } let(:postgres_mock) { instance_double(GDK::Postgresql, ready?: postgres_ready) } let(:postgres_ready) { nil } before do allow(GDK::Postgresql).to receive(:new).and_return(postgres_mock) end context 'but PostgreSQL is not ready' do let(:postgres_ready) { false } it 'advises and aborts' do expect { subject } .to output("ERROR: Cannot connect to PostgreSQL.\n").to_stderr .and raise_error(SystemExit) end end context 'and PostgreSQL is ready' do let(:postgres_ready) { true } let(:gitlabhq_development_db_exists) { nil } let(:gitlabhq_development_ci_db_exists) { nil } before do allow(instance).to receive(:try_connect!) allow(postgres_mock).to receive(:db_exists?).with('gitlabhq_development').and_return(gitlabhq_development_db_exists) allow(postgres_mock).to receive(:db_exists?).with('gitlabhq_development_ci').and_return(gitlabhq_development_ci_db_exists) end context 'when all DBs already exist' do let(:gitlabhq_development_db_exists) { true } let(:gitlabhq_development_ci_db_exists) { true } it 'advises and skips further logic' do expect(GDK::Output).to receive(:info).with('gitlabhq_development exists, nothing to do here.') expect(GDK::Output).to receive(:info).with('gitlabhq_development_ci exists, nothing to do here.') subject end end context 'where no DBs exist' do let(:gitlabhq_development_db_exists) { false } let(:gitlabhq_development_ci_db_exists) { false } context 'attempts to setup the gitlabhq_development DB' do context 'but `rake db:drop db:create gitlab:db:configure` fails' do it 'exits with a status code of 1' do stub_rake_tasks(%w[db:drop db:create gitlab:db:configure], success: false, retry_attempts: 3) expect { subject } .to output(/The rake task 'db:drop db:create gitlab:db:configure' failed/).to_stderr .and raise_error(SystemExit) { |error| expect(error.status).to eq(1) } end end context 'when `rake db:drop db:create gitlab:db:configure` succeeds' do context 'but `rake dev:copy_db:ci` fails' do it 'exits with a status code of 1' do stub_rake_tasks(%w[db:drop db:create gitlab:db:configure], success: true, retry_attempts: 3) stub_rake_tasks('db:seed_fu', success: true, retry_attempts: 3) stub_rake_tasks('dev:copy_db:ci', success: false, retry_attempts: 3) expect { subject } .to output(/The rake task 'dev:copy_db:ci' failed/).to_stderr .and raise_error(SystemExit) { |error| expect(error.status).to eq(1) } end end context 'and `rake dev:copy_db:ci` succeeds' do it 'exits with a status code of 0' do stub_rake_tasks(%w[db:drop db:create gitlab:db:configure], success: true, retry_attempts: 3) stub_rake_tasks('db:seed_fu', success: true, retry_attempts: 3) stub_rake_tasks('dev:copy_db:ci', success: true, retry_attempts: 3) expect { subject }.not_to raise_error end end end end end end end end def stub_rake_tasks(*tasks, success:, **args) rake_double = instance_double(GDK::Execute::Rake, success?: success) allow(GDK::Execute::Rake).to receive(:new).with(*tasks).and_return(rake_double) allow(rake_double).to receive(:execute_in_gitlab).with(**args).and_return(rake_double) end end