Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/database/load_balancing_spec.rb')
-rw-r--r--spec/lib/gitlab/database/load_balancing_spec.rb233
1 files changed, 65 insertions, 168 deletions
diff --git a/spec/lib/gitlab/database/load_balancing_spec.rb b/spec/lib/gitlab/database/load_balancing_spec.rb
index 6ec8e0516f6..f40ad444081 100644
--- a/spec/lib/gitlab/database/load_balancing_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing_spec.rb
@@ -40,106 +40,25 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
describe '.configuration' do
- it 'returns a Hash' do
- lb_config = { 'hosts' => %w(foo) }
+ it 'returns the configuration for the load balancer' do
+ raw = ActiveRecord::Base.connection_db_config.configuration_hash
+ cfg = described_class.configuration
- original_db_config = Gitlab::Database.main.config
- modified_db_config = original_db_config.merge(load_balancing: lb_config)
- expect(Gitlab::Database.main).to receive(:config).and_return(modified_db_config)
-
- expect(described_class.configuration).to eq(lb_config)
- end
- end
-
- describe '.max_replication_difference' do
- context 'without an explicitly configured value' do
- it 'returns the default value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({})
-
- expect(described_class.max_replication_difference).to eq(8.megabytes)
- end
- end
-
- context 'with an explicitly configured value' do
- it 'returns the configured value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'max_replication_difference' => 4 })
-
- expect(described_class.max_replication_difference).to eq(4)
- end
- end
- end
-
- describe '.max_replication_lag_time' do
- context 'without an explicitly configured value' do
- it 'returns the default value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({})
-
- expect(described_class.max_replication_lag_time).to eq(60)
- end
- end
-
- context 'with an explicitly configured value' do
- it 'returns the configured value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'max_replication_lag_time' => 4 })
-
- expect(described_class.max_replication_lag_time).to eq(4)
- end
- end
- end
-
- describe '.replica_check_interval' do
- context 'without an explicitly configured value' do
- it 'returns the default value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({})
-
- expect(described_class.replica_check_interval).to eq(60)
- end
- end
-
- context 'with an explicitly configured value' do
- it 'returns the configured value' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'replica_check_interval' => 4 })
-
- expect(described_class.replica_check_interval).to eq(4)
- end
- end
- end
-
- describe '.hosts' do
- it 'returns a list of hosts' do
- allow(described_class)
- .to receive(:configuration)
- .and_return({ 'hosts' => %w(foo bar baz) })
-
- expect(described_class.hosts).to eq(%w(foo bar baz))
- end
- end
-
- describe '.pool_size' do
- it 'returns a Fixnum' do
- expect(described_class.pool_size).to be_a_kind_of(Integer)
+ # There isn't much to test here as the load balancing settings might not
+ # (and likely aren't) set when running tests.
+ expect(cfg.pool_size).to eq(raw[:pool])
end
end
describe '.enable?' do
before do
- allow(described_class).to receive(:hosts).and_return(%w(foo))
+ allow(described_class.configuration)
+ .to receive(:hosts)
+ .and_return(%w(foo))
end
it 'returns false when no hosts are specified' do
- allow(described_class).to receive(:hosts).and_return([])
+ allow(described_class.configuration).to receive(:hosts).and_return([])
expect(described_class.enable?).to eq(false)
end
@@ -163,10 +82,10 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
it 'returns true when service discovery is enabled' do
- allow(described_class).to receive(:hosts).and_return([])
+ allow(described_class.configuration).to receive(:hosts).and_return([])
allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(false)
- allow(described_class)
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(true)
@@ -175,17 +94,17 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
describe '.configured?' do
- it 'returns true when Sidekiq is being used' do
- allow(described_class).to receive(:hosts).and_return(%w(foo))
- allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
+ it 'returns true when hosts are configured' do
+ allow(described_class.configuration)
+ .to receive(:hosts)
+ .and_return(%w[foo])
+
expect(described_class.configured?).to eq(true)
end
- it 'returns true when service discovery is enabled in Sidekiq' do
- allow(described_class).to receive(:hosts).and_return([])
- allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
-
- allow(described_class)
+ it 'returns true when service discovery is enabled' do
+ allow(described_class.configuration).to receive(:hosts).and_return([])
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(true)
@@ -193,9 +112,8 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
it 'returns false when neither service discovery nor hosts are configured' do
- allow(described_class).to receive(:hosts).and_return([])
-
- allow(described_class)
+ allow(described_class.configuration).to receive(:hosts).and_return([])
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(false)
@@ -204,9 +122,11 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
describe '.configure_proxy' do
- it 'configures the connection proxy' do
+ before do
allow(ActiveRecord::Base).to receive(:load_balancing_proxy=)
+ end
+ it 'configures the connection proxy' do
described_class.configure_proxy
expect(ActiveRecord::Base).to have_received(:load_balancing_proxy=)
@@ -214,71 +134,24 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
context 'when service discovery is enabled' do
- let(:service_discovery) { double(Gitlab::Database::LoadBalancing::ServiceDiscovery) }
-
it 'runs initial service discovery when configuring the connection proxy' do
- allow(described_class)
- .to receive(:configuration)
- .and_return('discover' => { 'record' => 'foo' })
-
- expect(Gitlab::Database::LoadBalancing::ServiceDiscovery).to receive(:new).and_return(service_discovery)
- expect(service_discovery).to receive(:perform_service_discovery)
-
- described_class.configure_proxy
- end
- end
- end
+ discover = instance_spy(Gitlab::Database::LoadBalancing::ServiceDiscovery)
- describe '.active_record_models' do
- it 'returns an Array' do
- expect(described_class.active_record_models).to be_an_instance_of(Array)
- end
- end
+ allow(described_class.configuration)
+ .to receive(:service_discovery)
+ .and_return({ record: 'foo' })
- describe '.service_discovery_enabled?' do
- it 'returns true if service discovery is enabled' do
- allow(described_class)
- .to receive(:configuration)
- .and_return('discover' => { 'record' => 'foo' })
-
- expect(described_class.service_discovery_enabled?).to eq(true)
- end
+ expect(Gitlab::Database::LoadBalancing::ServiceDiscovery)
+ .to receive(:new)
+ .with(
+ an_instance_of(Gitlab::Database::LoadBalancing::LoadBalancer),
+ an_instance_of(Hash)
+ )
+ .and_return(discover)
- it 'returns false if service discovery is disabled' do
- expect(described_class.service_discovery_enabled?).to eq(false)
- end
- end
+ expect(discover).to receive(:perform_service_discovery)
- describe '.service_discovery_configuration' do
- context 'when no configuration is provided' do
- it 'returns a default configuration Hash' do
- expect(described_class.service_discovery_configuration).to eq(
- nameserver: 'localhost',
- port: 8600,
- record: nil,
- record_type: 'A',
- interval: 60,
- disconnect_timeout: 120,
- use_tcp: false
- )
- end
- end
-
- context 'when configuration is provided' do
- it 'returns a Hash including the custom configuration' do
- allow(described_class)
- .to receive(:configuration)
- .and_return('discover' => { 'record' => 'foo', 'record_type' => 'SRV' })
-
- expect(described_class.service_discovery_configuration).to eq(
- nameserver: 'localhost',
- port: 8600,
- record: 'foo',
- record_type: 'SRV',
- interval: 60,
- disconnect_timeout: 120,
- use_tcp: false
- )
+ described_class.configure_proxy
end
end
end
@@ -292,15 +165,23 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
it 'starts service discovery if enabled' do
- allow(described_class)
+ allow(described_class.configuration)
.to receive(:service_discovery_enabled?)
.and_return(true)
instance = double(:instance)
+ config = Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base)
+ lb = Gitlab::Database::LoadBalancing::LoadBalancer.new(config)
+ proxy = Gitlab::Database::LoadBalancing::ConnectionProxy.new(lb)
+
+ allow(described_class)
+ .to receive(:proxy)
+ .and_return(proxy)
expect(Gitlab::Database::LoadBalancing::ServiceDiscovery)
.to receive(:new)
- .with(an_instance_of(Hash))
+ .with(lb, an_instance_of(Hash))
.and_return(instance)
expect(instance)
@@ -330,7 +211,13 @@ RSpec.describe Gitlab::Database::LoadBalancing do
context 'when the load balancing is configured' do
let(:db_host) { ActiveRecord::Base.connection_pool.db_config.host }
- let(:proxy) { described_class::ConnectionProxy.new([db_host]) }
+ let(:config) do
+ Gitlab::Database::LoadBalancing::Configuration
+ .new(ActiveRecord::Base, [db_host])
+ end
+
+ let(:load_balancer) { described_class::LoadBalancer.new(config) }
+ let(:proxy) { described_class::ConnectionProxy.new(load_balancer) }
context 'when a proxy connection is used' do
it 'returns :unknown' do
@@ -770,6 +657,16 @@ RSpec.describe Gitlab::Database::LoadBalancing do
it 'redirects queries to the right roles' do
roles = []
+ # If we don't run any queries, the pool may be a NullPool. This can
+ # result in some tests reporting a role as `:unknown`, even though the
+ # tests themselves are correct.
+ #
+ # To prevent this from happening we simply run a simple query to
+ # ensure the proper pool type is put in place. The exact query doesn't
+ # matter, provided it actually runs a query and thus creates a proper
+ # connection pool.
+ model.count
+
subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |event|
role = ::Gitlab::Database::LoadBalancing.db_role_for_connection(event.payload[:connection])
roles << role if role.present?