2022-08-30 11:10:02 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
RSpec.describe 'load_balancing', :delete, :reestablished_active_record_base do
|
|
|
|
subject(:initialize_load_balancer) do
|
|
|
|
load Rails.root.join('config/initializers/load_balancing.rb')
|
|
|
|
end
|
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
before do
|
|
|
|
# Stub out middleware call, as not idempotent
|
|
|
|
allow(Gitlab::Application.instance.middleware).to receive(:use)
|
|
|
|
end
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
context 'with replica hosts configured' do
|
2022-08-30 11:10:02 -04:00
|
|
|
before do
|
|
|
|
# Setup host-based load balancing
|
|
|
|
# Patch in our load balancer config, simply pointing at the test database twice
|
|
|
|
allow(Gitlab::Database::LoadBalancing::Configuration).to receive(:for_model) do |base_model|
|
|
|
|
db_host = base_model.connection_pool.db_config.host
|
|
|
|
|
|
|
|
Gitlab::Database::LoadBalancing::Configuration.new(base_model, [db_host, db_host])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
|
|
|
# reset load balancing to original state
|
|
|
|
allow(Gitlab::Database::LoadBalancing::Configuration).to receive(:for_model).and_call_original
|
|
|
|
allow(Gitlab::Cluster::LifecycleEvents).to receive(:in_clustered_puma?).and_call_original
|
|
|
|
|
|
|
|
load Rails.root.join('config/initializers/load_balancing.rb')
|
|
|
|
end
|
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
it 'configures load balancer with two replica hosts' do
|
|
|
|
expect(ApplicationRecord.connection.load_balancer.configuration.hosts.size).to eq(0)
|
|
|
|
expect(Ci::ApplicationRecord.connection.load_balancer.configuration.hosts.size).to eq(0)
|
|
|
|
|
2022-08-30 11:10:02 -04:00
|
|
|
initialize_load_balancer
|
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
expect(ApplicationRecord.connection.load_balancer.configuration.hosts.size).to eq(2)
|
|
|
|
expect(Ci::ApplicationRecord.connection.load_balancer.configuration.hosts.size).to eq(2)
|
2022-08-30 11:10:02 -04:00
|
|
|
end
|
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
context 'for a clustered puma worker' do
|
|
|
|
let!(:group) { create(:group, name: 'my group') }
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
before do
|
|
|
|
# Pretend we are in clustered environment
|
|
|
|
allow(Gitlab::Cluster::LifecycleEvents).to receive(:in_clustered_puma?).and_return(true)
|
|
|
|
end
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
it 'configures load balancer to have two replica hosts' do
|
|
|
|
initialize_load_balancer
|
|
|
|
|
|
|
|
simulate_puma_worker do
|
|
|
|
expect(ApplicationRecord.connection.load_balancer.configuration.hosts.size).to eq(2)
|
|
|
|
expect(Ci::ApplicationRecord.connection.load_balancer.configuration.hosts.size).to eq(2)
|
|
|
|
end
|
|
|
|
end
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
# We tried using Process.fork for a more realistic simulation
|
|
|
|
# but run into bugs where GPRC cannot be used before forking processes.
|
|
|
|
# See https://gitlab.com/gitlab-org/gitlab/-/issues/333184#note_1081658113
|
|
|
|
def simulate_puma_worker
|
|
|
|
# Called in https://github.com/rails/rails/blob/6-1-stable/activerecord/lib/active_record/connection_adapters/pool_config.rb#L73
|
|
|
|
ActiveRecord::ConnectionAdapters::PoolConfig.discard_pools!
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
# Called in config/puma.rb
|
|
|
|
Gitlab::Cluster::LifecycleEvents.do_worker_start
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
yield
|
2022-08-30 11:10:02 -04:00
|
|
|
end
|
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
it 'makes a read query successfully' do
|
|
|
|
# Clear any previous sticky writes
|
|
|
|
::Gitlab::Database::LoadBalancing::Session.clear_session
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
initialize_load_balancer
|
2022-08-30 11:10:02 -04:00
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
group_name = simulate_puma_worker do
|
|
|
|
Group.find_by_name('my group').name
|
2022-08-30 11:10:02 -04:00
|
|
|
end
|
|
|
|
|
2022-08-31 20:09:48 -04:00
|
|
|
expect(group_name).to eq(group.name)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'makes a write query successfully' do
|
|
|
|
initialize_load_balancer
|
|
|
|
|
|
|
|
expect do
|
|
|
|
simulate_puma_worker do
|
|
|
|
Group.touch_all
|
|
|
|
end
|
|
|
|
|
|
|
|
group.reload
|
|
|
|
end.to change(group, :updated_at)
|
|
|
|
end
|
2022-08-30 11:10:02 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|