# Copyright 2017 NOKIA
# All Rights Reserved.

from netaddr import IPNetwork
import testtools

from tempest.common import waiters
from tempest.lib import exceptions
from tempest.scenario import manager
from tempest.test import decorators

from nuage_tempest_plugin.lib.test.nuage_test import NuageAdminNetworksTest
from nuage_tempest_plugin.lib.test.nuage_test import NuageBaseTest
from nuage_tempest_plugin.lib.topology import Topology
from nuage_tempest_plugin.lib.utils import constants
from nuage_tempest_plugin.services.nuage_client import NuageRestClient

CONF = Topology.get_conf()
LOG = Topology.get_logger(__name__)


class PortsTest(NuageBaseTest, NuageAdminNetworksTest,
                manager.NetworkScenarioTest):
    @classmethod
    def setup_clients(cls):
        super(PortsTest, cls).setup_clients()
        cls.vsd_client = NuageRestClient()

    def show_port(self, port_id):
        """Wrapper utility that shows a given port."""
        body = self.ports_client.show_port(port_id)
        return body['port']

    def _create_server(self, name, network, port_id=None):
        keypair = self.create_keypair()
        network = {'uuid': network['id']}
        if port_id is not None:
            network['port'] = port_id
        return self.create_server(
            name=name,
            networks=[network],
            key_name=keypair['name'],
            wait_until='ACTIVE')

    def _delete_server(self, server_id, clients=None):
        if clients is None:
            clients = self.os_primary
        clients.servers_client.delete_server(server_id)
        waiters.wait_for_server_termination(clients.servers_client, server_id)

    @decorators.attr(type='smoke')
    def test_nuage_dhcp_port_create_check_status(self):
        network = self.create_network()
        self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                           mask_bits=24)
        filters = {
            'device_owner': 'network:dhcp:nuage',
            'network_id': network['id']
        }
        dhcp_port = self.ports_client.list_ports(**filters)['ports'][0]
        self.assertEqual('ACTIVE', dhcp_port['status'])

    @decorators.attr(type='smoke')
    def test_nuage_dhcp_port_with_router_detach_check_status(self):
        network = self.create_network()
        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=24)
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"],
                                     cleanup=False)

        self.routers_client.remove_router_interface(router_id=router["id"],
                                                    subnet_id=subnet["id"])
        filters = {
            'device_owner': 'network:dhcp:nuage',
            'network_id': network['id']
        }
        dhcp_port = self.ports_client.list_ports(**filters)['ports'][0]
        self.assertEqual('ACTIVE', dhcp_port['status'])

    @decorators.attr(type='smoke')
    def test_nuage_port_create_show_check_status(self):
        network = self.create_network()
        self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                           mask_bits=24)
        port = self.create_port(network)
        self.assertEqual('DOWN', port['status'])
        port = self.show_port(port['id'])
        # state has to remain DOWN as long as port is not bound
        self.assertEqual('DOWN', port['status'])

    @decorators.attr(type='smoke')
    def test_nuage_port_create_server_create_delete_check_status(self):
        network = self.create_network()
        self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                           mask_bits=24)
        port = self.create_port(network)
        server = self._create_server('s1', network, port['id'])
        port = self.show_port(port['id'])
        self.assertEqual('ACTIVE', port['status'])
        self._delete_server(server['id'])
        port = self.show_port(port['id'])
        self.assertEqual('DOWN', port['status'])

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_negative(self):
        # Set up resources
        # Base resources
        if self.is_dhcp_agent_present():
            raise self.skipException(
                'Cannot run this test case when DHCP agent is enabled')
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        subnet2 = self.create_subnet(network, cidr=IPNetwork("20.0.0.0/24"),
                                     mask_bits=28)
        self.assertIsNotNone(subnet2, "Unable to create second subnet")

        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "20.0.0.4",
                "subnet_id": subnet2["id"]
            }
        ]
        # Fail
        msg = "Port can't have multiple IPv4 IPs of different subnets"
        self.assertRaisesRegex(exceptions.BadRequest,
                               msg,
                               self.create_port,
                               network=network, fixed_ips=fixed_ips)

    @testtools.skipIf(Topology.before_nuage('5.4'), 'Unsupported pre-5.4')
    def test_nuage_os_managed_subnet_port_create_with_nuage_policy_negative(
            self):

        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")

        msg = ("Cannot use VSP policy groups on OS managed subnets,"
               " use neutron security groups instead.")

        self.assertRaisesRegex(exceptions.BadRequest,
                               msg,
                               self.create_port,
                               network=network,
                               nuage_policy_groups=['Random_value'])

    @testtools.skipIf(Topology.before_nuage('5.4'), 'Unsupported pre-5.4')
    def test_nuage_os_managed_subnet_port_update_with_nuage_policy_negative(
            self):

        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")

        port = self.create_port(network=network)

        self.assertIsNotNone(port, "Unable to create port")

        msg = ("Cannot use VSP policy groups on OS managed subnets,"
               " use neutron security groups instead.")

        self.assertRaisesRegex(exceptions.BadRequest,
                               msg,
                               self.update_port,
                               port=port,
                               nuage_policy_groups=['Random_value'])

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_negative(self):
        if self.is_dhcp_agent_present():
            raise self.skipException(
                'Multiple subnets in a network not supported when DHCP agent '
                'is enabled.')
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        subnet2 = self.create_subnet(network, cidr=IPNetwork("20.0.0.0/24"),
                                     mask_bits=28)
        self.assertIsNotNone(subnet2, "Unable to create second subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet2["id"])
        # Create port
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        port = self.update_port(port=port, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to update port")
        self.assertEqual(port["fixed_ips"][0]["ip_address"], "10.0.0.5",
                         message="The port did not update properly.")

        # Update to subnet2 should fail
        fixed_ips = [
            {
                "ip_address": "20.0.0.4",
                "subnet_id": subnet2["id"]
            }
        ]
        try:
            self.update_port(port=port, fixed_ips=fixed_ips)
            self.fail("Exception expected when updating to"
                      " a different subnet!")
        except exceptions.BadRequest as e:
            if "Updating fixed ip of port" in e._error_string:
                pass
            else:
                # Differentiate between VSD failure and update failure
                LOG.debug(e._error_string)
                self.fail("A different NuageBadRequest exception"
                          " was expected for this operation.")

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_same_subnet_l2(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")

        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]

        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.L2_DOMAIN,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_same_subnet_l2(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.L2_DOMAIN,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        port = self.update_port(port=port, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_same_subnet_l3(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4']
        vip_mismatch = False
        mac_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            if nuage_vport_vip['MAC'] != port['mac_address']:
                mac_mismatch = True
        self.assertEqual(vip_mismatch, False)
        self.assertEqual(mac_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_same_subnet_l3_no_security(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                port_security_enabled=False)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4']
        vip_mismatch = False
        mac_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            if nuage_vport_vip['MAC'] != port['mac_address']:
                mac_mismatch = True
        self.assertEqual(vip_mismatch, False)
        self.assertEqual(mac_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_same_subnet_l3_no_security(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.5',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network,
                                fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.update_port(port=port, fixed_ips=fixed_ips,
                                allowed_address_pairs=[],
                                security_groups=[],
                                port_security_enabled=False)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4']
        vip_mismatch = False
        mac_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            if nuage_vport_vip['MAC'] != port['mac_address']:
                mac_mismatch = True
        self.assertEqual(vip_mismatch, False)
        self.assertEqual(mac_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_same_subnet_l3(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        port = self.update_port(port=port, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4']
        vip_mismatch = False
        mac_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            if nuage_vport_vip['MAC'] != port['mac_address']:
                mac_mismatch = True
        self.assertEqual(vip_mismatch, False)
        self.assertEqual(mac_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_same_subnet_l2_with_aap(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")

        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.50',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.L2_DOMAIN,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_same_subnet_l2_with_aap(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.L2_DOMAIN,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.50',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.update_port(port=port,
                                fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_same_subnet_l3_with_aap(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4', allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_same_subnet_l3_with_aap_outside_cidr(
            self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '1.1.1.5',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4']
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_same_subnet_l3_with_aap(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.update_port(port=port, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4', allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_same_subnet_l3_with_aap_with_vm(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.10',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

        self._create_server(name='vm-' + network['name'],
                            network=network, port_id=port['id'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.6",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.7',
                                  'mac_address': 'fe:a0:36:4b:c8:70'},
                                 {'ip_address': '10.0.0.10',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.update_port(port=port, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address'],
                      allowed_address_pairs[1]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_update_app_to_fixed_ips_l3_with_vm(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

        self._create_server(name='vm-' + network['name'],
                            network=network, port_id=port['id'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.6",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.7',
                                  'mac_address': 'fe:a0:36:4b:c8:70'},
                                 {'ip_address': '10.0.0.10',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.update_port(port=port, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address'],
                      allowed_address_pairs[1]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ip_with_vm_and_conflict_with_aap_neg(
            self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.10',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

        self._create_server(name='vm-' + network['name'],
                            network=network, port_id=port['id'])
        fixed_ips = [
            {
                "ip_address": "10.0.0.8",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        self.create_port(network=network, fixed_ips=fixed_ips,
                         allowed_address_pairs=allowed_address_pairs)

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.6",
                "subnet_id": subnet["id"]
            }
        ]
        # below update will fail with proper roll back
        try:
            self.update_port(port=port, fixed_ips=fixed_ips)
            self.fail("Exception expected when updating to"
                      " a different subnet!")
        except exceptions.BadRequest as e:
            if ('Bad request: The IP Address 10.0.0.6 is'
                    ' currently in use by subnet' in e._error_string):
                vsd_vport_parent = self.vsd_client.get_global_resource(
                    constants.SUBNETWORK,
                    filters='externalID',
                    filter_value=subnet['id'])[0]
                nuage_vport = self.vsd_client.get_vport(
                    constants.SUBNETWORK,
                    vsd_vport_parent['ID'],
                    filters='externalID',
                    filter_value=port['id'])
                self.assertEqual(constants.INHERITED,
                                 nuage_vport[0]['addressSpoofing'])
                nuage_vport_vips = self.vsd_client.get_virtual_ip(
                    constants.VPORT,
                    nuage_vport[0]['ID'])
                vip_mismatch = False
                if valid_vips and not nuage_vport_vips:
                    vip_mismatch = True
                for nuage_vport_vip in nuage_vport_vips:
                    if nuage_vport_vip['virtualIP'] not in valid_vips:
                        vip_mismatch = True
                    self.assertEqual(vip_mismatch, False)
                pass
            else:
                # Differentiate between VSD failure and update failure
                LOG.debug(e._error_string)
                self.fail("A different NuageBadRequest exception"
                          " was expected for this operation.")

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ip_same_as_aap(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.6",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        mac_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            if nuage_vport_vip['MAC'] != port['mac_address']:
                mac_mismatch = True
            self.assertEqual(vip_mismatch, False)
            self.assertEqual(mac_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_update_fixed_ips_same_as_aap(self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }
        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

        fixed_ips = [
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.6",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.update_port(port=port, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = [fixed_ips[0]["ip_address"],
                      allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        mac_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)
            if nuage_vport_vip['MAC'] != port['mac_address']:
                mac_mismatch = True
            self.assertEqual(vip_mismatch, False)
            self.assertEqual(mac_mismatch, False)

    @decorators.attr(type='smoke')
    def test_nuage_port_create_fixed_ips_same_subnet_with_aap_router_attach(
            self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")

        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.create_port(network=network, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to create port on network")

        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.L2_DOMAIN,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED,
                         nuage_vport[0]['addressSpoofing'])
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"])

        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        valid_vips = ['10.0.0.4', allowed_address_pairs[0]['ip_address']]
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

    @decorators.attr(type='smoke')
    @testtools.skipIf(Topology.before_nuage('5.4'), 'Unsupported pre-5.4')
    def test_nuage_port_update_fixed_ips_same_subnet_with_aap_router_detach(
            self):
        # Set up resources
        # Base resources
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        router = self.create_router(
            admin_state_up=True,
            external_network_id=CONF.network.public_network_id)
        self.assertIsNotNone(router, "Unable to create router")
        # Attach subnet
        self.create_router_interface(router_id=router["id"],
                                     subnet_id=subnet["id"], cleanup=False)
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            }
        ]
        port = self.create_port(network=network, fixed_ips=fixed_ips)
        self.assertIsNotNone(port, "Unable to create port on network")
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.SUBNETWORK,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

        # update within subnet should succeed
        fixed_ips = [
            {
                "ip_address": "10.0.0.4",
                "subnet_id": subnet["id"]
            },
            {
                "ip_address": "10.0.0.5",
                "subnet_id": subnet["id"]
            }

        ]
        allowed_address_pairs = [{'ip_address': '10.0.0.6',
                                  'mac_address': 'fe:a0:36:4b:c8:70'}]
        port = self.update_port(port=port, fixed_ips=fixed_ips,
                                allowed_address_pairs=allowed_address_pairs)
        self.assertIsNotNone(port, "Unable to update port")
        nuage_vport = self.vsd_client.get_vport(
            constants.SUBNETWORK,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])
        valid_vips = ['10.0.0.4', allowed_address_pairs[0]['ip_address']]
        nuage_vport_vips = self.vsd_client.get_virtual_ip(
            constants.VPORT,
            nuage_vport[0]['ID'])
        vip_mismatch = False
        if valid_vips and not nuage_vport_vips:
            vip_mismatch = True
        for nuage_vport_vip in nuage_vport_vips:
            if nuage_vport_vip['virtualIP'] not in valid_vips:
                vip_mismatch = True
            self.assertEqual(vip_mismatch, False)

        self.admin_routers_client.remove_router_interface(
            router['id'],
            subnet_id=subnet['id'])
        vsd_vport_parent = self.vsd_client.get_global_resource(
            constants.L2_DOMAIN,
            filters='externalID',
            filter_value=subnet['id'])[0]
        nuage_vport = self.vsd_client.get_vport(
            constants.L2_DOMAIN,
            vsd_vport_parent['ID'],
            filters='externalID',
            filter_value=port['id'])
        self.assertEqual(constants.ENABLED if Topology.from_nuage('5.4')
                         else constants.INHERITED,
                         nuage_vport[0]['addressSpoofing'])

    @decorators.attr(type='smoke')
    @testtools.skipIf(Topology.before_nuage('5.4'), 'Unsupported pre-5.4')
    def test_delete_unbound_port_with_hanging_vminterface(self):
        # OPENSTACK-2797
        network = self.create_network()
        self.assertIsNotNone(network, "Unable to create network")

        subnet = self.create_subnet(network, cidr=IPNetwork("10.0.0.0/24"),
                                    mask_bits=28)
        self.assertIsNotNone(subnet, "Unable to create subnet")
        port = self.create_port(network=network, cleanup=False)
        self.addCleanup(self._try_delete,
                        self.manager.ports_client.delete_port,
                        port['id'])

        # Find vport
        l2domain = self.vsd.get_l2domain(by_subnet_id=subnet['id'])
        vport = self.vsd.get_vport(l2domain=l2domain, by_port_id=port['id'])

        # Create "Fake" VM interface to simulate following behavior:
        # -> Port is being bound -> VM created -> port deleted ->
        # Port not bound but leftover VM on VSD
        vminterface = self.vsd.vspk.NUVMInterface(
            name='test-fip-vm', vport_id=vport.id,
            external_id=self.vsd.external_id(port['id']),
            mac='E6:04:AA:7A:AA:86', ip_address='10.0.0.10')
        vm = self.vsd.vspk.NUVM(name='test-port-delete-vm',
                                uuid='1339f7f4-f7a0-445f-b257-8dbfaf0d6fc8',
                                external_id=self.vsd.external_id(
                                    '1339f7f4-f7a0-445f-b257-8dbfaf0d6fc8'),
                                interfaces=[vminterface])
        # Impersonate tenant user for appropriate permissions on VM
        self.vsd.session().impersonate(port['tenant_id'],
                                       self.default_netpartition_name)
        self.vsd.session().user.create_child(vm)
        self.vsd.session().stop_impersonate()

        # Delete port, VM should be deleted in this request
        self.delete_port(port)

        # Verify that vport is deleted
        vport = self.vsd.get_vport(l2domain=l2domain, by_port_id=port['id'])
        self.assertIsNone(vport, 'Vport not deleted by Port delete statement')

[((569, 588), 'nuage_tempest_plugin.lib.topology.Topology.get_conf', 'Topology.get_conf', ([], {}), '()\n', (586, 588), False, 'from nuage_tempest_plugin.lib.topology import Topology\n'), ((595, 624), 'nuage_tempest_plugin.lib.topology.Topology.get_logger', 'Topology.get_logger', (['__name__'], {}), '(__name__)\n', (614, 624), False, 'from nuage_tempest_plugin.lib.topology import Topology\n'), ((1668, 1697), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (1683, 1697), False, 'from tempest.test import decorators\n'), ((2156, 2185), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (2171, 2185), False, 'from tempest.test import decorators\n'), ((3135, 3164), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (3150, 3164), False, 'from tempest.test import decorators\n'), ((3620, 3649), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (3635, 3649), False, 'from tempest.test import decorators\n'), ((4207, 4236), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (4222, 4236), False, 'from tempest.test import decorators\n'), ((7364, 7393), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (7379, 7393), False, 'from tempest.test import decorators\n'), ((10182, 10211), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (10197, 10211), False, 'from tempest.test import decorators\n'), ((11499, 11528), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (11514, 11528), False, 'from tempest.test import decorators\n'), ((13424, 13453), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (13439, 13453), False, 'from tempest.test import decorators\n'), ((15717, 15746), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (15732, 15746), False, 'from tempest.test import decorators\n'), ((18081, 18110), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (18096, 18110), False, 'from tempest.test import decorators\n'), ((21405, 21434), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (21420, 21434), False, 'from tempest.test import decorators\n'), ((24309, 24338), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (24324, 24338), False, 'from tempest.test import decorators\n'), ((25841, 25870), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (25856, 25870), False, 'from tempest.test import decorators\n'), ((28014, 28043), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (28029, 28043), False, 'from tempest.test import decorators\n'), ((30395, 30424), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (30410, 30424), False, 'from tempest.test import decorators\n'), ((32758, 32787), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (32773, 32787), False, 'from tempest.test import decorators\n'), ((35750, 35779), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (35765, 35779), False, 'from tempest.test import decorators\n'), ((39968, 39997), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (39983, 39997), False, 'from tempest.test import decorators\n'), ((44171, 44200), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (44186, 44200), False, 'from tempest.test import decorators\n'), ((49204, 49233), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (49219, 49233), False, 'from tempest.test import decorators\n'), ((51784, 51813), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (51799, 51813), False, 'from tempest.test import decorators\n'), ((55634, 55663), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (55649, 55663), False, 'from tempest.test import decorators\n'), ((58508, 58537), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (58523, 58537), False, 'from tempest.test import decorators\n'), ((62282, 62311), 'tempest.test.decorators.attr', 'decorators.attr', ([], {'type': '"""smoke"""'}), "(type='smoke')\n", (62297, 62311), False, 'from tempest.test import decorators\n'), ((844, 861), 'nuage_tempest_plugin.services.nuage_client.NuageRestClient', 'NuageRestClient', ([], {}), '()\n', (859, 861), False, 'from nuage_tempest_plugin.services.nuage_client import NuageRestClient\n'), ((1591, 1661), 'tempest.common.waiters.wait_for_server_termination', 'waiters.wait_for_server_termination', (['clients.servers_client', 'server_id'], {}), '(clients.servers_client, server_id)\n', (1626, 1661), False, 'from tempest.common import waiters\n'), ((5570, 5598), 'nuage_tempest_plugin.lib.topology.Topology.before_nuage', 'Topology.before_nuage', (['"""5.4"""'], {}), "('5.4')\n", (5591, 5598), False, 'from nuage_tempest_plugin.lib.topology import Topology\n'), ((6423, 6451), 'nuage_tempest_plugin.lib.topology.Topology.before_nuage', 'Topology.before_nuage', (['"""5.4"""'], {}), "('5.4')\n", (6444, 6451), False, 'from nuage_tempest_plugin.lib.topology import Topology\n'), ((58560, 58588), 'nuage_tempest_plugin.lib.topology.Topology.before_nuage', 'Topology.before_nuage', (['"""5.4"""'], {}), "('5.4')\n", (58581, 58588), False, 'from nuage_tempest_plugin.lib.topology import Topology\n'), ((62334, 62362), 'nuage_tempest_plugin.lib.topology.Topology.before_nuage', 'Topology.before_nuage', (['"""5.4"""'], {}), "('5.4')\n", (62355, 62362), False, 'from nuage_tempest_plugin.lib.topology import Topology\n'), ((1835, 1859), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (1844, 1859), False, 'from netaddr import IPNetwork\n'), ((2344, 2368), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (2353, 2368), False, 'from netaddr import IPNetwork\n'), ((3302, 3326), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (3311, 3326), False, 'from netaddr import IPNetwork\n'), ((3803, 3827), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (3812, 3827), False, 'from netaddr import IPNetwork\n'), ((4654, 4678), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (4663, 4678), False, 'from netaddr import IPNetwork\n'), ((4845, 4869), 'netaddr.IPNetwork', 'IPNetwork', (['"""20.0.0.0/24"""'], {}), "('20.0.0.0/24')\n", (4854, 4869), False, 'from netaddr import IPNetwork\n'), ((5877, 5901), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (5886, 5901), False, 'from netaddr import IPNetwork\n'), ((6730, 6754), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (6739, 6754), False, 'from netaddr import IPNetwork\n'), ((7849, 7873), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (7858, 7873), False, 'from netaddr import IPNetwork\n'), ((8040, 8064), 'netaddr.IPNetwork', 'IPNetwork', (['"""20.0.0.0/24"""'], {}), "('20.0.0.0/24')\n", (8049, 8064), False, 'from netaddr import IPNetwork\n'), ((10484, 10508), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (10493, 10508), False, 'from netaddr import IPNetwork\n'), ((11801, 11825), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (11810, 11825), False, 'from netaddr import IPNetwork\n'), ((13726, 13750), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (13735, 13750), False, 'from netaddr import IPNetwork\n'), ((16031, 16055), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (16040, 16055), False, 'from netaddr import IPNetwork\n'), ((18395, 18419), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (18404, 18419), False, 'from netaddr import IPNetwork\n'), ((21707, 21731), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (21716, 21731), False, 'from netaddr import IPNetwork\n'), ((24620, 24644), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (24629, 24644), False, 'from netaddr import IPNetwork\n'), ((26152, 26176), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (26161, 26176), False, 'from netaddr import IPNetwork\n'), ((28325, 28349), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (28334, 28349), False, 'from netaddr import IPNetwork\n'), ((30732, 30756), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (30741, 30756), False, 'from netaddr import IPNetwork\n'), ((33069, 33093), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (33078, 33093), False, 'from netaddr import IPNetwork\n'), ((36069, 36093), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (36078, 36093), False, 'from netaddr import IPNetwork\n'), ((40273, 40297), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (40282, 40297), False, 'from netaddr import IPNetwork\n'), ((44504, 44528), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (44513, 44528), False, 'from netaddr import IPNetwork\n'), ((49502, 49526), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (49511, 49526), False, 'from netaddr import IPNetwork\n'), ((52083, 52107), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (52092, 52107), False, 'from netaddr import IPNetwork\n'), ((55969, 55993), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (55978, 55993), False, 'from netaddr import IPNetwork\n'), ((58918, 58942), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (58927, 58942), False, 'from netaddr import IPNetwork\n'), ((62138, 62164), 'nuage_tempest_plugin.lib.topology.Topology.from_nuage', 'Topology.from_nuage', (['"""5.4"""'], {}), "('5.4')\n", (62157, 62164), False, 'from nuage_tempest_plugin.lib.topology import Topology\n'), ((62634, 62658), 'netaddr.IPNetwork', 'IPNetwork', (['"""10.0.0.0/24"""'], {}), "('10.0.0.0/24')\n", (62643, 62658), False, 'from netaddr import IPNetwork\n')]