']) )
self._assertExpectedHTTP(res.status_int,
c_exc.NexusConfigFailed)
**** CubicPower OpenStack Study ****
def test_get_seg_id_fail(self):
"""Test handling of a NetworkSegmentIDNotFound exception.
Test the Cisco NetworkSegmentIDNotFound exception by simulating
a return of None by the OVS DB get_network_binding method
during port creation.
"""
orig = ovs_db_v2.get_network_binding
def _return_none_if_nexus_caller(self, *args, **kwargs):
def _calling_func_name(offset=0):
"""Get name of the calling function 'offset' frames back."""
return inspect.stack()[1 + offset][3]
if (_calling_func_name(1) == '_get_segmentation_id' and
_calling_func_name(2) == '_invoke_nexus_for_net_create'):
return None
else:
return orig(self, *args, **kwargs)
with mock.patch.object(ovs_db_v2, 'get_network_binding',
new=_return_none_if_nexus_caller):
with self._create_port_res(do_delete=False) as res:
self._assertExpectedHTTP(res.status_int,
c_exc.NetworkSegmentIDNotFound)
**** CubicPower OpenStack Study ****
def _return_none_if_nexus_caller(self, *args, **kwargs):
def _calling_func_name(offset=0):
"""Get name of the calling function 'offset' frames back."""
return inspect.stack()[1 + offset][3]
if (_calling_func_name(1) == '_get_segmentation_id' and
_calling_func_name(2) == '_invoke_nexus_for_net_create'):
return None
else:
return orig(self, *args, **kwargs)
with mock.patch.object(ovs_db_v2, 'get_network_binding',
new=_return_none_if_nexus_caller):
with self._create_port_res(do_delete=False) as res:
self._assertExpectedHTTP(res.status_int,
c_exc.NetworkSegmentIDNotFound)
**** CubicPower OpenStack Study ****
def test_nexus_host_non_configured(self):
"""Test handling of a NexusComputeHostNotConfigured exception.
Test the Cisco NexusComputeHostNotConfigured exception by using
a fictitious host name during port creation.
"""
with self._create_port_res(do_delete=False,
host_id='fakehost') as res:
self._assertExpectedHTTP(res.status_int,
c_exc.NexusComputeHostNotConfigured)
**** CubicPower OpenStack Study ****
def _check_rollback_on_bind_failure(self,
vlan_deletion_expected,
vlan_untrunk_expected):
"""Test for proper rollback following add Nexus DB binding failure.
Test that the Cisco Nexus plugin correctly rolls back the vlan
configuration on the Nexus switch when add_nexusport_binding fails
within the plugin's create_port() method.
"""
inserted_exc = KeyError
with mock.patch.object(nexus_db_v2, 'add_nexusport_binding',
side_effect=inserted_exc):
with self._create_port_res(do_delete=False) as res:
# Confirm that the configuration sent to the Nexus
# switch includes deletion of the vlan (if expected)
# and untrunking of the vlan from the ethernet interface
# (if expected).
self.assertTrue(self._is_vlan_unconfigured(
vlan_deletion_expected=vlan_deletion_expected,
vlan_untrunk_expected=vlan_untrunk_expected))
self._assertExpectedHTTP(res.status_int, inserted_exc)
**** CubicPower OpenStack Study ****
def test_nexus_rollback_on_bind_failure_non_provider_vlan(self):
"""Test rollback upon DB binding failure for non-provider vlan."""
self._check_rollback_on_bind_failure(vlan_deletion_expected=True,
vlan_untrunk_expected=True)
**** CubicPower OpenStack Study ****
def test_nexus_rollback_on_bind_failure_prov_vlan_no_auto_create(self):
"""Test rollback on bind fail for prov vlan w auto-create disabled."""
with mock.patch.object(network_db_v2, 'is_provider_vlan',
return_value=True):
# Disable auto-create. This config change will be cleared based
# on cleanup scheduled in the CiscoNetworkPluginV2TestCase
# class' setUp() method.
cisco_config.CONF.set_override('provider_vlan_auto_create',
False, 'CISCO')
self._check_rollback_on_bind_failure(vlan_deletion_expected=False,
vlan_untrunk_expected=True)
**** CubicPower OpenStack Study ****
def test_nexus_rollback_on_bind_failure_prov_vlan_no_auto_trunk(self):
"""Test rollback on bind fail for prov vlan w auto-trunk disabled."""
with mock.patch.object(network_db_v2, 'is_provider_vlan',
return_value=True):
# Disable auto-trunk. This config change will be cleared
# based on post-test cleanup scheduled in the
# CiscoNetworkPluginV2TestCase class' setUp() method.
cisco_config.CONF.set_override('provider_vlan_auto_trunk',
False, 'CISCO')
self._check_rollback_on_bind_failure(vlan_deletion_expected=True,
vlan_untrunk_expected=False)
**** CubicPower OpenStack Study ****
def test_model_update_port_rollback(self):
"""Test for proper rollback for Cisco model layer update port failure.
Test that the vSwitch plugin port configuration is rolled back
(restored) by the Cisco plugin model layer when there is a
failure in the Nexus sub-plugin for an update port operation.
The update port operation simulates a port attachment scenario:
first a port is created with no instance (null device_id),
and then a port update is requested with a non-null device_id
to simulate the port attachment.
"""
with self.port(fmt=self.fmt, device_id='',
device_owner=DEVICE_OWNER) as orig_port:
inserted_exc = ValueError
with mock.patch.object(
virt_phy_sw_v2.VirtualPhysicalSwitchModelV2,
'_invoke_nexus_for_net_create',
side_effect=inserted_exc):
# Send an update port request including a non-null device ID
data = {'port': {'device_id': DEVICE_ID_2,
'device_owner': DEVICE_OWNER,
portbindings.HOST_ID: COMP_HOST_NAME}}
port_id = orig_port['port']['id']
req = self.new_update_request('ports', data, port_id)
res = req.get_response(self.api)
# Sanity check failure result code
self._assertExpectedHTTP(res.status_int, inserted_exc)
# Check that the port still has the original device ID
plugin = base_plugin.NeutronDbPluginV2()
ctx = context.get_admin_context()
db_port = plugin._get_port(ctx, port_id)
self.assertEqual(db_port['device_id'],
orig_port['port']['device_id'])
**** CubicPower OpenStack Study ****
def test_model_delete_port_rollback(self):
"""Test for proper rollback for OVS plugin delete port failure.
Test that the nexus port configuration is rolled back (restored)
by the Cisco model plugin when there is a failure in the OVS
plugin for a delete port operation.
"""
with self._create_port_res() as res:
# After port is created, we should have one binding for this
# vlan/nexus switch.
port = self.deserialize(self.fmt, res)
start_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START,
NEXUS_IP_ADDR)
self.assertEqual(len(start_rows), 1)
# Inject an exception in the OVS plugin delete_port
# processing, and attempt a port deletion.
inserted_exc = n_exc.Conflict
expected_http = base.FAULT_MAP[inserted_exc].code
with mock.patch.object(l3_db.L3_NAT_db_mixin,
'disassociate_floatingips',
side_effect=inserted_exc):
self._delete('ports', port['port']['id'],
expected_code=expected_http)
# Confirm that the Cisco model plugin has restored
# the nexus configuration for this port after deletion failure.
end_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START,
NEXUS_IP_ADDR)
self.assertEqual(start_rows, end_rows)
**** CubicPower OpenStack Study ****
def test_nexus_delete_port_rollback(self):
"""Test for proper rollback for nexus plugin delete port failure.
Test for rollback (i.e. restoration) of a VLAN entry in the
nexus database whenever the nexus plugin fails to reconfigure the
nexus switch during a delete_port operation.
"""
with self._create_port_res() as res:
port = self.deserialize(self.fmt, res)
# Check that there is only one binding in the nexus database
# for this VLAN/nexus switch.
start_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START,
NEXUS_IP_ADDR)
self.assertEqual(len(start_rows), 1)
# Simulate a Nexus switch configuration error during
# port deletion.
with self._patch_ncclient(
'manager.connect.return_value.edit_config.side_effect',
AttributeError):
self._delete('ports', port['port']['id'],
base.FAULT_MAP[c_exc.NexusConfigFailed].code)
# Confirm that the binding has been restored (rolled back).
end_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START,
NEXUS_IP_ADDR)
self.assertEqual(start_rows, end_rows)
**** CubicPower OpenStack Study ****
def test_model_update_port_attach(self):
"""Test the model for update_port in attaching to an instance.
Mock the routines that call into the plugin code, and make sure they
are called with correct arguments.
"""
with contextlib.nested(
self.port(),
mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2,
'_invoke_plugin_per_device'),
mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2,
'_invoke_nexus_for_net_create')
) as (port, invoke_plugin_per_device, invoke_nexus_for_net_create):
data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME,
'device_id': DEVICE_ID_1,
'device_owner': DEVICE_OWNER}}
req = self.new_update_request('ports', data, port['port']['id'])
# Note, due to mocking out the two model routines, response won't
# contain any useful data
req.get_response(self.api)
# Note that call_args_list is used instead of
# assert_called_once_with which requires exact match of arguments.
# This is because the mocked routines contain variable number of
# arguments and/or dynamic objects.
self.assertEqual(invoke_plugin_per_device.call_count, 1)
self.assertEqual(
invoke_plugin_per_device.call_args_list[0][0][0:2],
(const.VSWITCH_PLUGIN, 'update_port'))
self.assertEqual(invoke_nexus_for_net_create.call_count, 1)
self.assertEqual(
invoke_nexus_for_net_create.call_args_list[0][0][1:],
(port['port']['tenant_id'], port['port']['network_id'],
data['port']['device_id'],
data['port'][portbindings.HOST_ID],))
**** CubicPower OpenStack Study ****
def test_model_update_port_migrate(self):
"""Test the model for update_port in migrating an instance.
Mock the routines that call into the plugin code, and make sure they
are called with correct arguments.
"""
arg_list = (portbindings.HOST_ID,)
data = {portbindings.HOST_ID: COMP_HOST_NAME,
'device_id': DEVICE_ID_1,
'device_owner': DEVICE_OWNER}
with contextlib.nested(
self.port(arg_list=arg_list, **data),
mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2,
'_invoke_plugin_per_device'),
mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2,
'_invoke_nexus_for_net_create')
) as (port, invoke_plugin_per_device, invoke_nexus_for_net_create):
data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME_2}}
req = self.new_update_request('ports', data, port['port']['id'])
# Note, due to mocking out the two model routines, response won't
# contain any useful data
req.get_response(self.api)
# Note that call_args_list is used instead of
# assert_called_once_with which requires exact match of arguments.
# This is because the mocked routines contain variable number of
# arguments and/or dynamic objects.
self.assertEqual(invoke_plugin_per_device.call_count, 2)
self.assertEqual(
invoke_plugin_per_device.call_args_list[0][0][0:2],
(const.VSWITCH_PLUGIN, 'update_port'))
self.assertEqual(
invoke_plugin_per_device.call_args_list[1][0][0:2],
(const.NEXUS_PLUGIN, 'delete_port'))
self.assertEqual(invoke_nexus_for_net_create.call_count, 1)
self.assertEqual(
invoke_nexus_for_net_create.call_args_list[0][0][1:],
(port['port']['tenant_id'], port['port']['network_id'],
port['port']['device_id'],
data['port'][portbindings.HOST_ID],))
**** CubicPower OpenStack Study ****
def test_model_update_port_net_create_not_needed(self):
"""Test the model for update_port when no action is needed.
Mock the routines that call into the plugin code, and make sure that
VSWITCH plugin is called with correct arguments, while NEXUS plugin is
not called at all.
"""
arg_list = (portbindings.HOST_ID,)
data = {portbindings.HOST_ID: COMP_HOST_NAME,
'device_id': DEVICE_ID_1,
'device_owner': DEVICE_OWNER}
with contextlib.nested(
self.port(arg_list=arg_list, **data),
mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2,
'_invoke_plugin_per_device'),
mock.patch.object(virt_phy_sw_v2.VirtualPhysicalSwitchModelV2,
'_invoke_nexus_for_net_create')
) as (port, invoke_plugin_per_device, invoke_nexus_for_net_create):
data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME,
'device_id': DEVICE_ID_1,
'device_owner': DEVICE_OWNER}}
req = self.new_update_request('ports', data, port['port']['id'])
# Note, due to mocking out the two model routines, response won't
# contain any useful data
req.get_response(self.api)
# Note that call_args_list is used instead of
# assert_called_once_with which requires exact match of arguments.
# This is because the mocked routines contain variable number of
# arguments and/or dynamic objects.
self.assertEqual(invoke_plugin_per_device.call_count, 1)
self.assertEqual(
invoke_plugin_per_device.call_args_list[0][0][0:2],
(const.VSWITCH_PLUGIN, 'update_port'))
self.assertFalse(invoke_nexus_for_net_create.called)
**** CubicPower OpenStack Study ****
def verify_portbinding(self, host_id1, host_id2,
vlan, device_id, binding_port):
"""Verify a port binding entry in the DB is correct."""
self.assertEqual(host_id1, host_id2)
pb = nexus_db_v2.get_nexusvm_bindings(vlan, device_id)
self.assertEqual(len(pb), 1)
self.assertEqual(pb[0].port_id, binding_port)
self.assertEqual(pb[0].switch_ip, NEXUS_IP_ADDR)
**** CubicPower OpenStack Study ****
def test_db_update_port_attach(self):
"""Test DB for update_port in attaching to an instance.
Query DB for the port binding entry corresponding to the search key
(vlan, device_id), and make sure that it's bound to correct switch port
"""
with self.port() as port:
data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME,
'device_id': DEVICE_ID_1,
'device_owner': DEVICE_OWNER}}
req = self.new_update_request('ports', data, port['port']['id'])
res = self.deserialize(self.fmt, req.get_response(self.api))
ctx = context.get_admin_context()
net = self._show('networks', res['port']['network_id'],
neutron_context=ctx)['network']
self.assertTrue(attributes.is_attr_set(
net.get(provider.SEGMENTATION_ID)))
vlan = net[provider.SEGMENTATION_ID]
self.assertEqual(vlan, VLAN_START)
self.verify_portbinding(res['port'][portbindings.HOST_ID],
data['port'][portbindings.HOST_ID],
vlan,
data['port']['device_id'],
NEXUS_PORT_1)
**** CubicPower OpenStack Study ****
def test_db_update_port_migrate(self):
"""Test DB for update_port in migrating an instance.
Query DB for the port binding entry corresponding to the search key
(vlan, device_id), and make sure that it's bound to correct switch port
before and after the migration.
"""
arg_list = (portbindings.HOST_ID,)
data = {portbindings.HOST_ID: COMP_HOST_NAME,
'device_id': DEVICE_ID_1,
'device_owner': DEVICE_OWNER}
with self.port(arg_list=arg_list, **data) as port:
ctx = context.get_admin_context()
net = self._show('networks', port['port']['network_id'],
neutron_context=ctx)['network']
self.assertTrue(attributes.is_attr_set(
net.get(provider.SEGMENTATION_ID)))
vlan = net[provider.SEGMENTATION_ID]
self.assertEqual(vlan, VLAN_START)
self.verify_portbinding(port['port'][portbindings.HOST_ID],
data[portbindings.HOST_ID],
vlan,
data['device_id'],
NEXUS_PORT_1)
new_data = {'port': {portbindings.HOST_ID: COMP_HOST_NAME_2}}
req = self.new_update_request('ports',
new_data, port['port']['id'])
res = self.deserialize(self.fmt, req.get_response(self.api))
self.verify_portbinding(res['port'][portbindings.HOST_ID],
new_data['port'][portbindings.HOST_ID],
vlan,
data['device_id'],
NEXUS_PORT_2)
**** CubicPower OpenStack Study ****
def test_delete_ports_by_device_id_second_call_failure(self):
plugin_ref = self._get_plugin_ref()
self._test_delete_ports_by_device_id_second_call_failure(plugin_ref)
**** CubicPower OpenStack Study ****
def test_delete_ports_ignores_port_not_found(self):
plugin_ref = self._get_plugin_ref()
self._test_delete_ports_ignores_port_not_found(plugin_ref)
**** CubicPower OpenStack Study ****
class TestCiscoNetworksV2(CiscoNetworkPluginV2TestCase,
test_db_plugin.TestNetworksV2):
**** CubicPower OpenStack Study ****
def test_create_networks_bulk_emulated_plugin_failure(self):
real_has_attr = hasattr
def fakehasattr(item, attr):
if attr.endswith('__native_bulk_support'):
return False
return real_has_attr(item, attr)
plugin_ref = self._get_plugin_ref()
orig = plugin_ref.create_network
#ensures the API choose the emulation code path
with mock.patch('__builtin__.hasattr',
new=fakehasattr):
with mock.patch.object(plugin_ref,
'create_network') as patched_plugin:
def side_effect(*args, **kwargs):
return self._do_side_effect(patched_plugin, orig,
*args, **kwargs)
patched_plugin.side_effect = side_effect
res = self._create_network_bulk(self.fmt, 2, 'test', True)
LOG.debug("response is %s" % res)
# We expect an internal server error as we injected a fault
self._validate_behavior_on_bulk_failure(
res,
'networks',
wexc.HTTPInternalServerError.code)
**** CubicPower OpenStack Study ****
def fakehasattr(item, attr):
if attr.endswith('__native_bulk_support'):
return False
return real_has_attr(item, attr)
plugin_ref = self._get_plugin_ref()
orig = plugin_ref.create_network
#ensures the API choose the emulation code path
with mock.patch('__builtin__.hasattr',
new=fakehasattr):
with mock.patch.object(plugin_ref,
'create_network') as patched_plugin:
def side_effect(*args, **kwargs):
return self._do_side_effect(patched_plugin, orig,
*args, **kwargs)
patched_plugin.side_effect = side_effect
res = self._create_network_bulk(self.fmt, 2, 'test', True)
LOG.debug("response is %s" % res)
# We expect an internal server error as we injected a fault
self._validate_behavior_on_bulk_failure(
res,
'networks',
wexc.HTTPInternalServerError.code)
**** CubicPower OpenStack Study ****
def test_create_networks_bulk_native_plugin_failure(self):
if self._skip_native_bulk:
self.skipTest("Plugin does not support native bulk network create")
plugin_ref = self._get_plugin_ref()
orig = plugin_ref.create_network
with mock.patch.object(plugin_ref,
'create_network') as patched_plugin:
def side_effect(*args, **kwargs):
return self._do_side_effect(patched_plugin, orig,
*args, **kwargs)
patched_plugin.side_effect = side_effect
res = self._create_network_bulk(self.fmt, 2, 'test', True)
# We expect an internal server error as we injected a fault
self._validate_behavior_on_bulk_failure(
res,
'networks',
wexc.HTTPInternalServerError.code)
@contextlib.contextmanager
**** CubicPower OpenStack Study ****
def _provider_vlan_network(self, phys_net, segment_id, net_name):
provider_attrs = {provider.NETWORK_TYPE: 'vlan',
provider.PHYSICAL_NETWORK: phys_net,
provider.SEGMENTATION_ID: segment_id}
arg_list = tuple(provider_attrs.keys())
res = self._create_network(self.fmt, net_name, True,
arg_list=arg_list, **provider_attrs)
network = self.deserialize(self.fmt, res)['network']
yield network
req = self.new_delete_request('networks', network['id'])
req.get_response(self.api)
**** CubicPower OpenStack Study ****
def test_create_provider_vlan_network(self):
with self._provider_vlan_network(PHYS_NET, '1234',
'pvnet1') as network:
expected = [('name', 'pvnet1'),
('admin_state_up', True),
('status', 'ACTIVE'),
('shared', False),
(provider.NETWORK_TYPE, 'vlan'),
(provider.PHYSICAL_NETWORK, PHYS_NET),
(provider.SEGMENTATION_ID, 1234)]
for k, v in expected:
self.assertEqual(network[k], v)
self.assertTrue(network_db_v2.is_provider_network(network['id']))
**** CubicPower OpenStack Study ****
def test_delete_provider_vlan_network(self):
with self._provider_vlan_network(PHYS_NET, '1234',
'pvnet1') as network:
network_id = network['id']
# Provider network should now be deleted
self.assertFalse(network_db_v2.is_provider_network(network_id))
**** CubicPower OpenStack Study ****
class TestCiscoSubnetsV2(CiscoNetworkPluginV2TestCase,
test_db_plugin.TestSubnetsV2):
**** CubicPower OpenStack Study ****
def test_create_subnets_bulk_emulated_plugin_failure(self):
real_has_attr = hasattr
#ensures the API choose the emulation code path
def fakehasattr(item, attr):
if attr.endswith('__native_bulk_support'):
return False
return real_has_attr(item, attr)
with mock.patch('__builtin__.hasattr',
new=fakehasattr):
plugin_ref = self._get_plugin_ref()
orig = plugin_ref.create_subnet
with mock.patch.object(plugin_ref,
'create_subnet') as patched_plugin:
def side_effect(*args, **kwargs):
self._do_side_effect(patched_plugin, orig,
*args, **kwargs)
patched_plugin.side_effect = side_effect
with self.network() as net:
res = self._create_subnet_bulk(self.fmt, 2,
net['network']['id'],
'test')
# We expect an internal server error as we injected a fault
self._validate_behavior_on_bulk_failure(
res,
'subnets',
wexc.HTTPInternalServerError.code)
**** CubicPower OpenStack Study ****
def fakehasattr(item, attr):
if attr.endswith('__native_bulk_support'):
return False
return real_has_attr(item, attr)
with mock.patch('__builtin__.hasattr',
new=fakehasattr):
plugin_ref = self._get_plugin_ref()
orig = plugin_ref.create_subnet
with mock.patch.object(plugin_ref,
'create_subnet') as patched_plugin:
def side_effect(*args, **kwargs):
self._do_side_effect(patched_plugin, orig,
*args, **kwargs)
patched_plugin.side_effect = side_effect
with self.network() as net:
res = self._create_subnet_bulk(self.fmt, 2,
net['network']['id'],
'test')
# We expect an internal server error as we injected a fault
self._validate_behavior_on_bulk_failure(
res,
'subnets',
wexc.HTTPInternalServerError.code)
**** CubicPower OpenStack Study ****
def test_create_subnets_bulk_native_plugin_failure(self):
if self._skip_native_bulk:
self.skipTest("Plugin does not support native bulk subnet create")
plugin_ref = self._get_plugin_ref()
orig = plugin_ref.create_subnet
with mock.patch.object(plugin_ref,
'create_subnet') as patched_plugin:
def side_effect(*args, **kwargs):
return self._do_side_effect(patched_plugin, orig,
*args, **kwargs)
patched_plugin.side_effect = side_effect
with self.network() as net:
res = self._create_subnet_bulk(self.fmt, 2,
net['network']['id'],
'test')
# We expect an internal server error as we injected a fault
self._validate_behavior_on_bulk_failure(
res,
'subnets',
wexc.HTTPInternalServerError.code)
**** CubicPower OpenStack Study ****
class TestCiscoRouterInterfacesV2(CiscoNetworkPluginV2TestCase):
**** CubicPower OpenStack Study ****
def setUp(self):
"""Configure a log exception counter and an API extension manager."""
self.log_exc_count = 0
def _count_exception_logs(*args, **kwargs):
self.log_exc_count += 1
mock.patch.object(logging.LoggerAdapter, 'exception',
autospec=True,
side_effect=_count_exception_logs,
wraps=logging.LoggerAdapter.exception).start()
super(TestCiscoRouterInterfacesV2, self).setUp()
ext_mgr = extensions.PluginAwareExtensionManager.get_instance()
self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr)
@contextlib.contextmanager
**** CubicPower OpenStack Study ****
def _count_exception_logs(*args, **kwargs):
self.log_exc_count += 1
mock.patch.object(logging.LoggerAdapter, 'exception',
autospec=True,
side_effect=_count_exception_logs,
wraps=logging.LoggerAdapter.exception).start()
super(TestCiscoRouterInterfacesV2, self).setUp()
ext_mgr = extensions.PluginAwareExtensionManager.get_instance()
self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr)
@contextlib.contextmanager
**** CubicPower OpenStack Study ****
def _network_subnet_router(self):
"""Context mgr for creating/deleting a net, subnet, and router."""
with self.network() as network:
with self.subnet(network=network) as subnet:
data = {'router': {'tenant_id': 'test_tenant_id'}}
request = self.new_create_request('routers', data, self.fmt)
response = request.get_response(self.ext_api)
router = self.deserialize(self.fmt, response)
yield network, subnet, router
self._delete('routers', router['router']['id'])
@contextlib.contextmanager
**** CubicPower OpenStack Study ****
def _router_interface(self, router, subnet, **kwargs):
"""Create a router interface, yield the response, then delete it."""
interface_data = {}
if subnet:
interface_data['subnet_id'] = subnet['subnet']['id']
interface_data.update(kwargs)
request = self.new_action_request('routers', interface_data,
router['router']['id'],
'add_router_interface')
response = request.get_response(self.ext_api)
yield response
# If router interface was created successfully, delete it now.
if response.status_int == wexc.HTTPOk.code:
request = self.new_action_request('routers', interface_data,
router['router']['id'],
'remove_router_interface')
request.get_response(self.ext_api)
@contextlib.contextmanager
**** CubicPower OpenStack Study ****
def _network_subnet_router_interface(self, **kwargs):
"""Context mgr for create/deleting a net, subnet, router and intf."""
with self._network_subnet_router() as (network, subnet, router):
with self._router_interface(router, subnet,
**kwargs) as response:
yield response
**** CubicPower OpenStack Study ****
def test_port_list_filtered_by_router_id(self):
"""Test port list command filtered by router ID."""
with self._network_subnet_router() as (network, subnet, router):
with self._router_interface(router, subnet):
query_params = "device_id=%s" % router['router']['id']
req = self.new_list_request('ports', self.fmt, query_params)
res = self.deserialize(self.fmt, req.get_response(self.api))
self.assertEqual(len(res['ports']), 1)
self.assertEqual(res['ports'][0]['device_id'],
router['router']['id'])
self.assertFalse(self.log_exc_count)
**** CubicPower OpenStack Study ****
def test_add_remove_router_intf_with_nexus_l3_enabled(self):
"""Verifies proper add/remove intf operation with Nexus L3 enabled.
With 'nexus_l3_enable' configured to True, confirm that a switched
virtual interface (SVI) is created/deleted on the Nexus switch when
a virtual router interface is created/deleted.
"""
cisco_config.CONF.set_override('nexus_l3_enable', True, 'CISCO')
with self._network_subnet_router_interface():
self.assertTrue(self._is_in_last_nexus_cfg(
['interface', 'vlan', 'ip', 'address']))
# Clear list of calls made to mock ncclient
self.mock_ncclient.reset()
# Router interface is now deleted. Confirm that SVI
# has been deleted from the Nexus switch.
self.assertTrue(self._is_in_nexus_cfg(['no', 'interface', 'vlan']))
self.assertTrue(self._is_in_last_nexus_cfg(['no', 'vlan']))
**** CubicPower OpenStack Study ****
def test_add_remove_router_intf_with_nexus_l3_disabled(self):
"""Verifies proper add/remove intf operation with Nexus L3 disabled.
With 'nexus_l3_enable' configured to False, confirm that no changes
are made to the Nexus switch running configuration when a virtual
router interface is created and then deleted.
"""
cisco_config.CONF.set_override('nexus_l3_enable', False, 'CISCO')
with self._network_subnet_router_interface():
self.assertFalse(self.mock_ncclient.manager.connect.
return_value.edit_config.called)
**** CubicPower OpenStack Study ****
def test_create_svi_but_subnet_not_specified_exception(self):
"""Tests raising of SubnetNotSpecified exception.
Tests that a SubnetNotSpecified exception is raised when an
add_router_interface request is made for creating a switch virtual
interface (SVI), but the request does not specify a subnet.
"""
cisco_config.CONF.set_override('nexus_l3_enable', True, 'CISCO')
with self._network_subnet_router() as (network, subnet, router):
with self._router_interface(router, subnet=None) as response:
self._assertExpectedHTTP(response.status_int,
c_exc.SubnetNotSpecified)
**** CubicPower OpenStack Study ****
def test_create_svi_but_port_id_included_exception(self):
"""Tests raising of PortIdForNexusSvi exception.
Tests that a PortIdForNexusSvi exception is raised when an
add_router_interface request is made for creating a switch virtual
interface (SVI), but the request includes a virtual port ID.
"""
cisco_config.CONF.set_override('nexus_l3_enable', True, 'CISCO')
with self._network_subnet_router_interface(
port_id='my_port_id') as response:
self._assertExpectedHTTP(response.status_int,
c_exc.PortIdForNexusSvi)
**** CubicPower OpenStack Study ****
class TestCiscoPortsV2XML(TestCiscoPortsV2):
fmt = 'xml'
**** CubicPower OpenStack Study ****
class TestCiscoNetworksV2XML(TestCiscoNetworksV2):
fmt = 'xml'
**** CubicPower OpenStack Study ****
class TestCiscoSubnetsV2XML(TestCiscoSubnetsV2):
fmt = 'xml'
**** CubicPower OpenStack Study ****
class TestCiscoRouterInterfacesV2XML(TestCiscoRouterInterfacesV2):
fmt = 'xml'