(POOLER-70) Update the provider base class

Previously it was expected that the timeout setting should be passed when
determining whether a VM was ready.  However this should be in the pool
configuration and is not required to be a method parameter.

Previously many of the methods did not have a pool name passed as a parameter.
While this may be ok for the vSphere provider, it may not for other providers.
This commit changes the base provider to consistently use (pool,vm,other..) as
method parameters.  This commit also updates the base spec tests as well.

Additionally:
- Updated documentation around expected error states
- Updated documentation to be more consistent in format
- Added snapshot and disk manager functions and unit tests
- Update the initialization method to take in a more formal defintion with
  required global objects for metrics, logging and configuration
- Added helper functions
  - logger : Allows providers to log information as per Pool Manager
  - metrics : Allows providers to submit metrics as per Pool Manager
  - provider_options : Allows providers to access initialization options for a
    provider
  - pool_config : Get the configuration for a specific pool
  - provider_config : Get the configuration of this specific provider
  - global_config: Get the VMPooler global configuration
This commit is contained in:
Glenn Sarti 2017-03-28 19:12:17 -07:00
parent 901ddde7c3
commit 821dcf45c2
2 changed files with 266 additions and 62 deletions

View file

@ -4,7 +4,12 @@ require 'spec_helper'
# to enforce that certain methods are defined in the base classes
describe 'Vmpooler::PoolManager::Provider::Base' do
let(:logger) { MockLogger.new }
let(:metrics) { Vmpooler::DummyStatsd.new }
let(:config) { {} }
let(:provider_name) { 'base' }
let(:provider_options) { { 'param' => 'value' } }
let(:fake_vm) {
fake_vm = {}
fake_vm['name'] = 'vm1'
@ -16,11 +21,102 @@ describe 'Vmpooler::PoolManager::Provider::Base' do
fake_vm
}
subject { Vmpooler::PoolManager::Provider::Base.new(config) }
subject { Vmpooler::PoolManager::Provider::Base.new(config, logger, metrics, provider_name, provider_options) }
# Helper attr_reader methods
describe '#logger' do
it 'should come from the provider initialization' do
expect(subject.logger).to be(logger)
end
end
describe '#metrics' do
it 'should come from the provider initialization' do
expect(subject.metrics).to be(metrics)
end
end
describe '#provider_options' do
it 'should come from the provider initialization' do
expect(subject.provider_options).to be(provider_options)
end
end
describe '#pool_config' do
let(:poolname) { 'pool1' }
let(:config) { YAML.load(<<-EOT
---
:pools:
- name: '#{poolname}'
alias: [ 'mockpool' ]
template: 'Templates/pool1'
folder: 'Pooler/pool1'
datastore: 'datastore0'
size: 5
timeout: 10
ready_ttl: 1440
clone_target: 'cluster1'
EOT
)
}
context 'Given a pool that does not exist' do
it 'should return nil' do
expect(subject.pool_config('missing_pool')).to be_nil
end
end
context 'Given a pool that does exist' do
it 'should return the pool\'s configuration' do
result = subject.pool_config(poolname)
expect(result['name']).to eq(poolname)
end
end
end
describe '#provider_config' do
let(:poolname) { 'pool1' }
let(:config) { YAML.load(<<-EOT
---
:providers:
:#{provider_name}:
option1: 'value1'
EOT
)
}
context 'Given a misconfigured provider name' do
let(:config) { YAML.load(<<-EOT
---
:providers:
:bad_provider:
option1: 'value1'
option2: 'value1'
EOT
)
}
it 'should return nil' do
expect(subject.provider_config).to be_nil
end
end
context 'Given a correct provider name' do
it 'should return the provider\'s configuration' do
result = subject.provider_config
expect(result['option1']).to eq('value1')
end
end
end
describe '#global_config' do
it 'should come from the provider initialization' do
expect(subject.global_config).to be(config)
end
end
# Pool Manager Methods
describe '#name' do
it 'should be base' do
expect(subject.name).to eq('base')
it "should come from the provider initialization" do
expect(subject.name).to eq(provider_name)
end
end
@ -32,25 +128,25 @@ describe 'Vmpooler::PoolManager::Provider::Base' do
describe '#get_vm_host' do
it 'should raise error' do
expect{subject.get_vm_host('vm')}.to raise_error(/does not implement get_vm_host/)
expect{subject.get_vm_host('pool', 'vm')}.to raise_error(/does not implement get_vm_host/)
end
end
describe '#find_least_used_compatible_host' do
it 'should raise error' do
expect{subject.find_least_used_compatible_host('vm')}.to raise_error(/does not implement find_least_used_compatible_host/)
expect{subject.find_least_used_compatible_host('pool', 'vm')}.to raise_error(/does not implement find_least_used_compatible_host/)
end
end
describe '#migrate_vm_to_host' do
it 'should raise error' do
expect{subject.migrate_vm_to_host('vm','host')}.to raise_error(/does not implement migrate_vm_to_host/)
expect{subject.migrate_vm_to_host('pool', 'vm','host')}.to raise_error(/does not implement migrate_vm_to_host/)
end
end
describe '#get_vm' do
it 'should raise error' do
expect{subject.get_vm('vm')}.to raise_error(/does not implement get_vm/)
expect{subject.get_vm('pool', 'vm')}.to raise_error(/does not implement get_vm/)
end
end
@ -60,33 +156,51 @@ describe 'Vmpooler::PoolManager::Provider::Base' do
end
end
describe '#create_disk' do
it 'should raise error' do
expect{subject.create_disk('pool', 'vm', 10)}.to raise_error(/does not implement create_disk/)
end
end
describe '#create_snapshot' do
it 'should raise error' do
expect{subject.create_snapshot('pool', 'vm', 'snapshot')}.to raise_error(/does not implement create_snapshot/)
end
end
describe '#revert_snapshot' do
it 'should raise error' do
expect{subject.revert_snapshot('pool', 'vm', 'snapshot')}.to raise_error(/does not implement revert_snapshot/)
end
end
describe '#destroy_vm' do
it 'should raise error' do
expect{subject.destroy_vm('vm','pool')}.to raise_error(/does not implement destroy_vm/)
expect{subject.destroy_vm('pool', 'vm')}.to raise_error(/does not implement destroy_vm/)
end
end
describe '#vm_ready?' do
it 'should raise error' do
expect{subject.vm_ready?('vm','pool','timeout')}.to raise_error(/does not implement vm_ready?/)
expect{subject.vm_ready?('pool', 'vm')}.to raise_error(/does not implement vm_ready?/)
end
end
describe '#vm_exists?' do
it 'should raise error' do
expect{subject.vm_exists?('vm')}.to raise_error(/does not implement/)
expect{subject.vm_exists?('pool', 'vm')}.to raise_error(/does not implement/)
end
it 'should return true when get_vm returns an object' do
allow(subject).to receive(:get_vm).with('vm').and_return(fake_vm)
allow(subject).to receive(:get_vm).with('pool', 'vm').and_return(fake_vm)
expect(subject.vm_exists?('vm')).to eq(true)
expect(subject.vm_exists?('pool', 'vm')).to eq(true)
end
it 'should return false when get_vm returns nil' do
allow(subject).to receive(:get_vm).with('vm').and_return(nil)
allow(subject).to receive(:get_vm).with('pool', 'vm').and_return(nil)
expect(subject.vm_exists?('vm')).to eq(false)
expect(subject.vm_exists?('pool', 'vm')).to eq(false)
end
end
end