debian-mirror-gitlab/spec/lib/gitlab/database/load_balancing/host_list_spec.rb
2021-11-11 11:23:49 +05:30

141 lines
3.5 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database::LoadBalancing::HostList do
let(:db_host) { ActiveRecord::Base.connection_pool.db_config.host }
let(:load_balancer) do
Gitlab::Database::LoadBalancing::LoadBalancer.new(
Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
)
end
let(:host_count) { 2 }
let(:hosts) { Array.new(host_count) { Gitlab::Database::LoadBalancing::Host.new(db_host, load_balancer, port: 5432) } }
let(:host_list) { described_class.new(hosts) }
before do
# each call generate a new replica pool
allow(load_balancer).to receive(:create_replica_connection_pool) do
double(:replica_connection_pool)
end
end
describe '#initialize' do
it 'sets metrics for current number of hosts and current index' do
host_list
expect_metrics(2)
end
end
describe '#length' do
it 'returns the number of hosts in the list' do
expect(host_list.length).to eq(2)
end
end
describe '#host_names_and_ports' do
context 'with ports' do
it 'returns the host names of all hosts' do
hosts = [
[db_host, 5432],
[db_host, 5432]
]
expect(host_list.host_names_and_ports).to eq(hosts)
end
end
context 'without ports' do
let(:hosts) { Array.new(2) { Gitlab::Database::LoadBalancing::Host.new(db_host, load_balancer) } }
it 'returns the host names of all hosts' do
hosts = [
[db_host, nil],
[db_host, nil]
]
expect(host_list.host_names_and_ports).to eq(hosts)
end
end
end
describe '#hosts' do
it 'returns a copy of the host' do
first = host_list.hosts
expect(host_list.hosts).to eq(first)
expect(host_list.hosts.object_id).not_to eq(first.object_id)
end
end
describe '#hosts=' do
it 'updates the list of hosts to use' do
host_list.hosts = [
Gitlab::Database::LoadBalancing::Host.new('foo', load_balancer)
]
expect(host_list.length).to eq(1)
expect(host_list.hosts[0].host).to eq('foo')
expect_metrics(1)
end
end
describe '#next' do
it 'returns a host' do
expect(host_list.next)
.to be_an_instance_of(Gitlab::Database::LoadBalancing::Host)
end
it 'cycles through all available hosts' do
expect(host_list.next).to eq(host_list.hosts[0])
expect_metrics(2)
expect(host_list.next).to eq(host_list.hosts[1])
expect_metrics(2)
expect(host_list.next).to eq(host_list.hosts[0])
expect_metrics(2)
end
it 'skips hosts that are offline' do
allow(host_list.hosts[0]).to receive(:online?).and_return(false)
expect(host_list.next).to eq(host_list.hosts[1])
expect_metrics(2)
end
it 'returns nil if no hosts are online' do
host_list.hosts.each do |host|
allow(host).to receive(:online?).and_return(false)
end
expect(host_list.next).to be_nil
expect_metrics(2)
end
it 'returns nil if no hosts are available' do
expect(described_class.new.next).to be_nil
end
end
describe '#shuffle' do
let(:host_count) { 3 }
it 'randomizes the list' do
2.times do
all_hosts = host_list.hosts
host_list.shuffle
expect(host_list.length).to eq(host_count)
expect(host_list.hosts).to contain_exactly(*all_hosts)
end
end
end
def expect_metrics(hosts)
expect(Gitlab::Metrics.registry.get(:db_load_balancing_hosts).get({})).to eq(hosts)
end
end