Merge "Add retry on Conflict for manual speaker bind" into mcp/caracal
diff --git a/neutron_tempest_plugin/api/admin/test_quotas.py b/neutron_tempest_plugin/api/admin/test_quotas.py
index 0cf474e..8d96695 100644
--- a/neutron_tempest_plugin/api/admin/test_quotas.py
+++ b/neutron_tempest_plugin/api/admin/test_quotas.py
@@ -12,6 +12,7 @@
# 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 time
from tempest.common import utils
from tempest.lib import decorators
@@ -50,6 +51,8 @@
def _create_network(self, project_id):
network = self.create_network(client=self.admin_client,
tenant_id=project_id)
+ # Give some time to setup internal ports
+ time.sleep(CONF.neutron_plugin_options.internal_port_setup_delay)
self.addCleanup(self.admin_client.delete_network,
network['id'])
return network
@@ -87,7 +90,7 @@
new_quotas = {'network': 0, 'security_group': 0}
# Change quotas for tenant
- quota_set = self._setup_quotas(tenant_id, **new_quotas)
+ quota_set = self._setup_quotas(tenant_id, force=True, **new_quotas)
for key, value in new_quotas.items():
self.assertEqual(value, quota_set[key])
@@ -112,6 +115,23 @@
for q in non_default_quotas['quotas']:
self.assertNotEqual(tenant_id, q['tenant_id'])
+ @decorators.idempotent_id('43d01327-d8be-4773-a8f0-1d2e9664fda2')
+ @decorators.attr(type='gate')
+ @utils.requires_ext(extension='quota-check-limit-default',
+ service='network')
+ def test_quotas_force_false(self):
+ project_id = self.create_project()['id']
+ self._create_network(project_id)
+
+ new_quotas = {'network': 0}
+ # force=false (by default)
+ self.assertRaises(lib_exc.BadRequest, self.admin_client.update_quotas,
+ project_id, **new_quotas)
+
+ new_quotas['network'] = 100
+ quota_set = self._setup_quotas(project_id, **new_quotas)
+ self.assertEqual(new_quotas['network'], quota_set['network'])
+
@decorators.idempotent_id('e974b5ba-090a-452c-a578-f9710151d9fc')
@decorators.attr(type='gate')
@utils.requires_ext(extension="quota_details", service="network")
diff --git a/neutron_tempest_plugin/api/admin/test_quotas_negative.py b/neutron_tempest_plugin/api/admin/test_quotas_negative.py
index 9c37d92..ae7c60f 100644
--- a/neutron_tempest_plugin/api/admin/test_quotas_negative.py
+++ b/neutron_tempest_plugin/api/admin/test_quotas_negative.py
@@ -13,6 +13,7 @@
from neutron_lib import constants
from tempest.common import utils
from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -24,6 +25,13 @@
class QuotasAdminNegativeTestJSON(test_quotas.QuotasTestBase):
+ def wait_network_ports(self, network_id, number):
+ def _wait_ports(network_id, number):
+ ports = self.admin_client.list_ports(
+ network_id=network_id)
+ return len(ports) == number
+ test_utils.call_until_true(_wait_ports, 90, 5, network_id, number)
+
@decorators.attr(type='negative')
@decorators.idempotent_id('952f9b24-9156-4bdc-90f3-682a3d4302f0')
def test_create_network_when_quotas_is_full(self):
@@ -74,6 +82,9 @@
'cidr': '10.0.0.0/24',
'ip_version': '4'}
subnet = self.admin_client.create_subnet(**subnet_args)['subnet']
+ self.wait_network_ports(subnet["network_id"],
+ CONF.network.service_ports_number)
+
self.addCleanup(self.admin_client.delete_subnet, subnet['id'])
ports = self.admin_client.list_ports(tenant_id=tenant_id)
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index 5a1de9c..0897c35 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -1225,6 +1225,16 @@
client = client or ndp_proxy.get('client') or cls.client
client.delete_ndp_proxy(ndp_proxy['id'])
+ @classmethod
+ def get_loaded_network_extensions(cls):
+ """Return the network service loaded extensions
+
+ :return: list of strings with the alias of the network service loaded
+ extensions.
+ """
+ body = cls.client.list_extensions()
+ return [net_ext['alias'] for net_ext in body['extensions']]
+
class BaseAdminNetworkTest(BaseNetworkTest):
@@ -1460,6 +1470,10 @@
def _extract_resources(cls, body):
return body[cls.plural_name]
+ @classmethod
+ def _test_resources(cls, resources):
+ return [res for res in resources if res["name"] in cls.resource_names]
+
def _test_list_sorts(self, direction):
sort_args = {
'sort_dir': direction,
@@ -1511,11 +1525,12 @@
'sort_key': self.field
}
body = self.list_method(**sort_args)
- expected_resources = self._extract_resources(body)
+ total_resources = self._extract_resources(body)
+ expected_resources = self._test_resources(total_resources)
self.assertNotEmpty(expected_resources)
resources = lister(
- len(expected_resources), sort_args
+ len(total_resources), sort_args
)
# finally, compare that the list retrieved in one go is identical to
@@ -1533,9 +1548,11 @@
pagination_args['marker'] = resources[-1]['id']
body = self.list_method(**pagination_args)
resources_ = self._extract_resources(body)
- self.assertEqual(1, len(resources_))
+ # Empty resource list can be returned when any concurrent
+ # tests delete them
+ self.assertGreaterEqual(1, len(resources_))
resources.extend(resources_)
- return resources
+ return self._test_resources(resources)
@_require_pagination
@_require_sorting
@@ -1558,8 +1575,10 @@
self.plural_name, uri
)
resources_ = self._extract_resources(body)
- self.assertEqual(1, len(resources_))
- resources.extend(resources_)
+ # Empty resource list can be returned when any concurrent
+ # tests delete them
+ self.assertGreaterEqual(1, len(resources_))
+ resources.extend(self._test_resources(resources_))
# The last element is empty and does not contain 'next' link
uri = self.get_bare_url(prev_links['next'])
@@ -1576,8 +1595,10 @@
self.plural_name, uri
)
resources_ = self._extract_resources(body)
- self.assertEqual(1, len(resources_))
- resources2.extend(resources_)
+ # Empty resource list can be returned when any concurrent
+ # tests delete them
+ self.assertGreaterEqual(1, len(resources_))
+ resources2.extend(self._test_resources(resources_))
self.assertSameOrder(resources, reversed(resources2))
@@ -1597,14 +1618,15 @@
'sort_key': self.field,
}
body = self.list_method(**pagination_args)
- expected_resources = self._extract_resources(body)
+ total_resources = self._extract_resources(body)
+ expected_resources = self._test_resources(total_resources)
page_size = 2
pagination_args['limit'] = page_size
prev_links = {}
resources = []
- num_resources = len(expected_resources)
+ num_resources = len(total_resources)
niterations = int(math.ceil(float(num_resources) / page_size))
for i in range(niterations):
if prev_links:
@@ -1616,7 +1638,7 @@
prev_links, body = self.list_client.get_uri_with_links(
self.plural_name, uri
)
- resources_ = self._extract_resources(body)
+ resources_ = self._test_resources(self._extract_resources(body))
self.assertGreaterEqual(page_size, len(resources_))
resources.extend(reversed(resources_))
diff --git a/neutron_tempest_plugin/api/test_security_groups.py b/neutron_tempest_plugin/api/test_security_groups.py
index 4f39cc6..c3b5f11 100644
--- a/neutron_tempest_plugin/api/test_security_groups.py
+++ b/neutron_tempest_plugin/api/test_security_groups.py
@@ -284,9 +284,10 @@
def _set_quota(self, val, resource):
res_quota = self._get_quota(resource)
project_id = self.client.project_id
- self.admin_client.update_quotas(project_id, **{resource: val})
+ self.admin_client.update_quotas(project_id, **{resource: val,
+ 'force': True})
self.addCleanup(self.admin_client.update_quotas,
- project_id, **{resource: res_quota})
+ project_id, **{resource: res_quota, 'force': True})
def _get_quota(self, resource):
project_id = self.client.project_id
@@ -386,7 +387,8 @@
def _set_sg_rules_quota(self, val):
project_id = self.client.project_id
self.admin_client.update_quotas(project_id,
- **{'security_group_rule': val})
+ **{'security_group_rule': val,
+ 'force': True})
LOG.info('Trying to update security group rule quota {} '.format(val))
def _get_sg_rules_quota(self):
@@ -438,7 +440,8 @@
sg_rules_quota = self._get_sg_rules_quota()
project_id = self.client.project_id
self.addCleanup(self.admin_client.update_quotas,
- project_id, **{'security_group_rule': sg_rules_quota})
+ project_id, **{'security_group_rule': sg_rules_quota,
+ 'force': True})
values = [-1, 0, 10, 2147483647]
for value in values:
self._set_sg_rules_quota(value)
diff --git a/neutron_tempest_plugin/api/test_subnets.py b/neutron_tempest_plugin/api/test_subnets.py
index 3b075d5..663713c 100644
--- a/neutron_tempest_plugin/api/test_subnets.py
+++ b/neutron_tempest_plugin/api/test_subnets.py
@@ -24,6 +24,8 @@
@classmethod
def resource_setup(cls):
+ if 'subnet-external-network' in cls.get_loaded_network_extensions():
+ cls.list_kwargs['router:external'] = False
super(SubnetsSearchCriteriaTest, cls).resource_setup()
net = cls.create_network(network_name='subnet-search-test-net')
for name in cls.resource_names:
@@ -67,6 +69,8 @@
@decorators.idempotent_id('c0f9280b-9d81-4728-a967-6be22659d4c8')
def test_list_validation_filters(self):
+ if 'subnet-external-network' in self.get_loaded_network_extensions():
+ self.list_kwargs['router:external'] = False
self._test_list_validation_filters(self.list_kwargs)
self._test_list_validation_filters({
'unknown_filter': 'value'}, filter_is_valid=False)
diff --git a/neutron_tempest_plugin/bgpvpn/scenario/manager.py b/neutron_tempest_plugin/bgpvpn/scenario/manager.py
index f5e9bf2..b65407d 100644
--- a/neutron_tempest_plugin/bgpvpn/scenario/manager.py
+++ b/neutron_tempest_plugin/bgpvpn/scenario/manager.py
@@ -241,10 +241,14 @@
if not subnets_client:
subnets_client = self.subnets_client
tenant_cidr = kwargs.get('cidr')
+ # reserving pool for Neutron service ports
+ net = netaddr.IPNetwork(tenant_cidr)
+ allocation_pools = [{'start': str(net[2]), 'end': str(net[9])}]
subnet = dict(
name=data_utils.rand_name(namestart),
network_id=network['id'],
tenant_id=network['tenant_id'],
+ allocation_pools=allocation_pools,
**kwargs)
result = subnets_client.create_subnet(**subnet)
self.assertIsNotNone(result, 'Unable to allocate tenant network')
diff --git a/neutron_tempest_plugin/config.py b/neutron_tempest_plugin/config.py
index 3f8ccd5..016299b 100644
--- a/neutron_tempest_plugin/config.py
+++ b/neutron_tempest_plugin/config.py
@@ -151,6 +151,10 @@
cfg.BoolOpt('bgp_schedule_speakers_to_agents',
default=False,
help='Schedule BGP speakers to agents explicitly.'),
+ cfg.IntOpt('internal_port_setup_delay',
+ default=5,
+ help='Number of seconds to wait after network create to '
+ 'setup internal ports.'),
]
# TODO(amuller): Redo configuration options registration as part of the planned
diff --git a/neutron_tempest_plugin/scenario/test_dns_integration.py b/neutron_tempest_plugin/scenario/test_dns_integration.py
index 3047c4d..fa859b8 100644
--- a/neutron_tempest_plugin/scenario/test_dns_integration.py
+++ b/neutron_tempest_plugin/scenario/test_dns_integration.py
@@ -64,7 +64,7 @@
def setup_clients(cls):
super(BaseDNSIntegrationTests, cls).setup_clients()
cls.dns_client = cls.os_tempest.dns_v2.ZonesClient()
- cls.query_client.build_timeout = 60
+ cls.query_client.build_timeout = CONF.dns.build_timeout
if CONF.enforce_scope.designate:
cls.admin_tld_client = cls.os_system_admin.dns_v2.TldClient()
cls.rec_client = cls.os_system_admin.dns_v2.RecordsetClient()
diff --git a/neutron_tempest_plugin/scenario/test_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index 4c68dae..340a6be 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -239,9 +239,13 @@
self.os_primary.interfaces_client, server['server']['id'],
port['id'], lib_constants.PORT_STATUS_ACTIVE)
fip = self.client.show_floatingip(fip['id'])['floatingip']
+ server_data = self.os_admin.servers_client.show_server(
+ server['server']['id'])['server']
+ zone = 'compute:' + server_data['OS-EXT-AZ:availability_zone']
self._check_port_details(
fip, port, status=lib_constants.PORT_STATUS_ACTIVE,
- device_id=server['server']['id'], device_owner='compute:nova')
+ device_id=server['server']['id'],
+ device_owner=zone)
LOG.debug('Port check for server %s and FIP %s finished, '
'lets detach port %s from server!',
server['server']['id'], fip['id'], port['id'])
diff --git a/neutron_tempest_plugin/scenario/test_security_groups.py b/neutron_tempest_plugin/scenario/test_security_groups.py
index ae6c57d..dc92342 100644
--- a/neutron_tempest_plugin/scenario/test_security_groups.py
+++ b/neutron_tempest_plugin/scenario/test_security_groups.py
@@ -579,6 +579,9 @@
# configure sec groups to support SSH connectivity
self.create_loginable_secgroup_rule(
secgroup_id=secgroups[-1]['id'])
+ # add the initial metadata access rule if VMs are not booted yet
+ self.create_ingress_metadata_secgroup_rule(
+ secgroup_id=secgroups[-1]['id'])
# Configure security groups, first two servers as remotes
for i, server in enumerate(servers):
diff --git a/requirements.txt b/requirements.txt
index 481bb7f..029edf6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -18,3 +18,4 @@
eventlet!=0.18.3,!=0.20.1,>=0.18.2 # MIT
debtcollector>=1.2.0 # Apache-2.0
docker # Apache-2.0
+Jinja2 # BSD License (3 clause)