diff --git a/vmware_nsx/tests/unit/dvs/test_plugin.py b/vmware_nsx/tests/unit/dvs/test_plugin.py index 97c10c0712..2921ec8aa7 100644 --- a/vmware_nsx/tests/unit/dvs/test_plugin.py +++ b/vmware_nsx/tests/unit/dvs/test_plugin.py @@ -141,7 +141,7 @@ class NeutronSimpleDvsTestCase(test_plugin.NeutronDbPluginV2TestCase): def setUp(self, mock_moref, mock_session, plugin=PLUGIN_NAME, ext_mgr=None, - service_plugins=None): + service_plugins=None, **kwargs): # Ensure that DVS is enabled cfg.CONF.set_override('host_ip', 'fake_ip', group='dvs') cfg.CONF.set_override('host_username', 'fake_user', group='dvs') diff --git a/vmware_nsx/tests/unit/nsx_tvd/test_plugin.py b/vmware_nsx/tests/unit/nsx_tvd/test_plugin.py index eb2aae385f..5984f4e4e1 100644 --- a/vmware_nsx/tests/unit/nsx_tvd/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_tvd/test_plugin.py @@ -54,7 +54,8 @@ class NsxTVDPluginTestCase(v_tests.NsxVPluginV2TestCase, super(NsxTVDPluginTestCase, self).setUp( plugin=plugin, - ext_mgr=ext_mgr) + ext_mgr=ext_mgr, + with_md_proxy=False) self._project_id = _uuid() self.core_plugin = directory.get_plugin() diff --git a/vmware_nsx/tests/unit/nsx_v/test_md_proxy.py b/vmware_nsx/tests/unit/nsx_v/test_md_proxy.py deleted file mode 100644 index f9b39dff12..0000000000 --- a/vmware_nsx/tests/unit/nsx_v/test_md_proxy.py +++ /dev/null @@ -1,315 +0,0 @@ -# Copyright (c) 2017 OpenStack Foundation. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import mock - -from oslo_config import cfg - -from neutron_lib import context - -from vmware_nsx.db import nsxv_db -from vmware_nsx.db import nsxv_models -from vmware_nsx.plugins.nsx_v.vshield.common import ( - constants as vcns_const) -from vmware_nsx.plugins.nsx_v.vshield import edge_utils -from vmware_nsx.tests.unit.nsx_v import test_plugin - - -PLUGIN_NAME = 'vmware_nsx.plugin.NsxVPlugin' - - -# Run all relevant plugin tests when the metadata proxy is enabled. -# Those tests does not specifically test the md_proxy. just verify that -# nothing gets broken. -class NsxVPluginWithMdV2TestCase(test_plugin.NsxVPluginV2TestCase): - - def setUp(self, plugin=PLUGIN_NAME, - ext_mgr=None, - service_plugins=None): - # Add the metadata configuration - cfg.CONF.set_override('mgt_net_moid', 'net-1', group="nsxv") - cfg.CONF.set_override('mgt_net_proxy_ips', ['2.2.2.2'], group="nsxv") - cfg.CONF.set_override('mgt_net_proxy_netmask', '255.255.255.0', - group="nsxv") - cfg.CONF.set_override('mgt_net_default_gateway', '1.1.1.1', - group="nsxv") - cfg.CONF.set_override('nova_metadata_ips', ['3.3.3.3'], group="nsxv") - - # Add some mocks required for the md code - mock_alloc_vnic = mock.patch.object(nsxv_db, 'allocate_edge_vnic') - mock_alloc_vnic_inst = mock_alloc_vnic.start() - mock_alloc_vnic_inst.return_value = nsxv_models.NsxvEdgeVnicBinding - mock.patch.object(edge_utils, "update_internal_interface").start() - - super(NsxVPluginWithMdV2TestCase, self).setUp( - plugin=plugin, ext_mgr=ext_mgr, - service_plugins=service_plugins) - - self.context = context.get_admin_context() - self.internal_net_id = nsxv_db.get_nsxv_internal_network_for_az( - self.context.session, - vcns_const.InternalEdgePurposes.INTER_EDGE_PURPOSE, - 'default')['network_id'] - - -class TestNetworksWithMdV2(test_plugin.TestNetworksV2, - NsxVPluginWithMdV2TestCase): - - # Skip all the tests that count networks, as there is an - # additional internal network for metadata. - def test_list_networks_with_sort_native(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_without_pk_in_fields_pagination_emulated(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_sort_emulated(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_shared(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_without_pk_in_fields_pagination_native(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_parameters(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_pagination_native(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_pagination_reverse_emulated(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_pagination_emulated(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_pagination_reverse_native(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_networks_with_fields(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_networks_bulk_wrong_input(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_networks_bulk_native_plugin_failure(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_networks_bulk_native_quotas(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_networks_bulk_emulated_plugin_failure(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_cannot_delete_md_net(self): - req = self.new_delete_request('networks', self.internal_net_id) - net_del_res = req.get_response(self.api) - self.assertEqual(net_del_res.status_int, 400) - - -class TestSubnetsWithMdV2(test_plugin.TestSubnetsV2, - NsxVPluginWithMdV2TestCase): - # Skip all the tests that count subnets, as there is an - # additional internal subnet for metadata. - def test_list_subnets_with_sort_native(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_subnets_with_sort_emulated(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_subnets_with_pagination_native(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_subnets_with_parameter(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_subnets_with_pagination_emulated(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_subnets_filtering_by_unknown_filter(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_subnets_shared(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_list_subnets(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_subnets_bulk_native_plugin_failure(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_subnets_bulk_native_quotas(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_subnets_bulk_emulated_plugin_failure(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_cannot_delete_md_subnet(self): - query_params = "network_id=%s" % self.internal_net_id - res = self._list('subnets', - neutron_context=self.context, - query_params=query_params) - internal_sub = res['subnets'][0]['id'] - req = self.new_delete_request('subnets', internal_sub) - net_del_res = req.get_response(self.api) - self.assertEqual(net_del_res.status_int, 400) - - -class TestExclusiveRouterWithMdTestCase( - test_plugin.TestExclusiveRouterTestCase, - NsxVPluginWithMdV2TestCase): - - # Skip all the tests that count firewall rules, as there are - # some MD specific rules - def test_router_set_gateway_with_nosnat(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_interfaces_different_tenants_update_firewall(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_interfaces_with_update_firewall(self): - self.skipTest("The test is not suitable for the metadata test case") - - # Skip all the tests that count routers or ports, as there is - # an additional router for the md proxy - def test_router_list_with_pagination_reverse(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list_with_sort(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list_with_pagination(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_add_interface_delete_port_after_failure(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_router_fail_at_the_backend(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_floatingip_delete_router_intf_with_subnet_id_returns_409(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_floatingip_delete_router_intf_with_port_id_returns_409(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_address_scope_snat_rules(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_address_scope_fw_rules(self): - self.skipTest("The test is not suitable for the metadata test case") - - -class TestVdrWithMdTestCase(test_plugin.TestVdrTestCase, - NsxVPluginWithMdV2TestCase): - # Skip all the tests that count firewall rules, as there are - # some MD specific rules - def test_router_set_gateway_with_nosnat(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_interfaces_different_tenants_update_firewall(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_interfaces_with_update_firewall(self): - self.skipTest("The test is not suitable for the metadata test case") - - # Skip all the tests that count routers or ports, as there is - # an additional router for the md proxy - def test_router_list_with_pagination_reverse(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list_with_sort(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list_with_pagination(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_add_interface_delete_port_after_failure(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_router_fail_at_the_backend(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_floatingip_delete_router_intf_with_subnet_id_returns_409(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_floatingip_delete_router_intf_with_port_id_returns_409(self): - self.skipTest("The test is not suitable for the metadata test case") - - #TODO(asarfaty): fix some mocks so those tests will pass - def test_router_plr_binding_default_size(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_plr_binding_configured_size(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_plr_binding_default_az(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_plr_binding_with_az(self): - self.skipTest("The test is not suitable for the metadata test case") - - -class TestSharedRouterWithMdTestCase(test_plugin.TestSharedRouterTestCase, - NsxVPluginWithMdV2TestCase): - # Skip all the tests that count firewall rules, as there are - # some MD specific rules - def test_router_set_gateway_with_nosnat(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_routers_set_gateway_with_nosnat(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_interfaces_different_tenants_update_firewall(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_interfaces_with_update_firewall(self): - self.skipTest("The test is not suitable for the metadata test case") - - # Skip all the tests that count routers or ports, as there is - # an additional router for the md proxy - def test_router_list_with_pagination_reverse(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list_with_sort(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list_with_pagination(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_list(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_router_add_interface_delete_port_after_failure(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_create_router_fail_at_the_backend(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_floatingip_delete_router_intf_with_subnet_id_returns_409(self): - self.skipTest("The test is not suitable for the metadata test case") - - def test_floatingip_delete_router_intf_with_port_id_returns_409(self): - self.skipTest("The test is not suitable for the metadata test case") diff --git a/vmware_nsx/tests/unit/nsx_v/test_plugin.py b/vmware_nsx/tests/unit/nsx_v/test_plugin.py index 3e3ace00c1..ead0f7473f 100644 --- a/vmware_nsx/tests/unit/nsx_v/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v/test_plugin.py @@ -58,12 +58,14 @@ from neutron_lib.utils import net from oslo_config import cfg from oslo_utils import uuidutils import six +from testtools import matchers import webob.exc from vmware_nsx._i18n import _ from vmware_nsx.common import config from vmware_nsx.common import exceptions as nsxv_exc from vmware_nsx.common import nsx_constants +from vmware_nsx.common import nsxv_constants from vmware_nsx.common import utils as c_utils from vmware_nsx.db import nsxv_db from vmware_nsx.dvs import dvs @@ -188,7 +190,9 @@ class NsxVPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): def setUp(self, mock_deploy_edge, plugin=PLUGIN_NAME, ext_mgr=None, - service_plugins=None): + service_plugins=None, + with_md_proxy=True, + **kwargs): test_utils.override_nsx_ini_test() mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True) mock_vcns_instance = mock_vcns.start() @@ -219,6 +223,23 @@ class NsxVPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): cfg.CONF.set_override("resource_pool_id", self.default_res_pool, group="nsxv") set_az_in_config('az7') + + # Add the metadata configuration + self.with_md_proxy = with_md_proxy + if self.with_md_proxy: + cfg.CONF.set_override('mgt_net_moid', 'net-1', group="nsxv") + cfg.CONF.set_override('mgt_net_proxy_ips', ['2.2.2.2'], + group="nsxv") + cfg.CONF.set_override('mgt_net_proxy_netmask', '255.255.255.0', + group="nsxv") + cfg.CONF.set_override('mgt_net_default_gateway', '1.1.1.1', + group="nsxv") + cfg.CONF.set_override('nova_metadata_ips', ['3.3.3.3'], + group="nsxv") + + # Add some mocks required for the md code + mock.patch.object(edge_utils, "update_internal_interface").start() + if service_plugins is not None: # override the service plugins only if specified directly super(NsxVPluginV2TestCase, self).setUp( @@ -244,6 +265,15 @@ class NsxVPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): # call init_complete manually. The event is not called in unit tests plugin_instance.init_complete(None, None, {}) + self.context = context.get_admin_context() + + self.internal_net_id = None + if self.with_md_proxy: + self.internal_net_id = nsxv_db.get_nsxv_internal_network_for_az( + self.context.session, + vcns_const.InternalEdgePurposes.INTER_EDGE_PURPOSE, + 'default')['network_id'] + def _get_core_plugin_with_dvs(self): # enable dvs features to allow policy with QOS cfg.CONF.set_default('use_dvs_features', True, 'nsxv') @@ -252,6 +282,129 @@ class NsxVPluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase): plugin._vcm = dvs.VCManager() return plugin + def _remove_md_proxy_from_list(self, items): + for r in items[:]: + if (r.get('tenant_id') == nsxv_constants.INTERNAL_TENANT_ID or + r.get('name') == 'inter-edge-net'): + items.remove(r) + + def deserialize(self, content_type, response): + """Override list actions to skip metadata internal objects + This will allow most tests to run with mdproxy + """ + ctype = 'application/%s' % content_type + data = self._deserializers[ctype].deserialize(response.body)['body'] + for resource in ['networks', 'subnets', 'ports']: + if data.get(resource): + self._remove_md_proxy_from_list(data[resource]) + return data + + def _list(self, resource, fmt=None, neutron_context=None, + query_params=None, expected_code=webob.exc.HTTPOk.code): + fmt = fmt or self.fmt + req = self.new_list_request(resource, fmt, query_params) + if neutron_context: + req.environ['neutron.context'] = neutron_context + res = req.get_response(self._api_for_resource(resource)) + self.assertEqual(expected_code, res.status_int) + if query_params and '_id=' in query_params: + # Do not remove objects if their id was requested specifically + return super(NsxVPluginV2TestCase, self).deserialize(fmt, res) + else: + return self.deserialize(fmt, res) + + def _test_list_with_pagination(self, resource, items, sort, + limit, expected_page_num, + resources=None, + query_params='', + verify_key='id'): + """Override list actions to skip metadata internal objects + This will allow most tests to run with mdproxy + """ + if not resources: + resources = '%ss' % resource + query_str = query_params + '&' if query_params else '' + query_str = query_str + ("limit=%s&sort_key=%s&" + "sort_dir=%s") % (limit, sort[0], sort[1]) + req = self.new_list_request(resources, params=query_str) + items_res = [] + page_num = 0 + api = self._api_for_resource(resources) + resource = resource.replace('-', '_') + resources = resources.replace('-', '_') + while req: + page_num = page_num + 1 + res = super(NsxVPluginV2TestCase, self).deserialize( + self.fmt, req.get_response(api)) + self.assertThat(len(res[resources]), + matchers.LessThan(limit + 1)) + items_res = items_res + res[resources] + req = None + if '%s_links' % resources in res: + for link in res['%s_links' % resources]: + if link['rel'] == 'next': + content_type = 'application/%s' % self.fmt + req = testlib_api.create_request(link['href'], + '', content_type) + self.assertEqual(len(res[resources]), + limit) + # skip md-proxy objects + orig_items_num = len(items_res) + self._remove_md_proxy_from_list(items_res) + # Test number of pages only if no mdproxy entries were removed + if orig_items_num == len(items_res): + self.assertEqual(expected_page_num, page_num) + self.assertEqual([item[resource][verify_key] for item in items], + [n[verify_key] for n in items_res]) + + def _test_list_with_pagination_reverse(self, resource, items, sort, + limit, expected_page_num, + resources=None, + query_params=''): + """Override list actions to skip metadata internal objects + This will allow most tests to run with mdproxy + """ + if not resources: + resources = '%ss' % resource + resource = resource.replace('-', '_') + api = self._api_for_resource(resources) + marker = items[-1][resource]['id'] + query_str = query_params + '&' if query_params else '' + query_str = query_str + ("limit=%s&page_reverse=True&" + "sort_key=%s&sort_dir=%s&" + "marker=%s") % (limit, sort[0], sort[1], + marker) + req = self.new_list_request(resources, params=query_str) + item_res = [items[-1][resource]] + page_num = 0 + resources = resources.replace('-', '_') + while req: + page_num = page_num + 1 + res = super(NsxVPluginV2TestCase, self).deserialize( + self.fmt, req.get_response(api)) + self.assertThat(len(res[resources]), + matchers.LessThan(limit + 1)) + res[resources].reverse() + item_res = item_res + res[resources] + req = None + if '%s_links' % resources in res: + for link in res['%s_links' % resources]: + if link['rel'] == 'previous': + content_type = 'application/%s' % self.fmt + req = testlib_api.create_request(link['href'], + '', content_type) + self.assertEqual(len(res[resources]), + limit) + # skip md-proxy objects + orig_items_num = len(item_res) + self._remove_md_proxy_from_list(item_res) + # Test number of pages only if no mdproxy entries were removed + if orig_items_num == len(item_res): + self.assertEqual(expected_page_num, page_num) + expected_res = [item[resource]['id'] for item in items] + expected_res.reverse() + self.assertEqual(expected_res, [n['id'] for n in item_res]) + class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase): @@ -415,11 +568,13 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase): with self.network(name='net2', shared=True): req = self.new_list_request('networks') res = self.deserialize('json', req.get_response(self.api)) + ###self._remove_md_proxy_from_list(res['networks']) self.assertEqual(len(res['networks']), 2) req_2 = self.new_list_request('networks') req_2.environ['neutron.context'] = context.Context('', 'somebody') res = self.deserialize('json', req_2.get_response(self.api)) + ###self._remove_md_proxy_from_list(res['networks']) # tenant must see a single network self.assertEqual(len(res['networks']), 1) @@ -843,6 +998,28 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase): self.assertEqual([], net['availability_zones']) + def test_list_networks_with_fields(self): + with self.network(name='net1'): + req = self.new_list_request('networks', + params='fields=name') + res = self.deserialize(self.fmt, req.get_response(self.api)) + self._remove_md_proxy_from_list(res['networks']) + self.assertEqual(1, len(res['networks'])) + net = res['networks'][0] + self.assertEqual('net1', net['name']) + self.assertNotIn('id', net) + self.assertNotIn('tenant_id', net) + self.assertNotIn('project_id', net) + + def test_list_networks_without_pk_in_fields_pagination_native(self): + self.skipTest("The test is not suitable for the metadata test case") + + def test_cannot_delete_md_net(self): + if self.internal_net_id: + req = self.new_delete_request('networks', self.internal_net_id) + net_del_res = req.get_response(self.api) + self.assertEqual(net_del_res.status_int, 400) + class TestVnicIndex(NsxVPluginV2TestCase, test_vnic_index.VnicIndexDbTestCase): @@ -2066,6 +2243,17 @@ class TestSubnetsV2(NsxVPluginV2TestCase, cidr='169.254.128.128/25') self.assertEqual(ctx_manager.exception.code, 400) + def test_cannot_delete_md_subnet(self): + if self.internal_net_id: + query_params = "network_id=%s" % self.internal_net_id + res = self._list('subnets', + neutron_context=self.context, + query_params=query_params) + internal_sub = res['subnets'][0]['id'] + req = self.new_delete_request('subnets', internal_sub) + net_del_res = req.get_response(self.api) + self.assertEqual(net_del_res.status_int, 400) + class TestSubnetPoolsV2(NsxVPluginV2TestCase, test_plugin.TestSubnetsV2): def setUp(self, @@ -2449,13 +2637,19 @@ class L3NatTestCaseBase(test_l3_plugin.L3NatTestCaseMixin): self.assertEqual(fp2['floatingip']['router_id'], r2['router']['id']) + def _get_md_proxy_fw_rules(self): + if not self.with_md_proxy: + return [] + return md_proxy.get_router_fw_rules() + @mock.patch.object(edge_utils, "update_firewall") def test_router_set_gateway_with_nosnat(self, mock): expected_fw = [{'action': 'allow', 'enabled': True, 'name': 'Subnet Rule', 'source_ip_address': [], - 'destination_ip_address': []}] + 'destination_ip_address': []} + ] + self._get_md_proxy_fw_rules() nosnat_fw = [{'action': 'allow', 'enabled': True, 'name': 'No SNAT Rule', @@ -3089,7 +3283,8 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, 'enabled': True, 'name': 'Subnet Rule', 'source_ip_address': expected_cidrs, - 'destination_ip_address': expected_cidrs}] + 'destination_ip_address': expected_cidrs} + ] + self._get_md_proxy_fw_rules() fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual(self._recursive_sort_list(expected_fw), self._recursive_sort_list(fw_rules)) @@ -3244,7 +3439,8 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, 'enabled': True, 'name': 'Subnet Rule', 'source_ip_address': expected_cidrs, - 'destination_ip_address': expected_cidrs}] + 'destination_ip_address': expected_cidrs} + ] + self._get_md_proxy_fw_rules() fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual(self._recursive_sort_list(expected_fw), self._recursive_sort_list(fw_rules)) @@ -3253,11 +3449,12 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, s1['subnet']['id'], None, tenant_id=tenant_id) + self._router_interface_action('remove', r['router']['id'], s2['subnet']['id'], None) - expected_fw = [] + expected_fw = self._get_md_proxy_fw_rules() fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual(expected_fw, fw_rules) @@ -3596,15 +3793,17 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, # check fw rules fw_rules = update_fw.call_args[0][3][ 'firewall_rule_list'] - self.assertEqual(2, len(fw_rules)) + exp_fw_len = 5 if self.with_md_proxy else 2 + pool_rule_ind = 4 if self.with_md_proxy else 1 + pool_rule = fw_rules[pool_rule_ind] + self.assertEqual(exp_fw_len, len(fw_rules)) self.assertEqual('Allocation Pool Rule', - fw_rules[1]['name']) - self.assertEqual('allow', fw_rules[1]['action']) - self.assertEqual( - int_subnet['subnet']['cidr'], - fw_rules[1]['destination_ip_address'][0]) + pool_rule['name']) + self.assertEqual('allow', pool_rule['action']) + self.assertEqual(int_subnet['subnet']['cidr'], + pool_rule['destination_ip_address'][0]) self.assertEqual('external', - fw_rules[1]['source_vnic_groups'][0]) + pool_rule['source_vnic_groups'][0]) def test_router_address_scope_fw_rules(self): """Test that if the router interfaces has different address scope @@ -3652,12 +3851,13 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, 'action': 'allow', 'name': 'Subnet Rule', 'source_ip_address': [subnet2['subnet']['cidr'], - subnet3['subnet']['cidr']]}] + subnet3['subnet']['cidr']]} + ] + self._get_md_proxy_fw_rules() # check the final fw rules fw_rules = update_fw.call_args[0][3][ 'firewall_rule_list'] - self.assertEqual(2, len(fw_rules)) + self.assertEqual(len(expected_rules), len(fw_rules)) self.assertEqual(self._recursive_sort_list(expected_rules), self._recursive_sort_list(fw_rules)) @@ -3741,6 +3941,23 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, def test_router_address_scope_gw_change(self): self._test_router_address_scope_change(change_gw=True) + def test_router_add_interface_delete_port_after_failure(self): + with self.router() as r, self.subnet(enable_dhcp=False) as s: + plugin = directory.get_plugin() + # inject a failure in the update port that happens at the end + # to ensure the port gets deleted + with mock.patch.object( + plugin, 'update_port', + side_effect=n_exc.InvalidInput(error_message='x')): + self._router_interface_action('add', + r['router']['id'], + s['subnet']['id'], + None, + webob.exc.HTTPBadRequest.code) + exp_num_of_ports = 1 if self.with_md_proxy else 0 + ports = plugin.get_ports(context.get_admin_context()) + self.assertEqual(exp_num_of_ports, len(ports)) + class ExtGwModeTestCase(NsxVPluginV2TestCase, test_ext_gw_mode.ExtGwModeIntTestCase): @@ -5031,8 +5248,10 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase, expected_fw1[0]['source_ip_address'] = ['11.0.0.0/24'] expected_fw1[0]['destination_ip_address'] = ['11.0.0.0/24'] fw_rules = mock.call_args[0][3]['firewall_rule_list'] - self.assertEqual(self._recursive_sort_list(expected_fw1), - self._recursive_sort_list(fw_rules)) + self.assertEqual( + self._recursive_sort_list( + self._get_md_proxy_fw_rules() + expected_fw1), + self._recursive_sort_list(fw_rules)) self._router_interface_action('add', r2['router']['id'], s2['subnet']['id'], @@ -5047,7 +5266,9 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase, expected_fw2[0]['destination_ip_address'] = ['12.0.0.0/24'] fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual( - self._recursive_sort_list(expected_fw1 + expected_fw2), + self._recursive_sort_list( + self._get_md_proxy_fw_rules() + expected_fw1 + + expected_fw2), self._recursive_sort_list(fw_rules)) self._update_router_enable_snat( r1['router']['id'], @@ -5056,8 +5277,9 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase, nosnat_fw1[0]['destination_ip_address'] = ['11.0.0.0/24'] fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual( - self._recursive_sort_list(expected_fw1 + expected_fw2 + - nosnat_fw1), + self._recursive_sort_list( + self._get_md_proxy_fw_rules() + expected_fw1 + + expected_fw2 + nosnat_fw1), self._recursive_sort_list(fw_rules)) self._update_router_enable_snat( r2['router']['id'], @@ -5066,8 +5288,9 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase, nosnat_fw2[0]['destination_ip_address'] = ['12.0.0.0/24'] fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual( - self._recursive_sort_list(expected_fw1 + expected_fw2 + - nosnat_fw1 + nosnat_fw2), + self._recursive_sort_list( + self._get_md_proxy_fw_rules() + expected_fw1 + + expected_fw2 + nosnat_fw1 + nosnat_fw2), self._recursive_sort_list(fw_rules)) self._update_router_enable_snat( r2['router']['id'], @@ -5075,8 +5298,9 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase, True) fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual( - self._recursive_sort_list(expected_fw1 + expected_fw2 + - nosnat_fw1), + self._recursive_sort_list( + self._get_md_proxy_fw_rules() + expected_fw1 + + expected_fw2 + nosnat_fw1), self._recursive_sort_list(fw_rules)) self._router_interface_action('remove', r2['router']['id'], @@ -5084,14 +5308,16 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase, None) fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual( - self._recursive_sort_list(expected_fw1 + nosnat_fw1), + self._recursive_sort_list( + self._get_md_proxy_fw_rules() + expected_fw1 + nosnat_fw1), self._recursive_sort_list(fw_rules)) self._remove_external_gateway_from_router( r1['router']['id'], ext_subnet['subnet']['network_id']) fw_rules = mock.call_args[0][3]['firewall_rule_list'] self.assertEqual( - self._recursive_sort_list(expected_fw1), + self._recursive_sort_list( + self._get_md_proxy_fw_rules() + expected_fw1), self._recursive_sort_list(fw_rules)) self._router_interface_action('remove', r1['router']['id'], @@ -5577,7 +5803,7 @@ class TestRouterFlavorTestCase(extension.ExtensionTestCase, def assertSyslogConfig(self, expected): """Verify syslog was updated in fake driver - Test assumes edge ids are created sequentally starting from edge-1 + Test assumes edge ids are created sequentially starting from edge-1 """ edge_id = ('edge-%s' % self._iteration) actual = self.plugin.nsx_v.vcns.get_edge_syslog(edge_id)[1] diff --git a/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py b/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py index b0757c29ab..069bb0f21c 100644 --- a/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py +++ b/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py @@ -249,7 +249,9 @@ class FakeVcns(object): response = { 'label': 'vNic_1', 'name': 'internal1', - 'addressGroups': {'addressGroups': []}, + 'addressGroups': { + 'addressGroups': [{'primaryAddress': '1.1.1.1'}]}, + 'portgroupId': '1', 'mtu': 1500, 'type': 'trunk', 'subInterfaces': {'subInterfaces': []}, @@ -788,6 +790,9 @@ class FakeVcns(object): response['config'] = self._fake_loadbalancer_config[edge_id] return self.return_helper(header, response) + def get_loadbalancer_statistics(self, edge_id): + return [{}, {}] + def update_ipsec_config(self, edge_id, ipsec_config): self.fake_ipsecvpn_dict[edge_id] = ipsec_config header = {'status': 204} diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index 30f2ab0680..fac698b6e0 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -215,7 +215,7 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase, def setUp(self, plugin=PLUGIN_NAME, ext_mgr=None, - service_plugins=None): + service_plugins=None, **kwargs): self._patchers = []