240 lines
8.2 KiB
Python
240 lines
8.2 KiB
Python
from mock import MagicMock, patch
|
|
import quantum_contexts
|
|
from contextlib import contextmanager
|
|
|
|
from test_utils import (
|
|
CharmTestCase
|
|
)
|
|
|
|
TO_PATCH = [
|
|
'config',
|
|
'relation_get',
|
|
'relation_ids',
|
|
'related_units',
|
|
'context_complete',
|
|
'unit_get',
|
|
'apt_install',
|
|
'get_os_codename_install_source',
|
|
]
|
|
|
|
|
|
@contextmanager
|
|
def patch_open():
|
|
'''Patch open() to allow mocking both open() itself and the file that is
|
|
yielded.
|
|
|
|
Yields the mock for "open" and "file", respectively.'''
|
|
mock_open = MagicMock(spec=open)
|
|
mock_file = MagicMock(spec=file)
|
|
|
|
@contextmanager
|
|
def stub_open(*args, **kwargs):
|
|
mock_open(*args, **kwargs)
|
|
yield mock_file
|
|
|
|
with patch('__builtin__.open', stub_open):
|
|
yield mock_open, mock_file
|
|
|
|
|
|
class _TestQuantumContext(CharmTestCase):
|
|
def setUp(self):
|
|
super(_TestQuantumContext, self).setUp(quantum_contexts, TO_PATCH)
|
|
self.config.side_effect = self.test_config.get
|
|
|
|
def test_not_related(self):
|
|
self.relation_ids.return_value = []
|
|
self.assertEquals(self.context(), {})
|
|
|
|
def test_no_units(self):
|
|
self.relation_ids.return_value = []
|
|
self.relation_ids.return_value = ['foo']
|
|
self.related_units.return_value = []
|
|
self.assertEquals(self.context(), {})
|
|
|
|
def test_no_data(self):
|
|
self.relation_ids.return_value = ['foo']
|
|
self.related_units.return_value = ['bar']
|
|
self.relation_get.side_effect = self.test_relation.get
|
|
self.context_complete.return_value = False
|
|
self.assertEquals(self.context(), {})
|
|
|
|
def test_data_multi_unit(self):
|
|
self.relation_ids.return_value = ['foo']
|
|
self.related_units.return_value = ['bar', 'baz']
|
|
self.context_complete.return_value = True
|
|
self.relation_get.side_effect = self.test_relation.get
|
|
self.assertEquals(self.context(), self.data_result)
|
|
|
|
def test_data_single_unit(self):
|
|
self.relation_ids.return_value = ['foo']
|
|
self.related_units.return_value = ['bar']
|
|
self.context_complete.return_value = True
|
|
self.relation_get.side_effect = self.test_relation.get
|
|
self.assertEquals(self.context(), self.data_result)
|
|
|
|
|
|
class TestQuantumSharedDBContext(_TestQuantumContext):
|
|
def setUp(self):
|
|
super(TestQuantumSharedDBContext, self).setUp()
|
|
self.context = quantum_contexts.QuantumSharedDBContext()
|
|
self.test_relation.set(
|
|
{'db_host': '10.5.0.1',
|
|
'nova_password': 'novapass',
|
|
'quantum_password': 'quantumpass'}
|
|
)
|
|
self.data_result = {
|
|
'database_host': '10.5.0.1',
|
|
'nova_user': 'nova',
|
|
'nova_password': 'novapass',
|
|
'nova_db': 'nova',
|
|
'quantum_user': 'quantum',
|
|
'quantum_password': 'quantumpass',
|
|
'quantum_db': 'quantum'
|
|
}
|
|
|
|
|
|
class TestNetworkServiceContext(_TestQuantumContext):
|
|
def setUp(self):
|
|
super(TestNetworkServiceContext, self).setUp()
|
|
self.context = quantum_contexts.NetworkServiceContext()
|
|
self.test_relation.set(
|
|
{'keystone_host': '10.5.0.1',
|
|
'service_port': '5000',
|
|
'auth_port': '20000',
|
|
'service_tenant': 'tenant',
|
|
'service_username': 'username',
|
|
'service_password': 'password',
|
|
'quantum_host': '10.5.0.2',
|
|
'quantum_port': '9696',
|
|
'quantum_url': 'http://10.5.0.2:9696/v2',
|
|
'region': 'aregion'}
|
|
)
|
|
self.data_result = {
|
|
'keystone_host': '10.5.0.1',
|
|
'service_port': '5000',
|
|
'auth_port': '20000',
|
|
'service_tenant': 'tenant',
|
|
'service_username': 'username',
|
|
'service_password': 'password',
|
|
'quantum_host': '10.5.0.2',
|
|
'quantum_port': '9696',
|
|
'quantum_url': 'http://10.5.0.2:9696/v2',
|
|
'region': 'aregion',
|
|
'service_protocol': 'http',
|
|
'auth_protocol': 'http',
|
|
}
|
|
|
|
|
|
class TestExternalPortContext(CharmTestCase):
|
|
def setUp(self):
|
|
super(TestExternalPortContext, self).setUp(quantum_contexts,
|
|
TO_PATCH)
|
|
|
|
def test_no_ext_port(self):
|
|
self.config.return_value = None
|
|
self.assertEquals(quantum_contexts.ExternalPortContext()(),
|
|
None)
|
|
|
|
def test_ext_port(self):
|
|
self.config.return_value = 'eth1010'
|
|
self.assertEquals(quantum_contexts.ExternalPortContext()(),
|
|
{'ext_port': 'eth1010'})
|
|
|
|
|
|
class TestQuantumGatewayContext(CharmTestCase):
|
|
def setUp(self):
|
|
super(TestQuantumGatewayContext, self).setUp(quantum_contexts,
|
|
TO_PATCH)
|
|
|
|
@patch.object(quantum_contexts, 'get_shared_secret')
|
|
@patch.object(quantum_contexts, 'get_host_ip')
|
|
def test_all(self, _host_ip, _secret):
|
|
self.config.return_value = 'ovs'
|
|
self.get_os_codename_install_source.return_value = 'folsom'
|
|
_host_ip.return_value = '10.5.0.1'
|
|
_secret.return_value = 'testsecret'
|
|
self.assertEquals(quantum_contexts.QuantumGatewayContext()(), {
|
|
'shared_secret': 'testsecret',
|
|
'local_ip': '10.5.0.1',
|
|
'core_plugin': "quantum.plugins.openvswitch.ovs_quantum_plugin."
|
|
"OVSQuantumPluginV2",
|
|
'plugin': 'ovs'
|
|
})
|
|
|
|
|
|
class TestSharedSecret(CharmTestCase):
|
|
def setUp(self):
|
|
super(TestSharedSecret, self).setUp(quantum_contexts,
|
|
TO_PATCH)
|
|
self.config.side_effect = self.test_config.get
|
|
|
|
@patch('os.path')
|
|
@patch('uuid.uuid4')
|
|
def test_secret_created_stored(self, _uuid4, _path):
|
|
_path.exists.return_value = False
|
|
_uuid4.return_value = 'secret_thing'
|
|
with patch_open() as (_open, _file):
|
|
self.assertEquals(quantum_contexts.get_shared_secret(),
|
|
'secret_thing')
|
|
_open.assert_called_with(
|
|
quantum_contexts.SHARED_SECRET.format('quantum'), 'w')
|
|
_file.write.assert_called_with('secret_thing')
|
|
|
|
@patch('os.path')
|
|
def test_secret_retrieved(self, _path):
|
|
_path.exists.return_value = True
|
|
with patch_open() as (_open, _file):
|
|
_file.read.return_value = 'secret_thing\n'
|
|
self.assertEquals(quantum_contexts.get_shared_secret(),
|
|
'secret_thing')
|
|
_open.assert_called_with(
|
|
quantum_contexts.SHARED_SECRET.format('quantum'), 'r')
|
|
|
|
|
|
class TestHostIP(CharmTestCase):
|
|
def setUp(self):
|
|
super(TestHostIP, self).setUp(quantum_contexts,
|
|
TO_PATCH)
|
|
self.config.side_effect = self.test_config.get
|
|
|
|
def test_get_host_ip_already_ip(self):
|
|
self.assertEquals(quantum_contexts.get_host_ip('10.5.0.1'),
|
|
'10.5.0.1')
|
|
|
|
def test_get_host_ip_noarg(self):
|
|
self.unit_get.return_value = "10.5.0.1"
|
|
self.assertEquals(quantum_contexts.get_host_ip(),
|
|
'10.5.0.1')
|
|
|
|
@patch('dns.resolver.query')
|
|
def test_get_host_ip_hostname_unresolvable(self, _query):
|
|
class NXDOMAIN(Exception):
|
|
pass
|
|
_query.side_effect = NXDOMAIN()
|
|
self.assertRaises(NXDOMAIN, quantum_contexts.get_host_ip,
|
|
'missing.example.com')
|
|
|
|
@patch('dns.resolver.query')
|
|
def test_get_host_ip_hostname_resolvable(self, _query):
|
|
data = MagicMock()
|
|
data.address = '10.5.0.1'
|
|
_query.return_value = [data]
|
|
self.assertEquals(quantum_contexts.get_host_ip('myhost.example.com'),
|
|
'10.5.0.1')
|
|
_query.assert_called_with('myhost.example.com', 'A')
|
|
|
|
|
|
class TestNetworkingName(CharmTestCase):
|
|
def setUp(self):
|
|
super(TestNetworkingName,
|
|
self).setUp(quantum_contexts,
|
|
TO_PATCH)
|
|
|
|
def test_lt_havana(self):
|
|
self.get_os_codename_install_source.return_value = 'folsom'
|
|
self.assertEquals(quantum_contexts.networking_name(), 'quantum')
|
|
|
|
def test_ge_havana(self):
|
|
self.get_os_codename_install_source.return_value = 'havana'
|
|
self.assertEquals(quantum_contexts.networking_name(), 'neutron')
|