Remove load-time mocking from unit tests

This patchset removes the load-time mocking necessary due to load-time
function calls in 'constants'.  The constants are changed to run-time
functions and and the lazy feature of restart_on_change is used, and the
harden disable for unit testing is switched on when needed.

Change-Id: I73e719ed082a7c8f9c477fd82094532bdbb8029b
This commit is contained in:
Alex Kavanagh 2019-08-23 16:48:48 +01:00
parent 5826826af5
commit 86b3e38a54
9 changed files with 438 additions and 373 deletions

View File

@ -54,9 +54,11 @@ NFG_LOG_RATE_LIMIT_MIN = 100
NFG_LOG_BURST_LIMIT_MIN = 25
def _get_availability_zone():
from neutron_utils import get_availability_zone as get_az
return get_az()
def get_availability_zone():
use_juju_az = config('customize-failure-domain')
juju_az = os.environ.get('JUJU_AVAILABILITY_ZONE')
return (juju_az if use_juju_az and juju_az
else config('default-availability-zone'))
def core_plugin():
@ -161,7 +163,7 @@ class NeutronGatewayContext(NeutronAPIContext):
'report_interval': api_settings['report_interval'],
'enable_metadata_network': config('enable-metadata-network'),
'enable_isolated_metadata': config('enable-isolated-metadata'),
'availability_zone': _get_availability_zone(),
'availability_zone': get_availability_zone(),
'enable_nfg_logging': api_settings['enable_nfg_logging'],
}

View File

@ -75,7 +75,23 @@ from neutron_utils import (
)
hooks = Hooks()
CONFIGS = register_configs()
# Note that CONFIGS is now set up via resolve_CONFIGS so that it is not a
# module load time constraint.
CONFIGS = None
def resolve_CONFIGS():
"""lazy function to resolve the CONFIGS so that it doesn't have to evaluate
at module load time. Note that it also returns the CONFIGS so that it can
be used in other, module loadtime, functions.
:returns: CONFIGS variable
:rtype: `:class:templating.OSConfigRenderer`
"""
global CONFIGS
if CONFIGS is None:
CONFIGS = register_configs()
return CONFIGS
@hooks.hook('install')
@ -111,10 +127,9 @@ def install():
@hooks.hook('config-changed')
@restart_on_change(restart_map())
@restart_on_change(restart_map)
@harden()
def config_changed():
global CONFIGS
if not config('action-managed-upgrade'):
if openstack_upgrade_available(NEUTRON_COMMON):
status_set('maintenance', 'Running openstack upgrade')
@ -191,7 +206,7 @@ def amqp_joined(relation_id=None):
@hooks.hook('amqp-nova-relation-departed')
@hooks.hook('amqp-nova-relation-changed')
@restart_on_change(restart_map())
@restart_on_change(restart_map)
def amqp_nova_changed():
if 'amqp-nova' not in CONFIGS.complete_contexts():
log('amqp relation incomplete. Peer not ready?')
@ -200,7 +215,7 @@ def amqp_nova_changed():
@hooks.hook('amqp-relation-departed')
@restart_on_change(restart_map())
@restart_on_change(restart_map)
def amqp_departed():
if 'amqp' not in CONFIGS.complete_contexts():
log('amqp relation incomplete. Peer not ready?')
@ -211,13 +226,13 @@ def amqp_departed():
@hooks.hook('amqp-relation-changed',
'cluster-relation-changed',
'cluster-relation-joined')
@restart_on_change(restart_map())
@restart_on_change(restart_map)
def amqp_changed():
CONFIGS.write_all()
@hooks.hook('neutron-plugin-api-relation-changed')
@restart_on_change(restart_map())
@restart_on_change(restart_map)
def neutron_plugin_api_changed():
if use_l3ha():
apt_update()
@ -226,7 +241,7 @@ def neutron_plugin_api_changed():
@hooks.hook('quantum-network-service-relation-changed')
@restart_on_change(restart_map())
@restart_on_change(restart_map)
def nm_changed():
CONFIGS.write_all()
if relation_get('ca_cert'):
@ -255,7 +270,7 @@ def nm_changed():
@hooks.hook("cluster-relation-departed")
@restart_on_change(restart_map())
@restart_on_change(restart_map)
def cluster_departed():
if config('plugin') in ['nvp', 'nsx']:
log('Unable to re-assign agent resources for'
@ -357,9 +372,14 @@ def post_series_upgrade():
resume_unit_helper, CONFIGS)
if __name__ == '__main__':
def main():
try:
hooks.execute(sys.argv)
except UnregisteredHookError as e:
log('Unknown hook {} - skipping.'.format(e))
assess_status(CONFIGS)
if __name__ == '__main__':
resolve_CONFIGS()
main()

View File

@ -342,235 +342,257 @@ NOVA_CONF_DIR = '/etc/nova'
NOVA_CONF = "/etc/nova/nova.conf"
VENDORDATA_FILE = '%s/vendor_data.json' % NOVA_CONF_DIR
NOVA_CONFIG_FILES = {
NOVA_CONF: {
'hook_contexts': [NetworkServiceContext(),
NeutronGatewayContext(),
SyslogContext(),
context.WorkerConfigContext(),
context.ZeroMQContext(),
context.NotificationDriverContext(),
NovaMetadataContext()],
'services': ['nova-api-metadata']
},
NOVA_API_METADATA_AA_PROFILE_PATH: {
'services': ['nova-api-metadata'],
'hook_contexts': [
context.AppArmorContext(NOVA_API_METADATA_AA_PROFILE)
],
},
VENDORDATA_FILE: {
'services': [],
'hook_contexts': [NovaMetadataJSONContext('neutron-common')],
},
}
__NOVA_CONFIG_FILES = None
__CONFIG_FILES = None
NEUTRON_SHARED_CONFIG_FILES = {
NEUTRON_DHCP_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-dhcp-agent']
},
NEUTRON_DNSMASQ_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-dhcp-agent']
},
NEUTRON_METADATA_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
context.WorkerConfigContext(),
NeutronGatewayContext(),
NovaMetadataContext()],
'services': ['neutron-metadata-agent']
},
NEUTRON_DHCP_AA_PROFILE_PATH: {
'services': ['neutron-dhcp-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_DHCP_AA_PROFILE)
],
},
NEUTRON_LBAAS_AA_PROFILE_PATH: {
'services': ['neutron-lbaas-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_LBAAS_AA_PROFILE)
],
},
NEUTRON_LBAASV2_AA_PROFILE_PATH: {
'services': ['neutron-lbaasv2-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_LBAASV2_AA_PROFILE)
],
},
NEUTRON_METADATA_AA_PROFILE_PATH: {
'services': ['neutron-metadata-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_METADATA_AA_PROFILE)
],
},
NEUTRON_METERING_AA_PROFILE_PATH: {
'services': ['neutron-metering-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_METERING_AA_PROFILE)
],
},
}
NEUTRON_SHARED_CONFIG_FILES.update(NOVA_CONFIG_FILES)
NEUTRON_OVS_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
SyslogContext(),
context.ZeroMQContext(),
context.WorkerConfigContext(),
context.NotificationDriverContext()],
'services': ['neutron-l3-agent',
'neutron-dhcp-agent',
'neutron-metadata-agent',
'neutron-plugin-openvswitch-agent',
'neutron-plugin-metering-agent',
'neutron-metering-agent',
'neutron-lbaas-agent',
'neutron-vpn-agent']
},
NEUTRON_L3_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
L3AgentContext(),
NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
NEUTRON_METERING_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-metering-agent',
'neutron-metering-agent']
},
NEUTRON_LBAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-lbaas-agent']
},
NEUTRON_VPNAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-vpn-agent']
},
NEUTRON_FWAAS_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
NEUTRON_ML2_PLUGIN_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-openvswitch-agent']
},
NEUTRON_OVS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-openvswitch-agent']
},
NEUTRON_OVS_AA_PROFILE_PATH: {
'services': ['neutron-plugin-openvswitch-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_OVS_AA_PROFILE)
],
},
NEUTRON_L3_AA_PROFILE_PATH: {
'services': ['neutron-l3-agent', 'neutron-vpn-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_L3_AA_PROFILE)
],
},
EXT_PORT_CONF: {
'hook_contexts': [ExternalPortContext()],
'services': ['ext-port']
},
PHY_NIC_MTU_CONF: {
'hook_contexts': [PhyNICMTUContext()],
'services': ['os-charm-phy-nic-mtu']
def get_nova_config_files():
global __NOVA_CONFIG_FILES
if __NOVA_CONFIG_FILES is not None:
return __NOVA_CONFIG_FILES
NOVA_CONFIG_FILES = {
NOVA_CONF: {
'hook_contexts': [NetworkServiceContext(),
NeutronGatewayContext(),
SyslogContext(),
context.WorkerConfigContext(),
context.ZeroMQContext(),
context.NotificationDriverContext(),
NovaMetadataContext()],
'services': ['nova-api-metadata']
},
NOVA_API_METADATA_AA_PROFILE_PATH: {
'services': ['nova-api-metadata'],
'hook_contexts': [
context.AppArmorContext(NOVA_API_METADATA_AA_PROFILE)
],
},
VENDORDATA_FILE: {
'services': [],
'hook_contexts': [NovaMetadataJSONContext('neutron-common')],
},
}
}
NEUTRON_OVS_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
NEUTRON_OVS_ODL_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
SyslogContext(),
context.ZeroMQContext(),
context.WorkerConfigContext(),
context.NotificationDriverContext()],
'services': ['neutron-l3-agent',
'neutron-dhcp-agent',
'neutron-metadata-agent',
'neutron-plugin-metering-agent',
'neutron-metering-agent',
'neutron-lbaas-agent',
'neutron-vpn-agent']
},
NEUTRON_L3_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
L3AgentContext(),
NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
NEUTRON_METERING_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-metering-agent',
'neutron-metering-agent']
},
NEUTRON_LBAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-lbaas-agent']
},
NEUTRON_VPNAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-vpn-agent']
},
NEUTRON_FWAAS_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
EXT_PORT_CONF: {
'hook_contexts': [ExternalPortContext()],
'services': ['ext-port']
},
PHY_NIC_MTU_CONF: {
'hook_contexts': [PhyNICMTUContext()],
'services': ['os-charm-phy-nic-mtu']
return NOVA_CONFIG_FILES
def get_config_files():
global __CONFIG_FILES
if __CONFIG_FILES is not None:
return __CONFIG_FILES
NOVA_CONFIG_FILES = get_nova_config_files()
NEUTRON_SHARED_CONFIG_FILES = {
NEUTRON_DHCP_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-dhcp-agent']
},
NEUTRON_DNSMASQ_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-dhcp-agent']
},
NEUTRON_METADATA_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
context.WorkerConfigContext(),
NeutronGatewayContext(),
NovaMetadataContext()],
'services': ['neutron-metadata-agent']
},
NEUTRON_DHCP_AA_PROFILE_PATH: {
'services': ['neutron-dhcp-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_DHCP_AA_PROFILE)
],
},
NEUTRON_LBAAS_AA_PROFILE_PATH: {
'services': ['neutron-lbaas-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_LBAAS_AA_PROFILE)
],
},
NEUTRON_LBAASV2_AA_PROFILE_PATH: {
'services': ['neutron-lbaasv2-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_LBAASV2_AA_PROFILE)
],
},
NEUTRON_METADATA_AA_PROFILE_PATH: {
'services': ['neutron-metadata-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_METADATA_AA_PROFILE)
],
},
NEUTRON_METERING_AA_PROFILE_PATH: {
'services': ['neutron-metering-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_METERING_AA_PROFILE)
],
},
}
}
NEUTRON_OVS_ODL_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
NEUTRON_SHARED_CONFIG_FILES.update(NOVA_CONFIG_FILES)
NEUTRON_NSX_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
context.WorkerConfigContext(),
SyslogContext()],
'services': ['neutron-dhcp-agent', 'neutron-metadata-agent']
},
}
NEUTRON_NSX_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
NEUTRON_OVS_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
SyslogContext(),
context.ZeroMQContext(),
context.WorkerConfigContext(),
context.NotificationDriverContext()],
'services': ['neutron-l3-agent',
'neutron-dhcp-agent',
'neutron-metadata-agent',
'neutron-plugin-openvswitch-agent',
'neutron-plugin-metering-agent',
'neutron-metering-agent',
'neutron-lbaas-agent',
'neutron-vpn-agent']
},
NEUTRON_L3_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
L3AgentContext(),
NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
NEUTRON_METERING_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-metering-agent',
'neutron-metering-agent']
},
NEUTRON_LBAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-lbaas-agent']
},
NEUTRON_VPNAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-vpn-agent']
},
NEUTRON_FWAAS_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
NEUTRON_ML2_PLUGIN_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-openvswitch-agent']
},
NEUTRON_OVS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-openvswitch-agent']
},
NEUTRON_OVS_AA_PROFILE_PATH: {
'services': ['neutron-plugin-openvswitch-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_OVS_AA_PROFILE)
],
},
NEUTRON_L3_AA_PROFILE_PATH: {
'services': ['neutron-l3-agent', 'neutron-vpn-agent'],
'hook_contexts': [
context.AppArmorContext(NEUTRON_L3_AA_PROFILE)
],
},
EXT_PORT_CONF: {
'hook_contexts': [ExternalPortContext()],
'services': ['ext-port']
},
PHY_NIC_MTU_CONF: {
'hook_contexts': [PhyNICMTUContext()],
'services': ['os-charm-phy-nic-mtu']
}
}
NEUTRON_OVS_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
NEUTRON_N1KV_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
context.WorkerConfigContext(),
SyslogContext()],
'services': ['neutron-l3-agent',
'neutron-dhcp-agent',
'neutron-metadata-agent']
},
NEUTRON_L3_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
L3AgentContext(),
NeutronGatewayContext()],
'services': ['neutron-l3-agent']
},
}
NEUTRON_N1KV_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
NEUTRON_OVS_ODL_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
SyslogContext(),
context.ZeroMQContext(),
context.WorkerConfigContext(),
context.NotificationDriverContext()],
'services': ['neutron-l3-agent',
'neutron-dhcp-agent',
'neutron-metadata-agent',
'neutron-plugin-metering-agent',
'neutron-metering-agent',
'neutron-lbaas-agent',
'neutron-vpn-agent']
},
NEUTRON_L3_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
L3AgentContext(),
NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
NEUTRON_METERING_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-plugin-metering-agent',
'neutron-metering-agent']
},
NEUTRON_LBAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-lbaas-agent']
},
NEUTRON_VPNAAS_AGENT_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-vpn-agent']
},
NEUTRON_FWAAS_CONF: {
'hook_contexts': [NeutronGatewayContext()],
'services': ['neutron-l3-agent', 'neutron-vpn-agent']
},
EXT_PORT_CONF: {
'hook_contexts': [ExternalPortContext()],
'services': ['ext-port']
},
PHY_NIC_MTU_CONF: {
'hook_contexts': [PhyNICMTUContext()],
'services': ['os-charm-phy-nic-mtu']
}
}
NEUTRON_OVS_ODL_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
NEUTRON_NSX_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
context.WorkerConfigContext(),
SyslogContext()],
'services': ['neutron-dhcp-agent', 'neutron-metadata-agent']
},
}
NEUTRON_NSX_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
NEUTRON_N1KV_CONFIG_FILES = {
NEUTRON_CONF: {
'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
NeutronGatewayContext(),
context.WorkerConfigContext(),
SyslogContext()],
'services': ['neutron-l3-agent',
'neutron-dhcp-agent',
'neutron-metadata-agent']
},
NEUTRON_L3_AGENT_CONF: {
'hook_contexts': [NetworkServiceContext(),
L3AgentContext(),
NeutronGatewayContext()],
'services': ['neutron-l3-agent']
},
}
NEUTRON_N1KV_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES)
__CONFIG_FILES = {
NSX: NEUTRON_NSX_CONFIG_FILES,
OVS: NEUTRON_OVS_CONFIG_FILES,
N1KV: NEUTRON_N1KV_CONFIG_FILES,
OVS_ODL: NEUTRON_OVS_ODL_CONFIG_FILES
}
return __CONFIG_FILES
CONFIG_FILES = {
NSX: NEUTRON_NSX_CONFIG_FILES,
OVS: NEUTRON_OVS_CONFIG_FILES,
N1KV: NEUTRON_N1KV_CONFIG_FILES,
OVS_ODL: NEUTRON_OVS_ODL_CONFIG_FILES
}
SERVICE_RENAMES = {
'icehouse': {
@ -626,7 +648,7 @@ def resolve_config_files(plugin, release):
:returns: dict of configuration files, contexts
and associated services
'''
config_files = deepcopy(CONFIG_FILES)
config_files = deepcopy(get_config_files())
drop_config = []
cmp_os_release = CompareOpenStackReleases(release)
if plugin == OVS:
@ -647,7 +669,7 @@ def resolve_config_files(plugin, release):
drop_config.extend([NEUTRON_LBAAS_AA_PROFILE_PATH])
if disable_nova_metadata(cmp_os_release):
drop_config.extend(NOVA_CONFIG_FILES.keys())
drop_config.extend(get_nova_config_files().keys())
else:
if is_relation_made('amqp-nova'):
amqp_nova_ctxt = context.AMQPContext(
@ -880,7 +902,7 @@ def remove_legacy_nova_metadata():
service_stop(service_name)
service('disable', service_name)
service('mask', service_name)
for f in NOVA_CONFIG_FILES.keys():
for f in get_nova_config_files().keys():
remove_file(f)
@ -1073,10 +1095,3 @@ def configure_apparmor():
profiles.append(NEUTRON_LBAASV2_AA_PROFILE)
for profile in profiles:
context.AppArmorContext(profile).setup_aa_profile()
def get_availability_zone():
use_juju_az = config('customize-failure-domain')
juju_az = os.environ.get('JUJU_AVAILABILITY_ZONE')
return (juju_az if use_juju_az and juju_az
else config('default-availability-zone'))

View File

@ -1,6 +1,6 @@
import sys
import mock
from mock import patch, MagicMock
from mock import MagicMock
from test_utils import CharmTestCase
@ -9,24 +9,20 @@ from test_utils import CharmTestCase
sys.modules['apt'] = MagicMock()
sys.modules['apt_pkg'] = MagicMock()
with patch('charmhelpers.core.hookenv.config'):
with patch('neutron_utils.restart_map'):
with patch('neutron_utils.register_configs') as configs:
with patch('charmhelpers.contrib.hardening.harden.harden') as \
mock_dec:
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
lambda *args, **kwargs:
f(*args, **kwargs))
with patch('charmhelpers.core.hookenv.status_set'):
configs.return_value = 'test-config'
import actions
import actions
class PauseTestCase(CharmTestCase):
def setUp(self):
super(PauseTestCase, self).setUp(
actions, ["pause_unit_helper"])
actions, ["pause_unit_helper",
"charmhelpers.core.hookenv.log",
"charmhelpers.core.hookenv.status_set",
"charmhelpers.core.hookenv.config"])
self.patch_object(None, "actions.register_configs",
name="register_configs",
return_value='test-config')
def test_pauses_services(self):
actions.pause([])
@ -37,9 +33,15 @@ class ResumeTestCase(CharmTestCase):
def setUp(self):
super(ResumeTestCase, self).setUp(
actions, ["resume_unit_helper"])
actions, ["resume_unit_helper",
"charmhelpers.core.hookenv.log",
"charmhelpers.core.hookenv.status_set",
"charmhelpers.core.hookenv.config"])
self.patch_object(None, "actions.register_configs",
name="register_configs",
return_value='test-config')
def test_pauses_services(self):
def test_resumes_services(self):
actions.resume([])
self.resume_unit_helper.assert_called_once_with('test-config')

View File

@ -7,14 +7,13 @@ from test_utils import (
os.environ['JUJU_UNIT_NAME'] = 'neutron-gateway'
with patch('charmhelpers.core.hookenv.config'):
with patch('neutron_utils.restart_map'):
with patch('neutron_utils.register_configs'):
import openstack_upgrade
import openstack_upgrade
TO_PATCH = [
'do_openstack_upgrade',
'config_changed',
'charmhelpers.core.hookenv.log',
'charmhelpers.contrib.openstack.utils.juju_log',
]

View File

@ -1,4 +1,3 @@
import io
from contextlib import contextmanager
@ -19,6 +18,7 @@ TO_PATCH = [
'unit_get',
'network_get_primary_address',
'os_release',
'charmhelpers.contrib.network.ip.log',
]
@ -157,12 +157,11 @@ class TestNeutronGatewayContext(CharmTestCase):
self.maxDiff = None
@patch.object(neutron_contexts, 'validate_nfg_log_path', lambda x: x)
@patch('neutron_utils.config')
@patch('charmhelpers.contrib.openstack.context.relation_get')
@patch('charmhelpers.contrib.openstack.context.related_units')
@patch('charmhelpers.contrib.openstack.context.relation_ids')
@patch.object(neutron_contexts, 'get_shared_secret')
def test_all(self, _secret, _rids, _runits, _rget, mock_config):
def test_all(self, _secret, _rids, _runits, _rget):
rdata = {'l2-population': 'True',
'enable-dvr': 'True',
'overlay-network-type': 'gre',
@ -186,12 +185,8 @@ class TestNeutronGatewayContext(CharmTestCase):
self.test_config.set('firewall-group-log-rate-limit', 100)
self.test_config.set('firewall-group-log-burst-limit', 50)
def config_side_effect(key):
return {
'customize-failure-domain': False,
'default-availability-zone': 'nova',
}[key]
mock_config.side_effect = config_side_effect
self.test_config.set('customize-failure-domain', False)
self.test_config.set('default-availability-zone', 'nova')
self.network_get_primary_address.side_effect = NotImplementedError
self.unit_get.return_value = '10.5.0.1'
@ -237,13 +232,11 @@ class TestNeutronGatewayContext(CharmTestCase):
})
@patch.object(neutron_contexts, 'validate_nfg_log_path', lambda x: x)
@patch('neutron_utils.config')
@patch('charmhelpers.contrib.openstack.context.relation_get')
@patch('charmhelpers.contrib.openstack.context.related_units')
@patch('charmhelpers.contrib.openstack.context.relation_ids')
@patch.object(neutron_contexts, 'get_shared_secret')
def test_all_network_spaces(self, _secret, _rids, _runits, _rget,
mock_config):
def test_all_network_spaces(self, _secret, _rids, _runits, _rget):
rdata = {'l2-population': 'True',
'enable-dvr': 'True',
'overlay-network-type': 'gre',
@ -261,12 +254,8 @@ class TestNeutronGatewayContext(CharmTestCase):
'physnet1:1000:2000 physnet2:2001:3000')
self.test_config.set('flat-network-providers', 'physnet3 physnet4')
def config_side_effect(key):
return {
'customize-failure-domain': False,
'default-availability-zone': 'nova',
}[key]
mock_config.side_effect = config_side_effect
self.test_config.set('customize-failure-domain', False)
self.test_config.set('default-availability-zone', 'nova')
self.network_get_primary_address.return_value = '192.168.20.2'
self.unit_get.return_value = '10.5.0.1'
@ -338,7 +327,6 @@ class TestNeutronGatewayContext(CharmTestCase):
self.assertTrue(ctxt['enable_isolated_metadata'])
self.assertTrue(ctxt['enable_metadata_network'])
@patch('neutron_utils.config')
@patch('os.environ.get')
@patch('charmhelpers.contrib.openstack.context.relation_get')
@patch('charmhelpers.contrib.openstack.context.related_units')
@ -346,8 +334,7 @@ class TestNeutronGatewayContext(CharmTestCase):
@patch.object(neutron_contexts, 'get_shared_secret')
def test_availability_zone_no_juju_with_env(self, _secret, _rids,
_runits, _rget,
mock_get,
mock_config):
mock_get):
def environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': 'az1',
@ -355,13 +342,9 @@ class TestNeutronGatewayContext(CharmTestCase):
}[key]
mock_get.side_effect = environ_get_side_effect
def config_side_effect(key):
return {
'customize-failure-domain': False,
'default-availability-zone': 'nova',
}[key]
self.test_config.set('customize-failure-domain', False)
self.test_config.set('default-availability-zone', 'nova')
mock_config.side_effect = config_side_effect
context = neutron_contexts.NeutronGatewayContext()
self.assertEqual(
'nova', context()['availability_zone'])
@ -593,3 +576,65 @@ class TestNovaMetadataContext(CharmTestCase):
'nova_metadata_port': '8775',
'nova_metadata_protocol': 'http',
'shared_secret': 'buuid'})
class TestGetAvailabilityZone(CharmTestCase):
def setUp(self):
super(TestGetAvailabilityZone, self).setUp(neutron_contexts, TO_PATCH)
@patch.object(neutron_contexts.os.environ, 'get')
def test_get_az_customize_with_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', True)
self.test_config.set('default-availability-zone', 'nova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': 'az1',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_contexts.get_availability_zone()
self.assertEqual('az1', az)
@patch.object(neutron_contexts.os.environ, 'get')
def test_get_az_customize_without_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', True)
self.test_config.set('default-availability-zone', 'mynova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': '',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_contexts.get_availability_zone()
self.assertEqual('mynova', az)
@patch.object(neutron_contexts.os.environ, 'get')
def test_get_az_no_customize_without_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', False)
self.test_config.set('default-availability-zone', 'nova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': '',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_contexts.get_availability_zone()
self.assertEqual('nova', az)
@patch.object(neutron_contexts.os.environ, 'get')
def test_get_az_no_customize_with_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', False)
self.test_config.set('default-availability-zone', 'nova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': 'az1',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_contexts.get_availability_zone()
self.assertEqual('nova', az)

View File

@ -8,15 +8,9 @@ sys.modules['apt'] = MagicMock()
sys.modules['apt_pkg'] = MagicMock()
import charmhelpers.core.hookenv as hookenv
with patch('charmhelpers.core.hookenv.config'):
with patch('neutron_utils.restart_map'):
with patch('neutron_utils.register_configs'):
with patch('charmhelpers.contrib.'
'hardening.harden.harden') as mock_dec:
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
lambda *args, **kwargs:
f(*args, **kwargs))
import neutron_hooks as hooks
import charmhelpers.contrib.hardening.harden as harden
import neutron_hooks as hooks
from test_utils import CharmTestCase
@ -56,7 +50,6 @@ TO_PATCH = [
'use_l3ha',
'kv',
'service_restart',
'is_unit_paused_set',
'install_systemd_override',
'configure_apparmor',
'disable_nova_metadata',
@ -64,6 +57,7 @@ TO_PATCH = [
'services',
'remove_old_packages',
'is_container',
'charmhelpers.contrib.openstack.utils.is_unit_paused_set',
]
@ -80,6 +74,8 @@ class TestQuantumHooks(CharmTestCase):
self.is_container.return_value = False
hookenv.config.side_effect = self.test_config.get
hooks.hooks._config_save = False
harden._DISABLE_HARDENING_FOR_UNIT_TEST = True
self.is_unit_paused_set.return_value = True
def _call_hook(self, hookname):
hooks.hooks.execute([
@ -264,9 +260,23 @@ class TestQuantumHooks(CharmTestCase):
self.assertTrue(self.CONFIGS.write_all.called)
self.install_ca_cert.assert_called_with('cert')
def test_nm_changed_restart_nonce(self):
@patch("neutron_utils.get_packages")
@patch("neutron_utils.resolve_config_files")
@patch("neutron_utils.config")
@patch("neutron_utils.os_release")
def test_nm_changed_restart_nonce(self,
mock_os_release,
mock_config,
mock_resolve_config_files,
mock_get_packages):
'''Ensure first set of restart_trigger restarts nova-api-metadata'''
self.disable_nova_metadata.return_value = False
# as restart_map is embedded into the decorator, we have to mock out
# the bits in the restart_map to be able to make it pass.
mock_os_release.return_value = 'mitaka'
mock_config.return_value = 'ovs'
mock_resolve_config_files.return_value = {'ovs': {}}
mock_get_packages.return_value = []
def _relation_get(key):
data = {
@ -288,9 +298,23 @@ class TestQuantumHooks(CharmTestCase):
'1111111222222333333')
self.assertTrue(kv_mock.flush.called)
def test_nm_changed_restart_nonce_changed(self):
@patch("neutron_utils.get_packages")
@patch("neutron_utils.resolve_config_files")
@patch("neutron_utils.config")
@patch("neutron_utils.os_release")
def test_nm_changed_restart_nonce_changed(self,
mock_os_release,
mock_config,
mock_resolve_config_files,
mock_get_packages):
'''Ensure change of restart_trigger restarts nova-api-metadata'''
self.disable_nova_metadata.return_value = False
# as restart_map is embedded into the decorator, we have to mock out
# the bits in the restart_map to be able to make it pass.
mock_os_release.return_value = 'mitaka'
mock_config.return_value = 'ovs'
mock_resolve_config_files.return_value = {'ovs': {}}
mock_get_packages.return_value = []
def _relation_get(key):
data = {
@ -312,10 +336,24 @@ class TestQuantumHooks(CharmTestCase):
'1111111222222333333')
self.assertTrue(kv_mock.flush.called)
def test_nm_changed_restart_nonce_nochange(self):
@patch("neutron_utils.get_packages")
@patch("neutron_utils.resolve_config_files")
@patch("neutron_utils.config")
@patch("neutron_utils.os_release")
def test_nm_changed_restart_nonce_nochange(self,
mock_os_release,
mock_config,
mock_resolve_config_files,
mock_get_packages):
'''Ensure no change in restart_trigger skips restarts'''
self.patch_object(hooks, 'disable_nova_metadata',
return_value=False)
# as restart_map is embedded into the decorator, we have to mock out
# the bits in the restart_map to be able to make it pass.
mock_os_release.return_value = 'mitaka'
mock_config.return_value = 'ovs'
mock_resolve_config_files.return_value = {'ovs': {}}
mock_get_packages.return_value = []
def _relation_get(key):
data = {

View File

@ -851,72 +851,6 @@ class TestNeutronUtils(CharmTestCase):
for config in EXC_CONFIG:
self.assertTrue(config not in actual_configs)
@patch.object(neutron_utils.os.environ, 'get')
def test_get_az_customize_with_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', True)
self.test_config.set('default-availability-zone', 'nova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': 'az1',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_utils.get_availability_zone()
self.assertEqual('az1', az)
@patch.object(neutron_utils.os.environ, 'get')
def test_get_az_customize_without_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', True)
self.test_config.set('default-availability-zone', 'mynova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': '',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_utils.get_availability_zone()
self.assertEqual('mynova', az)
@patch.object(neutron_utils.os.environ, 'get')
def test_get_az_no_customize_without_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', False)
self.test_config.set('default-availability-zone', 'nova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': '',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_utils.get_availability_zone()
self.assertEqual('nova', az)
@patch.object(neutron_utils.os.environ, 'get')
def test_get_az_no_customize_with_env(self, os_environ_get_mock):
self.config.side_effect = self.test_config.get
self.test_config.set('customize-failure-domain', False)
self.test_config.set('default-availability-zone', 'nova')
def os_environ_get_side_effect(key):
return {
'JUJU_AVAILABILITY_ZONE': 'az1',
}[key]
os_environ_get_mock.side_effect = os_environ_get_side_effect
az = neutron_utils.get_availability_zone()
self.assertEqual('nova', az)
network_context = {
'service_username': 'foo',
'service_password': 'bar',
'service_tenant': 'baz',
'region': 'foo-bar',
'keystone_host': 'keystone',
'auth_port': 5000,
'auth_protocol': 'https'
}
class DummyNetworkServiceContext():

View File

@ -57,14 +57,21 @@ class CharmTestCase(unittest.TestCase):
self._patches_start = {}
def patch(self, method):
_m = patch.object(self.obj, method)
if "." in method:
_m = patch(method)
else:
_m = patch.object(self.obj, method)
mock = _m.start()
self.addCleanup(_m.stop)
return mock
def patch_all(self):
for method in self.patches:
setattr(self, method, self.patch(method))
if "." in method:
attr = method.split('.')[-1]
else:
attr = method
setattr(self, attr, self.patch(method))
def tearDown(self):
for k, v in self._patches.items():
@ -85,7 +92,10 @@ class CharmTestCase(unittest.TestCase):
:param name: optional <string> name to call the mock.
:param **kwargs: any other args to pass to mock.patch()
"""
mocked = patch.object(obj, attr, **kwargs)
if obj is None:
mocked = patch(attr, **kwargs)
else:
mocked = patch.object(obj, attr, **kwargs)
if name is None:
name = attr
started = mocked.start()