mirror of
https://github.com/puppetlabs/vmpooler-dns-gcp.git
synced 2026-01-26 11:08:41 -05:00
Add rspec tests
This commit is contained in:
parent
103a73b298
commit
fb8c168751
6 changed files with 376 additions and 19 deletions
294
spec/unit/dns/clouddns_spec.rb
Normal file
294
spec/unit/dns/clouddns_spec.rb
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
require 'spec_helper'
|
||||
require 'mock_redis'
|
||||
require 'vmpooler/dns/gcp/clouddns'
|
||||
|
||||
describe 'Vmpooler::PoolManager::Dns::Gcp' do
|
||||
let(:logger) { MockLogger.new }
|
||||
let(:metrics) { Vmpooler::Metrics::DummyStatsd.new }
|
||||
let(:poolname) { 'debian-9' }
|
||||
let(:options) { { 'param' => 'value' } }
|
||||
let(:name) { 'gcp' }
|
||||
let(:zone_name) { 'vmpooler-example-com' }
|
||||
let(:config) { YAML.load(<<~EOT
|
||||
---
|
||||
:config:
|
||||
max_tries: 3
|
||||
retry_factor: 10
|
||||
:dns_configs:
|
||||
:#{name}:
|
||||
dns_class: gcp-clouddns
|
||||
project: vmpooler-example
|
||||
domain: vmpooler.example.com
|
||||
zone_name: vmpooler-example-com
|
||||
dns_zone_resource_name: vmpooler-example-com
|
||||
:providers:
|
||||
:dummy:
|
||||
filename: '/tmp/dummy-backing.yaml'
|
||||
:pools:
|
||||
- name: '#{poolname}'
|
||||
alias: [ 'mockpool' ]
|
||||
template: 'Templates/debian-9-x86_64'
|
||||
size: 5
|
||||
timeout: 10
|
||||
ready_ttl: 1440
|
||||
provider: 'dummy'
|
||||
dns_config: '#{name}'
|
||||
EOT
|
||||
)
|
||||
}
|
||||
|
||||
let(:vmname) { 'spicy-proton' }
|
||||
let(:connection_options) {{}}
|
||||
let(:connection) { mock_Google_Cloud_Dns_Project_Connection(connection_options) }
|
||||
let(:redis_connection_pool) do
|
||||
Vmpooler::PoolManager::GenericConnectionPool.new(
|
||||
metrics: metrics,
|
||||
connpool_type: 'redis_connection_pool',
|
||||
connpool_provider: 'testprovider',
|
||||
size: 1,
|
||||
timeout: 5
|
||||
) { MockRedis.new }
|
||||
end
|
||||
|
||||
subject { Vmpooler::PoolManager::Dns::Gcp::Clouddns.new(config, logger, metrics, redis_connection_pool, name, options) }
|
||||
|
||||
describe '#name' do
|
||||
it 'should be gcp-clouddns' do
|
||||
expect(subject.name).to eq('gcp-clouddns')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#project' do
|
||||
it 'should be the project specified in the dns config' do
|
||||
expect(subject.project).to eq('vmpooler-example')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#zone_name' do
|
||||
it 'should be the zone_name specified in the dns config' do
|
||||
expect(subject.zone_name).to eq('vmpooler-example-com')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#create_or_replace_record' do
|
||||
let(:hostname) { 'spicy-proton' }
|
||||
let(:zone) { MockDnsZone.new }
|
||||
let(:ip) { '169.254.255.255' }
|
||||
|
||||
context 'when adding a record' do
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).and_return(connection)
|
||||
allow(connection).to receive(:zone).and_return(zone)
|
||||
allow(subject).to receive(:get_ip).and_return(ip)
|
||||
end
|
||||
|
||||
it 'should attempt to add a record' do
|
||||
expect(zone).to receive(:add).with(hostname, 'A', 60, ip)
|
||||
result = subject.create_or_replace_record(hostname)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when record already exists' do
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).and_return(connection)
|
||||
allow(connection).to receive(:zone).and_return(zone)
|
||||
allow(subject).to receive(:get_ip).and_return(ip)
|
||||
end
|
||||
|
||||
it 'should attempt to replace a record' do
|
||||
allow(zone).to receive(:add).with(:hostname, 'A', 60, ip).and_raise(Google::Cloud::AlreadyExistsError,'MockError')
|
||||
expect(zone).to receive(:replace).with(:hostname, 'A', 60, ip)
|
||||
allow(subject).to receive(:get_ip).and_return(ip)
|
||||
result = subject.create_or_replace_record(:hostname)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when add record fails' do
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).and_return(connection)
|
||||
allow(connection).to receive(:zone).and_return(zone)
|
||||
allow(subject).to receive(:get_ip).and_return(ip)
|
||||
end
|
||||
|
||||
it 'should retry' do
|
||||
allow(zone).to receive(:add).with(:hostname, 'A', 60, ip).and_raise(Google::Cloud::FailedPreconditionError,'MockError')
|
||||
expect(zone).to receive(:add).with(:hostname, 'A', 60, ip).exactly(30).times
|
||||
allow(subject).to receive(:sleep)
|
||||
result = subject.create_or_replace_record(:hostname)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when IP does not exist' do
|
||||
let(:ip) { nil }
|
||||
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).and_return(connection)
|
||||
allow(connection).to receive(:zone).and_return(zone)
|
||||
allow(subject).to receive(:get_ip).and_return(ip)
|
||||
end
|
||||
|
||||
it 'should not attempt to add a record' do
|
||||
allow(zone).to receive(:add).with(:hostname, 'A', 60, ip).and_raise(Google::Cloud::AlreadyExistsError,'MockError')
|
||||
expect(zone).to_not have_received(:add)
|
||||
allow(subject).to receive(:get_ip).and_return(ip)
|
||||
result = subject.create_or_replace_record(:hostname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#delete_record" do
|
||||
let(:hostname) { 'spicy-proton' }
|
||||
let(:zone) { MockDnsZone.new }
|
||||
|
||||
context 'when removing a record' do
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).and_return(connection)
|
||||
allow(connection).to receive(:zone).and_return(zone)
|
||||
end
|
||||
|
||||
it 'should attempt to remove a record' do
|
||||
expect(zone).to receive(:remove).with(:hostname, 'A')
|
||||
result = subject.delete_record(:hostname)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when removing a record fails' do
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).and_return(connection)
|
||||
allow(connection).to receive(:zone).and_return(zone)
|
||||
end
|
||||
|
||||
it 'should retry' do
|
||||
allow(zone).to receive(:remove).with(:hostname, 'A').and_raise(Google::Cloud::FailedPreconditionError,'MockError')
|
||||
expect(zone).to receive(:remove).with(:hostname, 'A').exactly(30).times
|
||||
allow(subject).to receive(:sleep)
|
||||
result = subject.delete_record(:hostname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#ensured_gcp_connection' do
|
||||
let(:connection1) { mock_Google_Cloud_Dns_Project_Connection(connection_options) }
|
||||
let(:connection2) { mock_Google_Cloud_Dns_Project_Connection(connection_options) }
|
||||
|
||||
before(:each) do
|
||||
allow(subject).to receive(:connect_to_gcp).and_return(connection1)
|
||||
end
|
||||
|
||||
it 'should return the same connection object when calling the pool multiple times' do
|
||||
subject.connection_pool.with_metrics do |pool_object|
|
||||
expect(pool_object[:connection]).to be(connection1)
|
||||
end
|
||||
subject.connection_pool.with_metrics do |pool_object|
|
||||
expect(pool_object[:connection]).to be(connection1)
|
||||
end
|
||||
subject.connection_pool.with_metrics do |pool_object|
|
||||
expect(pool_object[:connection]).to be(connection1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the connection breaks' do
|
||||
before(:each) do
|
||||
# Emulate the connection state being good, then bad, then good again
|
||||
expect(subject).to receive(:gcp_connection_ok?).and_return(true, false, true)
|
||||
expect(subject).to receive(:connect_to_gcp).and_return(connection1, connection2)
|
||||
end
|
||||
|
||||
it 'should restore the connection' do
|
||||
subject.connection_pool.with_metrics do |pool_object|
|
||||
# This line needs to be added to all instances of the connection_pool allocation
|
||||
connection = subject.ensured_gcp_connection(pool_object)
|
||||
|
||||
expect(connection).to be(connection1)
|
||||
end
|
||||
|
||||
subject.connection_pool.with_metrics do |pool_object|
|
||||
connection = subject.ensured_gcp_connection(pool_object)
|
||||
# The second connection would have failed. This test ensures that a
|
||||
# new connection object was created.
|
||||
expect(connection).to be(connection2)
|
||||
end
|
||||
|
||||
subject.connection_pool.with_metrics do |pool_object|
|
||||
connection = subject.ensured_gcp_connection(pool_object)
|
||||
expect(connection).to be(connection2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#connect_to_gcp' do
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).and_return(connection)
|
||||
end
|
||||
|
||||
context 'successful connection' do
|
||||
it 'should return the connection object' do
|
||||
result = subject.connect_to_gcp
|
||||
|
||||
expect(result).to be(connection)
|
||||
end
|
||||
|
||||
it 'should increment the connect.open counter' do
|
||||
expect(metrics).to receive(:increment).with('connect.open')
|
||||
subject.connect_to_gcp
|
||||
end
|
||||
end
|
||||
|
||||
context 'connection is initially unsuccessful' do
|
||||
before(:each) do
|
||||
# Simulate a failure and then success
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
expect(Google::Cloud::Dns).to receive(:new).and_raise(RuntimeError,'MockError')
|
||||
allow(subject).to receive(:sleep)
|
||||
end
|
||||
|
||||
it 'should return the connection object' do
|
||||
result = subject.connect_to_gcp
|
||||
|
||||
expect(result).to be(connection)
|
||||
end
|
||||
|
||||
it 'should increment the connect.fail and then connect.open counter' do
|
||||
expect(metrics).to receive(:increment).with('connect.fail').exactly(1).times
|
||||
expect(metrics).to receive(:increment).with('connect.open').exactly(1).times
|
||||
subject.connect_to_gcp
|
||||
end
|
||||
end
|
||||
|
||||
context 'connection is always unsuccessful' do
|
||||
before(:each) do
|
||||
allow(Google::Cloud::Dns).to receive(:configure)
|
||||
allow(Google::Cloud::Dns).to receive(:new).exactly(3).times.and_raise(RuntimeError,'MockError')
|
||||
allow(subject).to receive(:sleep)
|
||||
end
|
||||
|
||||
it 'should retry the connection attempt config.max_tries times' do
|
||||
expect(Google::Cloud::Dns).to receive(:new).exactly(config[:config]['max_tries']).times
|
||||
|
||||
begin
|
||||
# Swallow any errors
|
||||
subject.connect_to_gcp
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
it 'should increment the connect.fail counter config.max_tries times' do
|
||||
expect(metrics).to receive(:increment).with('connect.fail').exactly(config[:config]['max_tries']).times
|
||||
|
||||
begin
|
||||
# Swallow any errors
|
||||
subject.connect_to_gcp
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue