Random IP for concurrent create pf and update_port

Port forwarding test port IP should be specified, otherwise IP
collision may happen between new port IP and router interface IP.
Or sometimes, port new IP and old IP are same.

After this patch, the port new IP will be randomly choiced from
the subset without [old_port_ips, router_interface_ips].

Partially reverts commit 414bdd4c59.

Change-Id: I157e08288765f1716b4cb12bb2e176760db806c0
Closes-Bug: #1818334
(cherry picked from commit cd6bf8035d)
This commit is contained in:
LIU Yulong 2019-03-18 23:52:18 +08:00
parent 01d0612a3a
commit c37f5bd4b9
2 changed files with 31 additions and 6 deletions

View File

@ -57,6 +57,9 @@ class PortForwardingTestCaseBase(ml2_test_base.ML2TestFramework,
def _delete_floatingip(self, fip_id):
return self.l3_plugin.delete_floatingip(self.context, fip_id)
def _get_ports(self, filters):
return self.core_plugin.get_ports(self.context, filters=filters)
def _update_port(self, port_id, update_info):
return self.core_plugin.update_port(
self.context, port_id, {'port': update_info})
@ -86,6 +89,13 @@ class PortForwardingTestCase(PortForwardingTestCaseBase):
super(PortForwardingTestCase, self).setUp()
self._prepare_env()
def _get_network_port_ips(self):
net_ports = self._get_ports(
filters={"network_id": [self.net['id']]})
net_port_ips = [
p['fixed_ips'][0]['ip_address'] for p in net_ports]
return net_port_ips
def _prepare_env(self):
self.router = self._create_router(distributed=True)
self.ext_net = self._create_network(
@ -101,9 +111,13 @@ class PortForwardingTestCase(PortForwardingTestCaseBase):
self._set_router_gw(self.router['id'], self.ext_net['id'])
self._add_router_interface(self.router['id'], self.subnet['id'])
self.fip = self._create_floatingip(self.ext_net['id'])
self.port_ip = self._find_ip_address(
self.subnet, exclude=self._get_network_port_ips(), is_random=True)
self.port = self._create_port(
self.fmt, self.net['id'],
fixed_ips=[{'subnet_id': self.subnet['id']}]).json['port']
fixed_ips=[{'subnet_id': self.subnet['id'],
'ip_address': self.port_ip}]).json['port']
self.port_forwarding = {
apidef.RESOURCE_NAME:
{apidef.EXTERNAL_PORT: 2225,
@ -445,7 +459,10 @@ class PortForwardingTestCase(PortForwardingTestCaseBase):
funcs, args_list)
def test_concurrent_create_port_forwarding_update_port(self):
new_ip = self._find_ip_address(self.subnet)
new_ip = self._find_ip_address(
self.subnet,
exclude=self._get_network_port_ips(),
is_random=True)
funcs = [self.pf_plugin.create_floatingip_port_forwarding,
self._update_port]
args_list = [(self.context, self.fip['id'], self.port_forwarding),

View File

@ -17,6 +17,7 @@ import contextlib
import copy
import functools
import itertools
import random
import eventlet
import mock
@ -286,10 +287,15 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase):
data = self._deserializers[ctype].deserialize(response.body)['body']
return data
def _find_ip_address(self, subnet):
def _find_ip_address(self, subnet, exclude=None, is_random=False):
network_ports = self._list_ports(
"json", 200, subnet['network_id']).json['ports']
used_ips = set()
if exclude:
if isinstance(exclude, (list, set, tuple)):
used_ips = set(exclude)
else:
used_ips.add(exclude)
for port in network_ports:
for ip in port['fixed_ips']:
if ip['subnet_id'] == subnet['id']:
@ -297,9 +303,11 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase):
for pool in subnet['allocation_pools']:
ips_range = netaddr.IPRange(pool['start'], pool['end'])
for ip in ips_range:
if ip not in used_ips:
return str(ip)
ip_list = [str(ip) for ip in ips_range if str(ip) not in used_ips]
if ip_list:
if is_random:
return random.choice(ip_list)
return ip_list[0]
def _create_bulk_from_list(self, fmt, resource, objects, **kwargs):
"""Creates a bulk request from a list of objects."""