Remove the bundled intree neutron tempest plugin
The plugin has been split into its own repository[1] in accordance with Queens Goal "Split Tempest Plugins into Separate Repos/Projects[2]". This patch removes the local copy as well as the setuptools entry point. We can also now remove the autodoc_tree_excludes pbr option since there's no more plugin to exclude and it defaults to [setup.py]. The patch leaves still in-tree base classes and constants in order to avoid breakage of projects depending on such code. In the future, we will deprecate those and gradually move affected subprojects to the new repo. List of affected repositories: - neutron-vpnaas - openstack-ansible-os_neutron - tripleo-quickstart-extras - networking-midonet - networking-l2gw - neutron-dynamic-routing - networking-vsphere - networking-plumgrid - networking-zvm [1] http://git.openstack.org/cgit/openstack/neutron-tempest-plugin [2] https://governance.openstack.org/tc/goals/queens/split-tempest-plugins.html Depends-On: I371aa4d5f043f695df04b98b0f485c8f0548f2b3 Change-Id: Ia21aad29d0bbf779583964db6f1665c9b3b83161
This commit is contained in:
parent
618ee8658f
commit
813295f8cf
@ -1,9 +0,0 @@
|
||||
WARNING
|
||||
=======
|
||||
|
||||
Some files under this path were copied from tempest as part of the move of the
|
||||
api tests, and they will be removed as required over time to minimize the
|
||||
dependency on the tempest testing framework. While it exists, only
|
||||
neutron.tests.tempest.* should be importing files from this path.
|
||||
neutron.tests.tempest.config uses the global cfg.CONF instance and importing it
|
||||
outside of the api tests has the potential to break Neutron's use of cfg.CONF.
|
@ -1,53 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from neutron_lib import constants
|
||||
from tempest.lib import decorators
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
AZ_SUPPORTED_AGENTS = [constants.AGENT_TYPE_DHCP, constants.AGENT_TYPE_L3]
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class AgentAvailabilityZoneTestCase(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['agent', 'availability_zone']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(AgentAvailabilityZoneTestCase, cls).resource_setup()
|
||||
body = cls.admin_client.list_agents()
|
||||
agents = body['agents']
|
||||
agents_type = [agent.get('agent_type') for agent in agents]
|
||||
for az_agent in AZ_SUPPORTED_AGENTS:
|
||||
if az_agent in agents_type:
|
||||
return
|
||||
msg = 'availability_zone supported agent not found.'
|
||||
raise cls.skipException(msg)
|
||||
|
||||
@decorators.idempotent_id('3ffa661e-cfcc-417d-8b63-1c5ec4a22e54')
|
||||
@testtools.skipUnless(CONF.neutron_plugin_options.agent_availability_zone,
|
||||
"Need a single availability_zone assumption.")
|
||||
def test_agents_availability_zone(self):
|
||||
"""
|
||||
Test list agents availability_zone, only L3 and DHCP agent support
|
||||
availability_zone, default availability_zone is "nova".
|
||||
"""
|
||||
body = self.admin_client.list_agents()
|
||||
agents = body['agents']
|
||||
for agent in agents:
|
||||
if agent.get('agent_type') in AZ_SUPPORTED_AGENTS:
|
||||
self.assertEqual(
|
||||
CONF.neutron_plugin_options.agent_availability_zone,
|
||||
agent.get('availability_zone'))
|
@ -1,90 +0,0 @@
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron.tests.tempest.common import tempest_fixtures
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class AgentManagementTestJSON(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['agent']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(AgentManagementTestJSON, cls).resource_setup()
|
||||
body = cls.admin_client.list_agents()
|
||||
agents = body['agents']
|
||||
cls.agent = agents[0] # don't modify this agent
|
||||
|
||||
@decorators.idempotent_id('9c80f04d-11f3-44a4-8738-ed2f879b0ff4')
|
||||
def test_list_agent(self):
|
||||
body = self.admin_client.list_agents()
|
||||
agents = body['agents']
|
||||
# Heartbeats must be excluded from comparison
|
||||
self.agent.pop('heartbeat_timestamp', None)
|
||||
self.agent.pop('configurations', None)
|
||||
for agent in agents:
|
||||
agent.pop('heartbeat_timestamp', None)
|
||||
agent.pop('configurations', None)
|
||||
self.assertIn(self.agent, agents)
|
||||
|
||||
@decorators.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
|
||||
def test_list_agents_non_admin(self):
|
||||
body = self.client.list_agents()
|
||||
self.assertEqual(len(body["agents"]), 0)
|
||||
|
||||
@decorators.idempotent_id('869bc8e8-0fda-4a30-9b71-f8a7cf58ca9f')
|
||||
def test_show_agent(self):
|
||||
body = self.admin_client.show_agent(self.agent['id'])
|
||||
agent = body['agent']
|
||||
self.assertEqual(agent['id'], self.agent['id'])
|
||||
|
||||
@decorators.idempotent_id('371dfc5b-55b9-4cb5-ac82-c40eadaac941')
|
||||
def test_update_agent_status(self):
|
||||
origin_status = self.agent['admin_state_up']
|
||||
# Try to update the 'admin_state_up' to the original
|
||||
# one to avoid the negative effect.
|
||||
agent_status = {'admin_state_up': origin_status}
|
||||
body = self.admin_client.update_agent(agent_id=self.agent['id'],
|
||||
agent_info=agent_status)
|
||||
updated_status = body['agent']['admin_state_up']
|
||||
self.assertEqual(origin_status, updated_status)
|
||||
|
||||
@decorators.idempotent_id('68a94a14-1243-46e6-83bf-157627e31556')
|
||||
def test_update_agent_description(self):
|
||||
agents = self.admin_client.list_agents()['agents']
|
||||
try:
|
||||
dyn_agent = agents[1]
|
||||
except IndexError:
|
||||
raise self.skipException("This test requires at least two agents.")
|
||||
|
||||
self.useFixture(tempest_fixtures.LockFixture('agent_description'))
|
||||
description = 'description for update agent.'
|
||||
agent_description = {'description': description}
|
||||
body = self.admin_client.update_agent(agent_id=dyn_agent['id'],
|
||||
agent_info=agent_description)
|
||||
self.addCleanup(self._restore_agent, dyn_agent)
|
||||
updated_description = body['agent']['description']
|
||||
self.assertEqual(updated_description, description)
|
||||
|
||||
def _restore_agent(self, dyn_agent):
|
||||
"""
|
||||
Restore the agent description after update test.
|
||||
"""
|
||||
description = dyn_agent['description']
|
||||
origin_agent = {'description': description}
|
||||
self.admin_client.update_agent(agent_id=dyn_agent['id'],
|
||||
agent_info=origin_agent)
|
@ -1,108 +0,0 @@
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib import constants
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.common import utils
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class DHCPAgentSchedulersTestJSON(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['dhcp_agent_scheduler']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(DHCPAgentSchedulersTestJSON, cls).resource_setup()
|
||||
# Create a network and make sure it will be hosted by a
|
||||
# dhcp agent: this is done by creating a regular port
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
cls.cidr = cls.subnet['cidr']
|
||||
cls.port = cls.create_port(cls.network)
|
||||
|
||||
@decorators.idempotent_id('f164801e-1dd8-4b8b-b5d3-cc3ac77cfaa5')
|
||||
def test_dhcp_port_status_active(self):
|
||||
|
||||
def dhcp_port_active():
|
||||
for p in self.client.list_ports(
|
||||
network_id=self.network['id'])['ports']:
|
||||
if (p['device_owner'] == constants.DEVICE_OWNER_DHCP and
|
||||
p['status'] == constants.PORT_STATUS_ACTIVE):
|
||||
return True
|
||||
return False
|
||||
utils.wait_until_true(dhcp_port_active)
|
||||
|
||||
@decorators.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
|
||||
def test_list_dhcp_agent_hosting_network(self):
|
||||
self.admin_client.list_dhcp_agent_hosting_network(
|
||||
self.network['id'])
|
||||
|
||||
@decorators.idempotent_id('30c48f98-e45d-4ffb-841c-b8aad57c7587')
|
||||
def test_list_networks_hosted_by_one_dhcp(self):
|
||||
body = self.admin_client.list_dhcp_agent_hosting_network(
|
||||
self.network['id'])
|
||||
agents = body['agents']
|
||||
self.assertIsNotNone(agents)
|
||||
agent = agents[0]
|
||||
self.assertTrue(self._check_network_in_dhcp_agent(
|
||||
self.network['id'], agent))
|
||||
|
||||
def _check_network_in_dhcp_agent(self, network_id, agent):
|
||||
network_ids = []
|
||||
body = self.admin_client.list_networks_hosted_by_one_dhcp_agent(
|
||||
agent['id'])
|
||||
networks = body['networks']
|
||||
for network in networks:
|
||||
network_ids.append(network['id'])
|
||||
return network_id in network_ids
|
||||
|
||||
@decorators.idempotent_id('a0856713-6549-470c-a656-e97c8df9a14d')
|
||||
def test_add_remove_network_from_dhcp_agent(self):
|
||||
# The agent is now bound to the network, we can free the port
|
||||
self.client.delete_port(self.port['id'])
|
||||
self.ports.remove(self.port)
|
||||
agent = dict()
|
||||
agent['agent_type'] = None
|
||||
body = self.admin_client.list_agents()
|
||||
agents = body['agents']
|
||||
for a in agents:
|
||||
if a['agent_type'] == 'DHCP agent':
|
||||
agent = a
|
||||
break
|
||||
self.assertEqual(agent['agent_type'], 'DHCP agent', 'Could not find '
|
||||
'DHCP agent in agent list though dhcp_agent_scheduler'
|
||||
' is enabled.')
|
||||
network = self.create_network()
|
||||
network_id = network['id']
|
||||
if self._check_network_in_dhcp_agent(network_id, agent):
|
||||
self._remove_network_from_dhcp_agent(network_id, agent)
|
||||
self._add_dhcp_agent_to_network(network_id, agent)
|
||||
else:
|
||||
self._add_dhcp_agent_to_network(network_id, agent)
|
||||
self._remove_network_from_dhcp_agent(network_id, agent)
|
||||
|
||||
def _remove_network_from_dhcp_agent(self, network_id, agent):
|
||||
self.admin_client.remove_network_from_dhcp_agent(
|
||||
agent_id=agent['id'],
|
||||
network_id=network_id)
|
||||
self.assertFalse(self._check_network_in_dhcp_agent(
|
||||
network_id, agent))
|
||||
|
||||
def _add_dhcp_agent_to_network(self, network_id, agent):
|
||||
self.admin_client.add_dhcp_agent_to_network(agent['id'],
|
||||
network_id)
|
||||
self.assertTrue(self._check_network_in_dhcp_agent(
|
||||
network_id, agent))
|
@ -1,35 +0,0 @@
|
||||
# Copyright 2015 Cisco Systems, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest.api import base_security_groups as base_security
|
||||
|
||||
|
||||
class PortSecurityAdminTests(base_security.BaseSecGroupTest,
|
||||
base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['port-security']
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('d39a96e2-2dea-4feb-8093-e7ac991ce6f8')
|
||||
def test_create_port_security_false_on_shared_network(self):
|
||||
network = self.create_shared_network()
|
||||
self.assertTrue(network['shared'])
|
||||
self.create_subnet(network, client=self.admin_client)
|
||||
self.assertRaises(lib_exc.Forbidden, self.create_port,
|
||||
network, port_security_enabled=False)
|
@ -1,196 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class ExternalNetworksRBACTestJSON(base.BaseAdminNetworkTest):
|
||||
|
||||
credentials = ['primary', 'alt', 'admin']
|
||||
required_extensions = ['rbac-policies']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(ExternalNetworksRBACTestJSON, cls).resource_setup()
|
||||
cls.client2 = cls.os_alt.network_client
|
||||
|
||||
def _create_network(self, external=True):
|
||||
post_body = {'name': data_utils.rand_name('network')}
|
||||
if external:
|
||||
post_body['router:external'] = external
|
||||
body = self.admin_client.create_network(**post_body)
|
||||
network = body['network']
|
||||
self.addCleanup(self.admin_client.delete_network, network['id'])
|
||||
return network
|
||||
|
||||
@decorators.idempotent_id('afd8f1b7-a81e-4629-bca8-a367b3a144bb')
|
||||
def test_regular_client_shares_with_another(self):
|
||||
net = self.create_network()
|
||||
self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant=self.client2.tenant_id)
|
||||
body = self.client2.list_networks()
|
||||
networks_list = [n['id'] for n in body['networks']]
|
||||
self.assertIn(net['id'], networks_list)
|
||||
r = self.client2.create_router(
|
||||
data_utils.rand_name('router'),
|
||||
external_gateway_info={'network_id': net['id']})['router']
|
||||
self.addCleanup(self.admin_client.delete_router, r['id'])
|
||||
|
||||
@decorators.idempotent_id('eff9443a-2d04-48ee-840e-d955ac564bcd')
|
||||
def test_regular_client_blocked_from_creating_external_wild_policies(self):
|
||||
net = self.create_network()
|
||||
with testtools.ExpectedException(lib_exc.Forbidden):
|
||||
self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant='*')
|
||||
|
||||
@decorators.idempotent_id('a2e19f06-48a9-4e4c-b717-08cb2008707d')
|
||||
def test_wildcard_policy_created_from_external_network_api(self):
|
||||
# create external makes wildcard
|
||||
net_id = self._create_network(external=True)['id']
|
||||
self.assertEqual(1, len(self.admin_client.list_rbac_policies(
|
||||
object_id=net_id, action='access_as_external',
|
||||
target_tenant='*')['rbac_policies']))
|
||||
# update to non-external clears wildcard
|
||||
self.admin_client.update_network(net_id, **{'router:external': False})
|
||||
self.assertEqual(0, len(self.admin_client.list_rbac_policies(
|
||||
object_id=net_id, action='access_as_external',
|
||||
target_tenant='*')['rbac_policies']))
|
||||
# create non-external has no wildcard
|
||||
net_id = self._create_network(external=False)['id']
|
||||
self.assertEqual(0, len(self.admin_client.list_rbac_policies(
|
||||
object_id=net_id, action='access_as_external',
|
||||
target_tenant='*')['rbac_policies']))
|
||||
# update to external makes wildcard
|
||||
self.admin_client.update_network(net_id, **{'router:external': True})
|
||||
self.assertEqual(1, len(self.admin_client.list_rbac_policies(
|
||||
object_id=net_id, action='access_as_external',
|
||||
target_tenant='*')['rbac_policies']))
|
||||
|
||||
@decorators.idempotent_id('a5539002-5bdb-48b5-b124-abcd12347865')
|
||||
def test_external_update_policy_from_wildcard_to_specific_tenant(self):
|
||||
net_id = self._create_network(external=True)['id']
|
||||
rbac_pol = self.admin_client.list_rbac_policies(
|
||||
object_id=net_id, action='access_as_external',
|
||||
target_tenant='*')['rbac_policies'][0]
|
||||
r = self.client2.create_router(
|
||||
data_utils.rand_name('router'),
|
||||
external_gateway_info={'network_id': net_id})['router']
|
||||
self.addCleanup(self.admin_client.delete_router, r['id'])
|
||||
# changing wildcard to specific tenant should be okay since its the
|
||||
# only one using the network
|
||||
self.admin_client.update_rbac_policy(
|
||||
rbac_pol['id'], target_tenant=self.client2.tenant_id)
|
||||
|
||||
@decorators.idempotent_id('a5539002-5bdb-48b5-b124-e9eedd5975e6')
|
||||
def test_external_conversion_on_policy_create(self):
|
||||
net_id = self._create_network(external=False)['id']
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net_id,
|
||||
action='access_as_external',
|
||||
target_tenant=self.client2.tenant_id)
|
||||
body = self.admin_client.show_network(net_id)['network']
|
||||
self.assertTrue(body['router:external'])
|
||||
|
||||
@decorators.idempotent_id('01364c50-bfb6-46c4-b44c-edc4564d61cf')
|
||||
def test_policy_allows_tenant_to_allocate_floatingip(self):
|
||||
net = self._create_network(external=False)
|
||||
# share to the admin client so it gets converted to external but
|
||||
# not shared to everyone
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant=self.admin_client.tenant_id)
|
||||
self.create_subnet(net, client=self.admin_client, enable_dhcp=False)
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
self.client2.create_floatingip(
|
||||
floating_network_id=net['id'])
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant=self.client2.tenant_id)
|
||||
self.client2.create_floatingip(
|
||||
floating_network_id=net['id'])
|
||||
|
||||
@decorators.idempotent_id('476be1e0-f72e-47dc-9a14-4435926bbe82')
|
||||
def test_policy_allows_tenant_to_attach_ext_gw(self):
|
||||
net = self._create_network(external=False)
|
||||
self.create_subnet(net, client=self.admin_client, enable_dhcp=False)
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant=self.client2.tenant_id)
|
||||
r = self.client2.create_router(
|
||||
data_utils.rand_name('router'),
|
||||
external_gateway_info={'network_id': net['id']})['router']
|
||||
self.addCleanup(self.admin_client.delete_router, r['id'])
|
||||
|
||||
@decorators.idempotent_id('d54decee-4203-4ced-91a2-ea42ca63e154')
|
||||
def test_delete_policies_while_tenant_attached_to_net(self):
|
||||
net = self._create_network(external=False)
|
||||
self.create_subnet(net, client=self.admin_client, enable_dhcp=False)
|
||||
wildcard = self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant='*')['rbac_policy']
|
||||
r = self.client2.create_router(
|
||||
data_utils.rand_name('router'),
|
||||
external_gateway_info={'network_id': net['id']})['router']
|
||||
# delete should fail because the wildcard is required for the tenant's
|
||||
# access
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.delete_rbac_policy(wildcard['id'])
|
||||
tenant = self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant=self.client2.tenant_id)['rbac_policy']
|
||||
# now we can delete the policy because the tenant has its own policy
|
||||
# to allow it access
|
||||
self.admin_client.delete_rbac_policy(wildcard['id'])
|
||||
# but now we can't delete the tenant's policy without the wildcard
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.delete_rbac_policy(tenant['id'])
|
||||
wildcard = self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_external',
|
||||
target_tenant='*')['rbac_policy']
|
||||
# with the wildcard added back we can delete the tenant's policy
|
||||
self.admin_client.delete_rbac_policy(tenant['id'])
|
||||
self.admin_client.delete_router(r['id'])
|
||||
# now without the tenant attached, the wildcard can be deleted
|
||||
self.admin_client.delete_rbac_policy(wildcard['id'])
|
||||
# finally we ensure that the tenant can't attach to the network since
|
||||
# there are no policies allowing it
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
self.client2.create_router(
|
||||
data_utils.rand_name('router'),
|
||||
external_gateway_info={'network_id': net['id']})
|
||||
|
||||
@decorators.idempotent_id('7041cec7-d8fe-4c78-9b04-b51b2fd49dc9')
|
||||
def test_wildcard_policy_delete_blocked_on_default_ext(self):
|
||||
public_net_id = cfg.CONF.network.public_network_id
|
||||
# ensure it is default before so we don't wipe out the policy
|
||||
self.admin_client.update_network(public_net_id, is_default=True)
|
||||
policy = self.admin_client.list_rbac_policies(
|
||||
object_id=public_net_id, action='access_as_external',
|
||||
target_tenant='*')['rbac_policies'][0]
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.delete_rbac_policy(policy['id'])
|
@ -1,83 +0,0 @@
|
||||
# Copyright 2014 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class FloatingIPAdminTestJSON(base.BaseAdminNetworkTest):
|
||||
force_tenant_isolation = True
|
||||
credentials = ['primary', 'alt', 'admin']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(FloatingIPAdminTestJSON, cls).resource_setup()
|
||||
cls.ext_net_id = CONF.network.public_network_id
|
||||
cls.floating_ip = cls.create_floatingip(cls.ext_net_id)
|
||||
cls.alt_client = cls.os_alt.network_client
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
cls.router = cls.create_router(data_utils.rand_name('router'),
|
||||
external_network_id=cls.ext_net_id)
|
||||
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
|
||||
cls.port = cls.create_port(cls.network)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('11116ee9-4e99-5b15-b8e1-aa7df92ca589')
|
||||
def test_associate_floating_ip_with_port_from_another_project(self):
|
||||
body = self.client.create_floatingip(
|
||||
floating_network_id=self.ext_net_id)
|
||||
floating_ip = body['floatingip']
|
||||
project_id = self.create_project()['id']
|
||||
|
||||
port = self.admin_client.create_port(network_id=self.network['id'],
|
||||
project_id=project_id)
|
||||
self.addCleanup(self.admin_client.delete_port, port['port']['id'])
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.update_floatingip,
|
||||
floating_ip['id'], port_id=port['port']['id'])
|
||||
|
||||
@testtools.skipUnless(
|
||||
CONF.neutron_plugin_options.specify_floating_ip_address_available,
|
||||
"Feature for specifying floating IP address is disabled")
|
||||
@decorators.idempotent_id('332a8ae4-402e-4b98-bb6f-532e5a87b8e0')
|
||||
def test_create_floatingip_with_specified_ip_address(self):
|
||||
# other tests may end up stealing the IP before we can use it
|
||||
# since it's on the external network so we need to retry if it's
|
||||
# in use.
|
||||
for i in range(100):
|
||||
fip = self.get_unused_ip(self.ext_net_id, ip_version=4)
|
||||
try:
|
||||
body = self.admin_client.create_floatingip(
|
||||
floating_network_id=self.ext_net_id,
|
||||
floating_ip_address=fip)
|
||||
break
|
||||
except lib_exc.Conflict:
|
||||
pass
|
||||
else:
|
||||
self.fail("Could not get an unused IP after 100 attempts")
|
||||
created_floating_ip = body['floatingip']
|
||||
self.addCleanup(self.admin_client.delete_floatingip,
|
||||
created_floating_ip['id'])
|
||||
self.assertIsNotNone(created_floating_ip['id'])
|
||||
self.assertIsNotNone(created_floating_ip['tenant_id'])
|
||||
self.assertEqual(created_floating_ip['floating_ip_address'], fip)
|
@ -1,85 +0,0 @@
|
||||
# Copyright 2013 IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import exceptions
|
||||
|
||||
AGENT_TYPE = 'L3 agent'
|
||||
AGENT_MODES = (
|
||||
'legacy',
|
||||
'dvr_snat'
|
||||
)
|
||||
|
||||
|
||||
class L3AgentSchedulerTestJSON(base.BaseAdminNetworkTest):
|
||||
_agent_mode = 'legacy'
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
Neutron:
|
||||
|
||||
List routers that the given L3 agent is hosting.
|
||||
List L3 agents hosting the given router.
|
||||
Add and Remove Router to L3 agent
|
||||
|
||||
v2.0 of the Neutron API is assumed.
|
||||
|
||||
The l3_agent_scheduler extension is required for these tests.
|
||||
"""
|
||||
|
||||
required_extensions = ['l3_agent_scheduler']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(L3AgentSchedulerTestJSON, cls).resource_setup()
|
||||
body = cls.admin_client.list_agents()
|
||||
agents = body['agents']
|
||||
for agent in agents:
|
||||
# TODO(armax): falling back on default _agent_mode can be
|
||||
# dropped as soon as Icehouse is dropped.
|
||||
agent_mode = (
|
||||
agent['configurations'].get('agent_mode', cls._agent_mode))
|
||||
if agent['agent_type'] == AGENT_TYPE and agent_mode in AGENT_MODES:
|
||||
cls.agent = agent
|
||||
break
|
||||
else:
|
||||
msg = "L3 Agent Scheduler enabled in conf, but L3 Agent not found"
|
||||
raise exceptions.InvalidConfiguration(msg)
|
||||
cls.router = cls.create_router(data_utils.rand_name('router'))
|
||||
|
||||
@decorators.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
|
||||
def test_list_routers_on_l3_agent(self):
|
||||
self.admin_client.list_routers_on_l3_agent(self.agent['id'])
|
||||
|
||||
@decorators.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
|
||||
def test_add_list_remove_router_on_l3_agent(self):
|
||||
l3_agent_ids = list()
|
||||
self.admin_client.add_router_to_l3_agent(
|
||||
self.agent['id'],
|
||||
self.router['id'])
|
||||
body = (
|
||||
self.admin_client.list_l3_agents_hosting_router(self.router['id']))
|
||||
for agent in body['agents']:
|
||||
l3_agent_ids.append(agent['id'])
|
||||
self.assertIn('agent_type', agent)
|
||||
self.assertEqual('L3 agent', agent['agent_type'])
|
||||
self.assertIn(self.agent['id'], l3_agent_ids)
|
||||
body = self.admin_client.remove_router_from_l3_agent(
|
||||
self.agent['id'],
|
||||
self.router['id'])
|
||||
# NOTE(afazekas): The deletion not asserted, because neutron
|
||||
# is not forbidden to reschedule the router to the same agent
|
@ -1,87 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import testtools
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
|
||||
class NetworksTestAdmin(base.BaseAdminNetworkTest):
|
||||
|
||||
@decorators.idempotent_id('d3c76044-d067-4cb0-ae47-8cdd875c7f67')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_admin_create_network_keystone_v3(self):
|
||||
project_id = self.client.tenant_id # non-admin
|
||||
|
||||
name = 'admin-created-with-project_id'
|
||||
new_net = self.create_network_keystone_v3(name, project_id,
|
||||
client=self.admin_client)
|
||||
self.assertEqual(name, new_net['name'])
|
||||
self.assertEqual(project_id, new_net['project_id'])
|
||||
self.assertEqual(project_id, new_net['tenant_id'])
|
||||
|
||||
body = self.client.list_networks(id=new_net['id'])
|
||||
lookup_net = body['networks'][0]
|
||||
self.assertEqual(name, lookup_net['name'])
|
||||
self.assertEqual(project_id, lookup_net['project_id'])
|
||||
self.assertEqual(project_id, lookup_net['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('8d21aaca-4364-4eb9-8b79-44b4fff6373b')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_admin_create_network_keystone_v3_and_tenant(self):
|
||||
project_id = self.client.tenant_id # non-admin
|
||||
|
||||
name = 'created-with-project-and-tenant'
|
||||
new_net = self.create_network_keystone_v3(
|
||||
name, project_id, tenant_id=project_id, client=self.admin_client)
|
||||
self.assertEqual(name, new_net['name'])
|
||||
self.assertEqual(project_id, new_net['project_id'])
|
||||
self.assertEqual(project_id, new_net['tenant_id'])
|
||||
|
||||
body = self.client.list_networks(id=new_net['id'])
|
||||
lookup_net = body['networks'][0]
|
||||
self.assertEqual(name, lookup_net['name'])
|
||||
self.assertEqual(project_id, lookup_net['project_id'])
|
||||
self.assertEqual(project_id, lookup_net['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('08b92179-669d-45ee-8233-ef6611190809')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_admin_create_network_keystone_v3_and_other_tenant(self):
|
||||
project_id = self.client.tenant_id # non-admin
|
||||
other_tenant = uuidutils.generate_uuid()
|
||||
|
||||
name = 'created-with-project-and-other-tenant'
|
||||
e = self.assertRaises(lib_exc.BadRequest,
|
||||
self.create_network_keystone_v3, name,
|
||||
project_id, tenant_id=other_tenant,
|
||||
client=self.admin_client)
|
||||
expected_message = "'project_id' and 'tenant_id' do not match"
|
||||
self.assertEqual(expected_message, e.resp_body['message'])
|
||||
|
||||
@decorators.idempotent_id('571d0dde-0f84-11e7-b565-fa163e4fa634')
|
||||
@testtools.skipUnless("vxlan" in config.CONF.neutron_plugin_options.
|
||||
available_type_drivers,
|
||||
'VXLAN type_driver is not enabled')
|
||||
@utils.requires_ext(extension="provider", service="network")
|
||||
def test_create_tenant_network_vxlan(self):
|
||||
network = self.admin_client.create_network(
|
||||
**{"provider:network_type": "vxlan"})['network']
|
||||
self.addCleanup(self.admin_client.delete_network,
|
||||
network['id'])
|
||||
network = self.admin_client.show_network(
|
||||
network['id'])['network']
|
||||
self.assertEqual('vxlan', network['provider:network_type'])
|
@ -1,150 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class QuotasTestBase(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['quotas']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(QuotasTestBase, cls).resource_setup()
|
||||
|
||||
def _setup_quotas(self, project_id, **new_quotas):
|
||||
# Change quotas for tenant
|
||||
quota_set = self.admin_client.update_quotas(project_id,
|
||||
**new_quotas)
|
||||
self.addCleanup(self._cleanup_quotas, project_id)
|
||||
return quota_set
|
||||
|
||||
def _cleanup_quotas(self, project_id):
|
||||
# Try to clean up the resources. If it fails, then
|
||||
# assume that everything was already deleted, so
|
||||
# it is OK to continue.
|
||||
try:
|
||||
self.admin_client.reset_quotas(project_id)
|
||||
except lib_exc.NotFound:
|
||||
pass
|
||||
|
||||
def _create_network(self, project_id):
|
||||
network = self.create_network(client=self.admin_client,
|
||||
tenant_id=project_id)
|
||||
self.addCleanup(self.admin_client.delete_network,
|
||||
network['id'])
|
||||
return network
|
||||
|
||||
def _create_port(self, **kwargs):
|
||||
port = self.admin_client.create_port(**kwargs)['port']
|
||||
self.addCleanup(self.admin_client.delete_port,
|
||||
port['id'])
|
||||
return port
|
||||
|
||||
|
||||
class QuotasTest(QuotasTestBase):
|
||||
"""Test the Neutron API of Quotas.
|
||||
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
Neutron:
|
||||
|
||||
list quotas for tenants who have non-default quota values
|
||||
show quotas for a specified tenant
|
||||
show detail quotas for a specified tenant
|
||||
update quotas for a specified tenant
|
||||
reset quotas to default values for a specified tenant
|
||||
|
||||
v2.0 of the API is assumed.
|
||||
It is also assumed that the per-tenant quota extension API is configured
|
||||
in /etc/neutron/neutron.conf as follows:
|
||||
|
||||
quota_driver = neutron.db.driver.DbQuotaDriver
|
||||
"""
|
||||
|
||||
@decorators.attr(type='gate')
|
||||
@decorators.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
|
||||
def test_quotas(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
new_quotas = {'network': 0, 'security_group': 0}
|
||||
|
||||
# Change quotas for tenant
|
||||
quota_set = self._setup_quotas(tenant_id, **new_quotas)
|
||||
for key, value in new_quotas.items():
|
||||
self.assertEqual(value, quota_set[key])
|
||||
|
||||
# Confirm our tenant is listed among tenants with non default quotas
|
||||
non_default_quotas = self.admin_client.list_quotas()
|
||||
found = False
|
||||
for qs in non_default_quotas['quotas']:
|
||||
if qs['tenant_id'] == tenant_id:
|
||||
self.assertEqual(tenant_id, qs['project_id'])
|
||||
found = True
|
||||
self.assertTrue(found)
|
||||
|
||||
# Confirm from API quotas were changed as requested for tenant
|
||||
quota_set = self.admin_client.show_quotas(tenant_id)
|
||||
quota_set = quota_set['quota']
|
||||
for key, value in new_quotas.items():
|
||||
self.assertEqual(value, quota_set[key])
|
||||
|
||||
# Reset quotas to default and confirm
|
||||
self.admin_client.reset_quotas(tenant_id)
|
||||
non_default_quotas = self.admin_client.list_quotas()
|
||||
for q in non_default_quotas['quotas']:
|
||||
self.assertNotEqual(tenant_id, q['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('e974b5ba-090a-452c-a578-f9710151d9fc')
|
||||
@decorators.attr(type='gate')
|
||||
@utils.requires_ext(extension="quota_details", service="network")
|
||||
def test_detail_quotas(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
new_quotas = {'network': {'used': 1, 'limit': 2, 'reserved': 0},
|
||||
'port': {'used': 1, 'limit': 2, 'reserved': 0}}
|
||||
|
||||
# update quota limit for tenant
|
||||
new_quota = {'network': new_quotas['network']['limit'], 'port':
|
||||
new_quotas['port']['limit']}
|
||||
quota_set = self._setup_quotas(tenant_id, **new_quota)
|
||||
|
||||
# create test resources
|
||||
network = self._create_network(tenant_id)
|
||||
post_body = {"network_id": network['id'],
|
||||
"tenant_id": tenant_id}
|
||||
self._create_port(**post_body)
|
||||
|
||||
# confirm from extended API quotas were changed
|
||||
# as requested for tenant
|
||||
quota_set = self.admin_client.show_details_quota(tenant_id)
|
||||
quota_set = quota_set['quota']
|
||||
for key, value in six.iteritems(new_quotas):
|
||||
self.assertEqual(new_quotas[key]['limit'],
|
||||
quota_set[key]['limit'])
|
||||
self.assertEqual(new_quotas[key]['reserved'],
|
||||
quota_set[key]['reserved'])
|
||||
self.assertEqual(new_quotas[key]['used'],
|
||||
quota_set[key]['used'])
|
||||
|
||||
# validate 'default' action for old extension
|
||||
quota_limit = self.admin_client.show_quotas(tenant_id)['quota']
|
||||
for key, value in six.iteritems(new_quotas):
|
||||
self.assertEqual(new_quotas[key]['limit'], quota_limit[key])
|
@ -1,175 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api.admin import test_quotas
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class QuotasAdminNegativeTestJSON(test_quotas.QuotasTestBase):
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('952f9b24-9156-4bdc-90f3-682a3d4302f0')
|
||||
def test_create_network_when_quotas_is_full(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
new_quotas = {'network': 1}
|
||||
self._setup_quotas(tenant_id, **new_quotas)
|
||||
|
||||
net_args = {'tenant_id': tenant_id}
|
||||
net = self.admin_client.create_network(**net_args)['network']
|
||||
self.addCleanup(self.admin_client.delete_network, net['id'])
|
||||
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.admin_client.create_network, **net_args)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('0b7f99e3-9f77-45ce-9a89-b39a184de618')
|
||||
def test_create_subnet_when_quotas_is_full(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
new_quotas = {'subnet': 1}
|
||||
self._setup_quotas(tenant_id, **new_quotas)
|
||||
|
||||
net_args = {'tenant_id': tenant_id}
|
||||
net = self.admin_client.create_network(**net_args)['network']
|
||||
self.addCleanup(self.admin_client.delete_network, net['id'])
|
||||
|
||||
subnet_args = {'tenant_id': tenant_id,
|
||||
'network_id': net['id'],
|
||||
'cidr': '10.0.0.0/24',
|
||||
'ip_version': '4'}
|
||||
subnet = self.admin_client.create_subnet(**subnet_args)['subnet']
|
||||
self.addCleanup(self.admin_client.delete_subnet, subnet['id'])
|
||||
|
||||
subnet_args['cidr'] = '10.1.0.0/24'
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.admin_client.create_subnet, **subnet_args)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('fe20d9f9-346c-4a20-bbfa-d9ca390f4dc6')
|
||||
def test_create_port_when_quotas_is_full(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
new_quotas = {'port': 1}
|
||||
self._setup_quotas(tenant_id, **new_quotas)
|
||||
|
||||
net_args = {'tenant_id': tenant_id}
|
||||
net = self.admin_client.create_network(**net_args)['network']
|
||||
self.addCleanup(self.admin_client.delete_network, net['id'])
|
||||
|
||||
subnet_args = {'tenant_id': tenant_id,
|
||||
'network_id': net['id'],
|
||||
'enable_dhcp': False,
|
||||
'cidr': '10.0.0.0/24',
|
||||
'ip_version': '4'}
|
||||
subnet = self.admin_client.create_subnet(**subnet_args)['subnet']
|
||||
self.addCleanup(self.admin_client.delete_subnet, subnet['id'])
|
||||
|
||||
port_args = {'tenant_id': tenant_id,
|
||||
'network_id': net['id']}
|
||||
port = self.admin_client.create_port(**port_args)['port']
|
||||
self.addCleanup(self.admin_client.delete_port, port['id'])
|
||||
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.admin_client.create_port, **port_args)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('bb1e9c3c-7e6f-41f1-b579-63dbc655ecb7')
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def test_create_router_when_quotas_is_full(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
new_quotas = {'router': 1}
|
||||
self._setup_quotas(tenant_id, **new_quotas)
|
||||
|
||||
name = data_utils.rand_name('test_router')
|
||||
router_args = {'tenant_id': tenant_id}
|
||||
router = self.admin_client.create_router(
|
||||
name, True, **router_args)['router']
|
||||
self.addCleanup(self.admin_client.delete_router, router['id'])
|
||||
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.admin_client.create_router,
|
||||
name, True, **router_args)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('5c924ff7-b7a9-474f-92a3-dbe0f976ec13')
|
||||
@utils.requires_ext(extension="security-group", service="network")
|
||||
def test_create_security_group_when_quotas_is_full(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
sg_args = {'tenant_id': tenant_id}
|
||||
# avoid a number that is made by default
|
||||
sg_list = self.admin_client.list_security_groups(
|
||||
tenant_id=tenant_id)['security_groups']
|
||||
num = len(sg_list) + 1
|
||||
|
||||
new_quotas = {'security_group': num}
|
||||
self._setup_quotas(tenant_id, **new_quotas)
|
||||
|
||||
sg = self.admin_client.create_security_group(
|
||||
**sg_args)['security_group']
|
||||
self.addCleanup(self.admin_client.delete_security_group, sg['id'])
|
||||
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.admin_client.create_security_group, **sg_args)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('b7143480-6118-4ed4-be38-1b6f15f30d05')
|
||||
@utils.requires_ext(extension="security-group", service="network")
|
||||
def test_create_security_group_rule_when_quotas_is_full(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
sg_args = {'tenant_id': tenant_id}
|
||||
|
||||
sg = self.admin_client.create_security_group(
|
||||
**sg_args)['security_group']
|
||||
self.addCleanup(self.admin_client.delete_security_group, sg['id'])
|
||||
|
||||
# avoid a number that is made by default
|
||||
sg_rule_list = self.admin_client.list_security_group_rules(
|
||||
tenant_id=tenant_id)['security_group_rules']
|
||||
num = len(sg_rule_list) + 1
|
||||
|
||||
new_quotas = {'security_group_rule': num}
|
||||
self._setup_quotas(tenant_id, **new_quotas)
|
||||
|
||||
sg_rule_args = {'tenant_id': tenant_id,
|
||||
'security_group_id': sg['id'],
|
||||
'direction': 'ingress'}
|
||||
sg_rule = self.admin_client.create_security_group_rule(
|
||||
**sg_rule_args)['security_group_rule']
|
||||
self.addCleanup(
|
||||
self.admin_client.delete_security_group_rule, sg_rule['id'])
|
||||
|
||||
sg_rule_args['direction'] = 'egress'
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.admin_client.create_security_group_rule,
|
||||
**sg_rule_args)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('d00fe5bb-9db8-4e1a-9c31-490f52897e6f')
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def test_create_floatingip_when_quotas_is_full(self):
|
||||
tenant_id = self.create_project()['id']
|
||||
new_quotas = {'floatingip': 1}
|
||||
self._setup_quotas(tenant_id, **new_quotas)
|
||||
|
||||
ext_net_id = CONF.network.public_network_id
|
||||
fip_args = {'tenant_id': tenant_id,
|
||||
'floating_network_id': ext_net_id}
|
||||
fip = self.admin_client.create_floatingip(**fip_args)['floatingip']
|
||||
self.addCleanup(self.admin_client.delete_floatingip, fip['id'])
|
||||
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.admin_client.create_floatingip, **fip_args)
|
@ -1,101 +0,0 @@
|
||||
# Copyright 2015 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base_routers as base
|
||||
|
||||
|
||||
class RoutersTestDVR(base.BaseRouterTest):
|
||||
|
||||
required_extensions = ['router', 'dvr']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
# The check above will pass if api_extensions=all, which does
|
||||
# not mean DVR extension itself is present.
|
||||
# Instead, we have to check whether DVR is actually present by using
|
||||
# admin credentials to create router with distributed=True attribute
|
||||
# and checking for BadRequest exception and that the resulting router
|
||||
# has a distributed attribute.
|
||||
super(RoutersTestDVR, cls).resource_setup()
|
||||
name = data_utils.rand_name('pretest-check')
|
||||
router = cls.admin_client.create_router(name)
|
||||
if 'distributed' not in router['router']:
|
||||
msg = "'distributed' attribute not found. DVR Possibly not enabled"
|
||||
raise cls.skipException(msg)
|
||||
cls.admin_client.delete_router(router['router']['id'])
|
||||
|
||||
@decorators.idempotent_id('08a2a0a8-f1e4-4b34-8e30-e522e836c44e')
|
||||
def test_distributed_router_creation(self):
|
||||
"""
|
||||
Test uses administrative credentials to creates a
|
||||
DVR (Distributed Virtual Routing) router using the
|
||||
distributed=True.
|
||||
|
||||
Acceptance
|
||||
The router is created and the "distributed" attribute is
|
||||
set to True
|
||||
"""
|
||||
name = data_utils.rand_name('router')
|
||||
router = self.admin_client.create_router(name, distributed=True)
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
router['router']['id'])
|
||||
self.assertTrue(router['router']['distributed'])
|
||||
|
||||
@decorators.idempotent_id('8a0a72b4-7290-4677-afeb-b4ffe37bc352')
|
||||
def test_centralized_router_creation(self):
|
||||
"""
|
||||
Test uses administrative credentials to creates a
|
||||
CVR (Centralized Virtual Routing) router using the
|
||||
distributed=False.
|
||||
|
||||
Acceptance
|
||||
The router is created and the "distributed" attribute is
|
||||
set to False, thus making it a "Centralized Virtual Router"
|
||||
as opposed to a "Distributed Virtual Router"
|
||||
"""
|
||||
name = data_utils.rand_name('router')
|
||||
router = self.admin_client.create_router(name, distributed=False)
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
router['router']['id'])
|
||||
self.assertFalse(router['router']['distributed'])
|
||||
|
||||
@decorators.idempotent_id('acd43596-c1fb-439d-ada8-31ad48ae3c2e')
|
||||
def test_centralized_router_update_to_dvr(self):
|
||||
"""
|
||||
Test uses administrative credentials to creates a
|
||||
CVR (Centralized Virtual Routing) router using the
|
||||
distributed=False.Then it will "update" the router
|
||||
distributed attribute to True
|
||||
|
||||
Acceptance
|
||||
The router is created and the "distributed" attribute is
|
||||
set to False. Once the router is updated, the distributed
|
||||
attribute will be set to True
|
||||
"""
|
||||
name = data_utils.rand_name('router')
|
||||
# router needs to be in admin state down in order to be upgraded to DVR
|
||||
router = self.admin_client.create_router(name, distributed=False,
|
||||
ha=False,
|
||||
admin_state_up=False)
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
router['router']['id'])
|
||||
self.assertFalse(router['router']['distributed'])
|
||||
self.assertFalse(router['router']['ha'])
|
||||
router = self.admin_client.update_router(router['router']['id'],
|
||||
distributed=True)
|
||||
self.assertTrue(router['router']['distributed'])
|
@ -1,104 +0,0 @@
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.plugins import constants
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base_routers as base
|
||||
|
||||
|
||||
class RoutersFlavorTestCase(base.BaseRouterTest):
|
||||
|
||||
required_extensions = ['router', 'flavors', 'l3-flavors']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(RoutersFlavorTestCase, cls).resource_setup()
|
||||
cls.service_profiles = []
|
||||
cls.flavor_service_profiles = []
|
||||
# make a flavor based on legacy router for regular tenant to use
|
||||
driver = ('neutron.services.l3_router.service_providers.'
|
||||
'single_node.SingleNodeDriver')
|
||||
try:
|
||||
sp = cls.admin_client.create_service_profile(driver=driver)
|
||||
except lib_exc.NotFound as e:
|
||||
if e.resp_body['type'] == 'ServiceProfileDriverNotFound':
|
||||
raise cls.skipException("%s is not available" % driver)
|
||||
raise
|
||||
cls.service_profiles.append(sp['service_profile'])
|
||||
cls.flavor = cls.create_flavor(
|
||||
name='special_flavor',
|
||||
description='econonomy class',
|
||||
service_type=constants.L3)
|
||||
cls.admin_client.create_flavor_service_profile(
|
||||
cls.flavor['id'], sp['service_profile']['id'])
|
||||
cls.flavor_service_profiles.append((cls.flavor['id'],
|
||||
sp['service_profile']['id']))
|
||||
# make another with a different driver
|
||||
driver = ('neutron.services.l3_router.service_providers.'
|
||||
'dvr.DvrDriver')
|
||||
try:
|
||||
sp = cls.admin_client.create_service_profile(driver=driver)
|
||||
except lib_exc.NotFound as e:
|
||||
if e.resp_body['type'] == 'ServiceProfileDriverNotFound':
|
||||
raise cls.skipException("%s is not available" % driver)
|
||||
raise
|
||||
cls.service_profiles.append(sp['service_profile'])
|
||||
cls.prem_flavor = cls.create_flavor(
|
||||
name='better_special_flavor',
|
||||
description='econonomy comfort',
|
||||
service_type=constants.L3)
|
||||
cls.admin_client.create_flavor_service_profile(
|
||||
cls.prem_flavor['id'], sp['service_profile']['id'])
|
||||
cls.flavor_service_profiles.append((cls.prem_flavor['id'],
|
||||
sp['service_profile']['id']))
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
for flavor_id, service_profile_id in cls.flavor_service_profiles:
|
||||
cls.admin_client.delete_flavor_service_profile(flavor_id,
|
||||
service_profile_id)
|
||||
for service_profile in cls.service_profiles:
|
||||
cls.admin_client.delete_service_profile(
|
||||
service_profile['id'])
|
||||
super(RoutersFlavorTestCase, cls).resource_cleanup()
|
||||
|
||||
@decorators.idempotent_id('a4d01977-e968-4983-b4d9-824ea6c33f4b')
|
||||
def test_create_router_with_flavor(self):
|
||||
# ensure regular client can see flavor
|
||||
flavors = self.client.list_flavors(id=self.flavor['id'])
|
||||
flavor = flavors['flavors'][0]
|
||||
self.assertEqual('special_flavor', flavor['name'])
|
||||
flavors = self.client.list_flavors(id=self.prem_flavor['id'])
|
||||
prem_flavor = flavors['flavors'][0]
|
||||
self.assertEqual('better_special_flavor', prem_flavor['name'])
|
||||
|
||||
# ensure client can create router with both flavors
|
||||
router = self.create_router('name', flavor_id=flavor['id'])
|
||||
self.assertEqual(flavor['id'], router['flavor_id'])
|
||||
router = self.create_router('name', flavor_id=prem_flavor['id'])
|
||||
self.assertEqual(prem_flavor['id'], router['flavor_id'])
|
||||
|
||||
@decorators.idempotent_id('30e73858-a0fc-409c-a2e0-e9cd2826f6a2')
|
||||
def test_delete_router_flavor_in_use(self):
|
||||
self.create_router('name', flavor_id=self.flavor['id'])
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.delete_flavor(self.flavor['id'])
|
||||
|
||||
@decorators.idempotent_id('83939cf7-5070-41bc-9a3e-cd9f22df2186')
|
||||
def test_badrequest_on_requesting_flags_and_flavor(self):
|
||||
with testtools.ExpectedException(lib_exc.BadRequest):
|
||||
self.admin_client.create_router(
|
||||
'name', flavor_id=self.flavor['id'], distributed=True)
|
@ -1,92 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base_routers as base
|
||||
|
||||
|
||||
class RoutersTestHA(base.BaseRouterTest):
|
||||
|
||||
required_extensions = ['router', 'l3-ha']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
# The check above will pass if api_extensions=all, which does
|
||||
# not mean "l3-ha" extension itself is present.
|
||||
# Instead, we have to check whether "ha" is actually present by using
|
||||
# admin credentials to create router with ha=True attribute
|
||||
# and checking for BadRequest exception and that the resulting router
|
||||
# has a high availability attribute.
|
||||
super(RoutersTestHA, cls).resource_setup()
|
||||
name = data_utils.rand_name('pretest-check')
|
||||
router = cls.admin_client.create_router(name)
|
||||
if 'ha' not in router['router']:
|
||||
cls.admin_client.delete_router(router['router']['id'])
|
||||
msg = "'ha' attribute not found. HA Possibly not enabled"
|
||||
raise cls.skipException(msg)
|
||||
|
||||
@decorators.idempotent_id('8abc177d-14f1-4018-9f01-589b299cbee1')
|
||||
def test_ha_router_creation(self):
|
||||
"""
|
||||
Test uses administrative credentials to create a
|
||||
HA (High Availability) router using the ha=True.
|
||||
|
||||
Acceptance
|
||||
The router is created and the "ha" attribute is set to True
|
||||
"""
|
||||
name = data_utils.rand_name('router')
|
||||
router = self.admin_client.create_router(name, ha=True)
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
router['router']['id'])
|
||||
self.assertTrue(router['router']['ha'])
|
||||
|
||||
@decorators.idempotent_id('97b5f7ef-2192-4fa3-901e-979cd5c1097a')
|
||||
def test_legacy_router_creation(self):
|
||||
"""
|
||||
Test uses administrative credentials to create a
|
||||
SF (Single Failure) router using the ha=False.
|
||||
|
||||
Acceptance
|
||||
The router is created and the "ha" attribute is
|
||||
set to False, thus making it a "Single Failure Router"
|
||||
as opposed to a "High Availability Router"
|
||||
"""
|
||||
name = data_utils.rand_name('router')
|
||||
router = self.admin_client.create_router(name, ha=False)
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
router['router']['id'])
|
||||
self.assertFalse(router['router']['ha'])
|
||||
|
||||
@decorators.idempotent_id('5a6bfe82-5b23-45a4-b027-5160997d4753')
|
||||
def test_legacy_router_update_to_ha(self):
|
||||
"""
|
||||
Test uses administrative credentials to create a
|
||||
SF (Single Failure) router using the ha=False.
|
||||
Then it will "update" the router ha attribute to True
|
||||
|
||||
Acceptance
|
||||
The router is created and the "ha" attribute is
|
||||
set to False. Once the router is updated, the ha
|
||||
attribute will be set to True
|
||||
"""
|
||||
name = data_utils.rand_name('router')
|
||||
# router needs to be in admin state down in order to be upgraded to HA
|
||||
router = self.admin_client.create_router(name, ha=False,
|
||||
admin_state_up=False)
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
router['router']['id'])
|
||||
self.assertFalse(router['router']['ha'])
|
||||
router = self.admin_client.update_router(router['router']['id'],
|
||||
ha=True)
|
||||
self.assertTrue(router['router']['ha'])
|
@ -1,43 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base_security_groups as base
|
||||
|
||||
|
||||
class SecGroupAdminTest(base.BaseSecGroupTest):
|
||||
required_extensions = ['security-group']
|
||||
credentials = ['primary', 'admin']
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(SecGroupAdminTest, cls).setup_clients()
|
||||
cls.admin_client = cls.os_admin.network_client
|
||||
cls.identity_admin_client = cls.os_admin.projects_client
|
||||
|
||||
@decorators.idempotent_id('44f1e1c4-af10-4aa0-972f-87c1c8fa25cc')
|
||||
def test_security_group_recreated_on_port_update(self):
|
||||
network = self.create_network()
|
||||
self.create_subnet(network)
|
||||
port = self.create_port(network, security_groups=[])
|
||||
for sg in self.client.list_security_groups()['security_groups']:
|
||||
if sg['name'] == 'default':
|
||||
self.admin_client.delete_security_group(sg['id'])
|
||||
self.update_port(port, name='update')
|
||||
names = [
|
||||
sg['name']
|
||||
for sg in self.client.list_security_groups()['security_groups']
|
||||
]
|
||||
self.assertIn('default', names)
|
@ -1,464 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.dsvsv
|
||||
# Copyright 2015 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
from tempest.common import utils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class SharedNetworksTest(base.BaseAdminNetworkTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(SharedNetworksTest, cls).resource_setup()
|
||||
cls.shared_network = cls.create_shared_network()
|
||||
|
||||
@decorators.idempotent_id('6661d219-b96d-4597-ad10-55766123421a')
|
||||
def test_filtering_shared_networks(self):
|
||||
# this test is necessary because the 'shared' column does not actually
|
||||
# exist on networks so the filter function has to translate it into
|
||||
# queries against the RBAC table
|
||||
self.create_network()
|
||||
self._check_shared_correct(
|
||||
self.client.list_networks(shared=True)['networks'], True)
|
||||
self._check_shared_correct(
|
||||
self.admin_client.list_networks(shared=True)['networks'], True)
|
||||
self._check_shared_correct(
|
||||
self.client.list_networks(shared=False)['networks'], False)
|
||||
self._check_shared_correct(
|
||||
self.admin_client.list_networks(shared=False)['networks'], False)
|
||||
|
||||
def _check_shared_correct(self, items, shared):
|
||||
self.assertNotEmpty(items)
|
||||
self.assertTrue(all(n['shared'] == shared for n in items))
|
||||
|
||||
def _list_subnets_ids(self, client, shared):
|
||||
body = client.list_subnets(shared=shared)
|
||||
return [subnet['id'] for subnet in body['subnets']]
|
||||
|
||||
@decorators.idempotent_id('6661d219-b96d-4597-ad10-51672353421a')
|
||||
def test_filtering_shared_subnets(self):
|
||||
# shared subnets need to be tested because their shared status isn't
|
||||
# visible as a regular API attribute and it's solely dependent on the
|
||||
# parent network
|
||||
reg = self.create_network()
|
||||
priv = self.create_subnet(reg, client=self.client)
|
||||
shared = self.create_subnet(self.shared_network,
|
||||
client=self.admin_client)
|
||||
self.assertIn(shared['id'],
|
||||
self._list_subnets_ids(self.client, shared=True))
|
||||
self.assertIn(shared['id'],
|
||||
self._list_subnets_ids(self.admin_client, shared=True))
|
||||
self.assertNotIn(priv['id'],
|
||||
self._list_subnets_ids(self.client, shared=True))
|
||||
self.assertNotIn(
|
||||
priv['id'],
|
||||
self._list_subnets_ids(self.admin_client, shared=True))
|
||||
self.assertIn(priv['id'],
|
||||
self._list_subnets_ids(self.client, shared=False))
|
||||
self.assertIn(priv['id'],
|
||||
self._list_subnets_ids(self.admin_client, shared=False))
|
||||
self.assertNotIn(shared['id'],
|
||||
self._list_subnets_ids(self.client, shared=False))
|
||||
self.assertNotIn(
|
||||
shared['id'],
|
||||
self._list_subnets_ids(self.admin_client, shared=False))
|
||||
|
||||
@decorators.idempotent_id('6661d219-b96d-4597-ad10-55766ce4abf7')
|
||||
def test_create_update_shared_network(self):
|
||||
shared_network = self.create_shared_network()
|
||||
net_id = shared_network['id']
|
||||
self.assertEqual('ACTIVE', shared_network['status'])
|
||||
self.assertIsNotNone(shared_network['id'])
|
||||
self.assertTrue(self.shared_network['shared'])
|
||||
new_name = "New_shared_network"
|
||||
body = self.admin_client.update_network(net_id, name=new_name,
|
||||
admin_state_up=False,
|
||||
shared=False)
|
||||
updated_net = body['network']
|
||||
self.assertEqual(new_name, updated_net['name'])
|
||||
self.assertFalse(updated_net['shared'])
|
||||
self.assertFalse(updated_net['admin_state_up'])
|
||||
|
||||
@decorators.idempotent_id('9c31fabb-0181-464f-9ace-95144fe9ca77')
|
||||
def test_create_port_shared_network_as_non_admin_tenant(self):
|
||||
# create a port as non admin
|
||||
body = self.client.create_port(network_id=self.shared_network['id'])
|
||||
port = body['port']
|
||||
self.addCleanup(self.admin_client.delete_port, port['id'])
|
||||
# verify the tenant id of admin network and non admin port
|
||||
self.assertNotEqual(self.shared_network['tenant_id'],
|
||||
port['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('3e39c4a6-9caf-4710-88f1-d20073c6dd76')
|
||||
def test_create_bulk_shared_network(self):
|
||||
# Creates 2 networks in one request
|
||||
net_nm = [data_utils.rand_name('network'),
|
||||
data_utils.rand_name('network')]
|
||||
body = self.admin_client.create_bulk_network(net_nm, shared=True)
|
||||
created_networks = body['networks']
|
||||
for net in created_networks:
|
||||
self.addCleanup(self.admin_client.delete_network, net['id'])
|
||||
self.assertIsNotNone(net['id'])
|
||||
self.assertTrue(net['shared'])
|
||||
|
||||
def _list_shared_networks(self, user):
|
||||
body = user.list_networks(shared=True)
|
||||
networks_list = [net['id'] for net in body['networks']]
|
||||
self.assertIn(self.shared_network['id'], networks_list)
|
||||
self.assertTrue(self.shared_network['shared'])
|
||||
|
||||
@decorators.idempotent_id('a064a9fd-e02f-474a-8159-f828cd636a28')
|
||||
def test_list_shared_networks(self):
|
||||
# List the shared networks and confirm that
|
||||
# shared network extension attribute is returned for those networks
|
||||
# that are created as shared
|
||||
self._list_shared_networks(self.admin_client)
|
||||
self._list_shared_networks(self.client)
|
||||
|
||||
def _show_shared_network(self, user):
|
||||
body = user.show_network(self.shared_network['id'])
|
||||
show_shared_net = body['network']
|
||||
self.assertEqual(self.shared_network['name'], show_shared_net['name'])
|
||||
self.assertEqual(self.shared_network['id'], show_shared_net['id'])
|
||||
self.assertTrue(show_shared_net['shared'])
|
||||
|
||||
@decorators.idempotent_id('e03c92a2-638d-4bfa-b50a-b1f66f087e58')
|
||||
def test_show_shared_networks_attribute(self):
|
||||
# Show a shared network and confirm that
|
||||
# shared network extension attribute is returned.
|
||||
self._show_shared_network(self.admin_client)
|
||||
self._show_shared_network(self.client)
|
||||
|
||||
|
||||
class AllowedAddressPairSharedNetworkTest(base.BaseAdminNetworkTest):
|
||||
allowed_address_pairs = [{'ip_address': '1.1.1.1'}]
|
||||
required_extensions = ['allowed-address-pairs']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(AllowedAddressPairSharedNetworkTest, cls).resource_setup()
|
||||
cls.network = cls.create_shared_network()
|
||||
cls.create_subnet(cls.network, client=cls.admin_client)
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-ffffffff1fff')
|
||||
def test_create_with_address_pair_blocked_on_other_network(self):
|
||||
with testtools.ExpectedException(lib_exc.Forbidden):
|
||||
self.create_port(self.network,
|
||||
allowed_address_pairs=self.allowed_address_pairs)
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-ffffffff2fff')
|
||||
def test_update_with_address_pair_blocked_on_other_network(self):
|
||||
port = self.create_port(self.network)
|
||||
with testtools.ExpectedException(lib_exc.Forbidden):
|
||||
self.update_port(
|
||||
port, allowed_address_pairs=self.allowed_address_pairs)
|
||||
|
||||
|
||||
class RBACSharedNetworksTest(base.BaseAdminNetworkTest):
|
||||
|
||||
force_tenant_isolation = True
|
||||
credentials = ['primary', 'alt', 'admin']
|
||||
required_extensions = ['rbac-policies']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(RBACSharedNetworksTest, cls).resource_setup()
|
||||
cls.client2 = cls.os_alt.network_client
|
||||
|
||||
def _make_admin_net_and_subnet_shared_to_tenant_id(self, tenant_id):
|
||||
net = self.admin_client.create_network(
|
||||
name=data_utils.rand_name('test-network'))['network']
|
||||
self.addCleanup(self.admin_client.delete_network, net['id'])
|
||||
subnet = self.create_subnet(net, client=self.admin_client)
|
||||
# network is shared to first unprivileged client by default
|
||||
pol = self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared', target_tenant=tenant_id
|
||||
)['rbac_policy']
|
||||
return {'network': net, 'subnet': subnet, 'policy': pol}
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-bfffffff1eee')
|
||||
def test_create_rbac_policy_with_target_tenant_none(self):
|
||||
with testtools.ExpectedException(lib_exc.BadRequest):
|
||||
self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
tenant_id=None)
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-bfffffff1fff')
|
||||
def test_create_rbac_policy_with_target_tenant_too_long_id(self):
|
||||
with testtools.ExpectedException(lib_exc.BadRequest):
|
||||
target_tenant = '1234' * 100
|
||||
self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
tenant_id=target_tenant)
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff1fff')
|
||||
def test_network_only_visible_to_policy_target(self):
|
||||
net = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)['network']
|
||||
self.client.show_network(net['id'])
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
# client2 has not been granted access
|
||||
self.client2.show_network(net['id'])
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff2fff')
|
||||
def test_subnet_on_network_only_visible_to_policy_target(self):
|
||||
sub = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)['subnet']
|
||||
self.client.show_subnet(sub['id'])
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
# client2 has not been granted access
|
||||
self.client2.show_subnet(sub['id'])
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff2eee')
|
||||
def test_policy_target_update(self):
|
||||
res = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)
|
||||
# change to client2
|
||||
update_res = self.admin_client.update_rbac_policy(
|
||||
res['policy']['id'], target_tenant=self.client2.tenant_id)
|
||||
self.assertEqual(self.client2.tenant_id,
|
||||
update_res['rbac_policy']['target_tenant'])
|
||||
# make sure everything else stayed the same
|
||||
res['policy'].pop('target_tenant')
|
||||
update_res['rbac_policy'].pop('target_tenant')
|
||||
self.assertEqual(res['policy'], update_res['rbac_policy'])
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-affefefef321')
|
||||
def test_duplicate_policy_error(self):
|
||||
res = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=res['network']['id'],
|
||||
action='access_as_shared', target_tenant=self.client.tenant_id)
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff3fff')
|
||||
def test_port_presence_prevents_network_rbac_policy_deletion(self):
|
||||
res = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)
|
||||
port = self.client.create_port(network_id=res['network']['id'])['port']
|
||||
# a port on the network should prevent the deletion of a policy
|
||||
# required for it to exist
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.delete_rbac_policy(res['policy']['id'])
|
||||
|
||||
# a wildcard policy should allow the specific policy to be deleted
|
||||
# since it allows the remaining port
|
||||
wild = self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=res['network']['id'],
|
||||
action='access_as_shared', target_tenant='*')['rbac_policy']
|
||||
self.admin_client.delete_rbac_policy(res['policy']['id'])
|
||||
|
||||
# now that wildcard is the only remaining, it should be subjected to
|
||||
# to the same restriction
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.delete_rbac_policy(wild['id'])
|
||||
# similarly, we can't update the policy to a different tenant
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.admin_client.update_rbac_policy(
|
||||
wild['id'], target_tenant=self.client2.tenant_id)
|
||||
|
||||
self.client.delete_port(port['id'])
|
||||
# anchor is gone, delete should pass
|
||||
self.admin_client.delete_rbac_policy(wild['id'])
|
||||
|
||||
@decorators.idempotent_id('34d627da-a732-68c0-2e1a-bc4a19246698')
|
||||
def test_delete_self_share_rule(self):
|
||||
net = self.create_network()
|
||||
self_share = self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared',
|
||||
target_tenant=net['tenant_id'])['rbac_policy']
|
||||
port = self.client.create_port(network_id=net['id'])['port']
|
||||
self.client.delete_rbac_policy(self_share['id'])
|
||||
self.client.delete_port(port['id'])
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-beefbeefbeef')
|
||||
def test_tenant_can_delete_port_on_own_network(self):
|
||||
net = self.create_network() # owned by self.client
|
||||
self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared', target_tenant=self.client2.tenant_id)
|
||||
port = self.client2.create_port(network_id=net['id'])['port']
|
||||
self.client.delete_port(port['id'])
|
||||
|
||||
@decorators.idempotent_id('f7539232-389a-4e9c-9e37-e42a129eb541')
|
||||
def test_tenant_cant_delete_other_tenants_ports(self):
|
||||
net = self.create_network()
|
||||
port = self.client.create_port(network_id=net['id'])['port']
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
self.client2.delete_port(port['id'])
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff4fff')
|
||||
def test_regular_client_shares_to_another_regular_client(self):
|
||||
net = self.create_network() # owned by self.client
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
self.client2.show_network(net['id'])
|
||||
pol = self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared', target_tenant=self.client2.tenant_id)
|
||||
self.client2.show_network(net['id'])
|
||||
|
||||
self.assertIn(pol['rbac_policy'],
|
||||
self.client.list_rbac_policies()['rbac_policies'])
|
||||
# ensure that 'client2' can't see the policy sharing the network to it
|
||||
# because the policy belongs to 'client'
|
||||
self.assertNotIn(pol['rbac_policy']['id'],
|
||||
[p['id']
|
||||
for p in self.client2.list_rbac_policies()['rbac_policies']])
|
||||
|
||||
@decorators.idempotent_id('bf5052b8-b11e-407c-8e43-113447404d3e')
|
||||
def test_filter_fields(self):
|
||||
net = self.create_network()
|
||||
self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared', target_tenant=self.client2.tenant_id)
|
||||
field_args = (('id',), ('id', 'action'), ('object_type', 'object_id'),
|
||||
('tenant_id', 'target_tenant'))
|
||||
for fields in field_args:
|
||||
res = self.client.list_rbac_policies(fields=fields)
|
||||
self.assertEqual(set(fields), set(res['rbac_policies'][0].keys()))
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff5fff')
|
||||
def test_policy_show(self):
|
||||
res = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)
|
||||
p1 = res['policy']
|
||||
p2 = self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=res['network']['id'],
|
||||
action='access_as_shared',
|
||||
target_tenant='*')['rbac_policy']
|
||||
|
||||
self.assertEqual(
|
||||
p1, self.admin_client.show_rbac_policy(p1['id'])['rbac_policy'])
|
||||
self.assertEqual(
|
||||
p2, self.admin_client.show_rbac_policy(p2['id'])['rbac_policy'])
|
||||
|
||||
@decorators.idempotent_id('e7bcb1ea-4877-4266-87bb-76f68b421f31')
|
||||
def test_filter_policies(self):
|
||||
net = self.create_network()
|
||||
pol1 = self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared',
|
||||
target_tenant=self.client2.tenant_id)['rbac_policy']
|
||||
pol2 = self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared',
|
||||
target_tenant=self.client.tenant_id)['rbac_policy']
|
||||
res1 = self.client.list_rbac_policies(id=pol1['id'])['rbac_policies']
|
||||
res2 = self.client.list_rbac_policies(id=pol2['id'])['rbac_policies']
|
||||
self.assertEqual(1, len(res1))
|
||||
self.assertEqual(1, len(res2))
|
||||
self.assertEqual(pol1['id'], res1[0]['id'])
|
||||
self.assertEqual(pol2['id'], res2[0]['id'])
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff6fff')
|
||||
def test_regular_client_blocked_from_sharing_anothers_network(self):
|
||||
net = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)['network']
|
||||
with testtools.ExpectedException(lib_exc.BadRequest):
|
||||
self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared', target_tenant=self.client.tenant_id)
|
||||
|
||||
@decorators.idempotent_id('c5f8f785-ce8d-4430-af7e-a236205862fb')
|
||||
@utils.requires_ext(extension="quotas", service="network")
|
||||
def test_rbac_policy_quota(self):
|
||||
quota = self.client.show_quotas(self.client.tenant_id)['quota']
|
||||
max_policies = quota['rbac_policy']
|
||||
self.assertGreater(max_policies, 0)
|
||||
net = self.client.create_network(
|
||||
name=data_utils.rand_name('test-network'))['network']
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
for i in range(0, max_policies + 1):
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared',
|
||||
target_tenant=uuidutils.generate_uuid().replace('-', ''))
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-afffffff7fff')
|
||||
def test_regular_client_blocked_from_sharing_with_wildcard(self):
|
||||
net = self.create_network()
|
||||
with testtools.ExpectedException(lib_exc.Forbidden):
|
||||
self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared', target_tenant='*')
|
||||
# ensure it works on update as well
|
||||
pol = self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared', target_tenant=self.client2.tenant_id)
|
||||
with testtools.ExpectedException(lib_exc.Forbidden):
|
||||
self.client.update_rbac_policy(pol['rbac_policy']['id'],
|
||||
target_tenant='*')
|
||||
|
||||
@decorators.idempotent_id('34d627da-869f-68c0-2e1a-bc4a19246698')
|
||||
def test_update_self_share_rule(self):
|
||||
net = self.create_network()
|
||||
self_share = self.client.create_rbac_policy(
|
||||
object_type='network', object_id=net['id'],
|
||||
action='access_as_shared',
|
||||
target_tenant=net['tenant_id'])['rbac_policy']
|
||||
port = self.client.create_port(network_id=net['id'])['port']
|
||||
self.client.update_rbac_policy(self_share['id'],
|
||||
target_tenant=self.client2.tenant_id)
|
||||
self.client.delete_port(port['id'])
|
||||
|
||||
@utils.requires_ext(extension="standard-attr-revisions", service="network")
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-1234-89664291a4cb')
|
||||
def test_rbac_bumps_network_revision(self):
|
||||
resp = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)
|
||||
net_id = resp['network']['id']
|
||||
rev = self.client.show_network(net_id)['network']['revision_number']
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net_id,
|
||||
action='access_as_shared', target_tenant='*')
|
||||
self.assertGreater(
|
||||
self.client.show_network(net_id)['network']['revision_number'],
|
||||
rev
|
||||
)
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-aeeeeeee7fff')
|
||||
def test_filtering_works_with_rbac_records_present(self):
|
||||
resp = self._make_admin_net_and_subnet_shared_to_tenant_id(
|
||||
self.client.tenant_id)
|
||||
net = resp['network']['id']
|
||||
sub = resp['subnet']['id']
|
||||
self.admin_client.create_rbac_policy(
|
||||
object_type='network', object_id=net,
|
||||
action='access_as_shared', target_tenant='*')
|
||||
self._assert_shared_object_id_listing_presence('subnets', False, sub)
|
||||
self._assert_shared_object_id_listing_presence('subnets', True, sub)
|
||||
self._assert_shared_object_id_listing_presence('networks', False, net)
|
||||
self._assert_shared_object_id_listing_presence('networks', True, net)
|
||||
|
||||
def _assert_shared_object_id_listing_presence(self, resource, shared, oid):
|
||||
lister = getattr(self.admin_client, 'list_%s' % resource)
|
||||
objects = [o['id'] for o in lister(shared=shared)[resource]]
|
||||
if shared:
|
||||
self.assertIn(oid, objects)
|
||||
else:
|
||||
self.assertNotIn(oid, objects)
|
@ -1,516 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
|
||||
class TagTestJSON(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['tag']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TagTestJSON, cls).resource_setup()
|
||||
cls.res_id = cls._create_resource()
|
||||
|
||||
def _get_and_compare_tags(self, tags):
|
||||
res_body = self.client.get_tags(self.resource, self.res_id)
|
||||
self.assertItemsEqual(tags, res_body['tags'])
|
||||
|
||||
def _test_tag_operations(self):
|
||||
# create and get tags
|
||||
tags = ['red', 'blue']
|
||||
res_body = self.client.update_tags(self.resource, self.res_id, tags)
|
||||
self.assertItemsEqual(tags, res_body['tags'])
|
||||
self._get_and_compare_tags(tags)
|
||||
|
||||
# add a tag
|
||||
self.client.update_tag(self.resource, self.res_id, 'green')
|
||||
self._get_and_compare_tags(['red', 'blue', 'green'])
|
||||
|
||||
# update tag exist
|
||||
self.client.update_tag(self.resource, self.res_id, 'red')
|
||||
self._get_and_compare_tags(['red', 'blue', 'green'])
|
||||
|
||||
# add a tag with a dot
|
||||
self.client.update_tag(self.resource, self.res_id, 'black.or.white')
|
||||
self._get_and_compare_tags(['red', 'blue', 'green', 'black.or.white'])
|
||||
|
||||
# replace tags
|
||||
tags = ['red', 'yellow', 'purple']
|
||||
res_body = self.client.update_tags(self.resource, self.res_id, tags)
|
||||
self.assertItemsEqual(tags, res_body['tags'])
|
||||
self._get_and_compare_tags(tags)
|
||||
|
||||
# get tag
|
||||
self.client.get_tag(self.resource, self.res_id, 'red')
|
||||
|
||||
# get tag not exist
|
||||
self.assertRaises(lib_exc.NotFound, self.client.get_tag,
|
||||
self.resource, self.res_id, 'green')
|
||||
|
||||
# delete tag
|
||||
self.client.delete_tag(self.resource, self.res_id, 'red')
|
||||
self._get_and_compare_tags(['yellow', 'purple'])
|
||||
|
||||
# delete tag not exist
|
||||
self.assertRaises(lib_exc.NotFound, self.client.delete_tag,
|
||||
self.resource, self.res_id, 'green')
|
||||
|
||||
# delete tags
|
||||
self.client.delete_tags(self.resource, self.res_id)
|
||||
self._get_and_compare_tags([])
|
||||
|
||||
|
||||
class TagNetworkTestJSON(TagTestJSON):
|
||||
resource = 'networks'
|
||||
|
||||
@classmethod
|
||||
def _create_resource(cls):
|
||||
network = cls.create_network()
|
||||
return network['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('5621062d-fbfb-4437-9d69-138c78ea4188')
|
||||
def test_network_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagSubnetTestJSON(TagTestJSON):
|
||||
resource = 'subnets'
|
||||
|
||||
@classmethod
|
||||
def _create_resource(cls):
|
||||
network = cls.create_network()
|
||||
subnet = cls.create_subnet(network)
|
||||
return subnet['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('2805aabf-a94c-4e70-a0b2-9814f06beb03')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_subnet_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagPortTestJSON(TagTestJSON):
|
||||
resource = 'ports'
|
||||
|
||||
@classmethod
|
||||
def _create_resource(cls):
|
||||
network = cls.create_network()
|
||||
port = cls.create_port(network)
|
||||
return port['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('c7c44f2c-edb0-4ebd-a386-d37cec155c34')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_port_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagSubnetPoolTestJSON(TagTestJSON):
|
||||
resource = 'subnetpools'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="subnet_allocation", service="network")
|
||||
def _create_resource(cls):
|
||||
subnetpool = cls.create_subnetpool('subnetpool', default_prefixlen=24,
|
||||
prefixes=['10.0.0.0/8'])
|
||||
return subnetpool['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('bdc1c24b-c0b5-4835-953c-8f67dc11edfe')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_subnetpool_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagRouterTestJSON(TagTestJSON):
|
||||
resource = 'routers'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def _create_resource(cls):
|
||||
router = cls.create_router(router_name='test')
|
||||
return router['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('b898ff92-dc33-4232-8ab9-2c6158c80d28')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_router_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagSecGroupTestJSON(TagTestJSON):
|
||||
resource = 'security-groups'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="security-group", service="network")
|
||||
def _create_resource(cls):
|
||||
sec_group = cls.create_security_group(name='test')
|
||||
return sec_group['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('0f1a78eb-c5be-42cf-919d-2ce3621a51c2')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_security_group_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagFloatingIpTestJSON(TagTestJSON):
|
||||
resource = 'floatingips'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def _create_resource(cls):
|
||||
cls.ext_net_id = config.CONF.network.public_network_id
|
||||
floatingip = cls.create_floatingip(cls.ext_net_id)
|
||||
return floatingip['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('53f6c2bf-e272-4e9e-b9a9-b165eb7be807')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_floatingip_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagQosPolicyTestJSON(TagTestJSON):
|
||||
resource = 'policies'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="qos", service="network")
|
||||
def _create_resource(cls):
|
||||
qos_policy = cls.create_qos_policy(name='test-policy', shared=True)
|
||||
return qos_policy['id']
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('e9bac15e-c8bc-4317-8295-4bf1d8d522b8')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_qos_policy_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagTrunkTestJSON(TagTestJSON):
|
||||
resource = 'trunks'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="trunk", service="network")
|
||||
def _create_resource(cls):
|
||||
network = cls.create_network()
|
||||
parent_port = cls.create_port(network)
|
||||
trunk = cls.client.create_trunk(parent_port['id'], None)
|
||||
return trunk['trunk']['id']
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
cls.client.delete_trunk(cls.res_id)
|
||||
super(TagTrunkTestJSON, cls).resource_cleanup()
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('4c63708b-c4c3-407c-8101-7a9593882f5f')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_trunk_tags(self):
|
||||
self._test_tag_operations()
|
||||
|
||||
|
||||
class TagFilterTestJSON(base.BaseAdminNetworkTest):
|
||||
credentials = ['primary', 'alt', 'admin']
|
||||
required_extensions = ['tag']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TagFilterTestJSON, cls).resource_setup()
|
||||
|
||||
cls.res_ids = []
|
||||
for i in range(5):
|
||||
cls.res_ids.append(cls._create_resource())
|
||||
|
||||
cls.client.update_tags(cls.resource, cls.res_ids[0], ['red'])
|
||||
cls.client.update_tags(cls.resource, cls.res_ids[1], ['red', 'blue'])
|
||||
cls.client.update_tags(cls.resource, cls.res_ids[2],
|
||||
['red', 'blue', 'green'])
|
||||
cls.client.update_tags(cls.resource, cls.res_ids[3], ['green'])
|
||||
# 5th resource: no tags
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(TagFilterTestJSON, cls).setup_clients()
|
||||
cls.client = cls.os_alt.network_client
|
||||
|
||||
def _assertEqualResources(self, expected, res):
|
||||
expected = [self.res_ids[i] for i in expected]
|
||||
actual = [n['id'] for n in res if n['id'] in self.res_ids]
|
||||
self.assertEqual(set(expected), set(actual))
|
||||
|
||||
def _test_filter_tags(self):
|
||||
# tags single
|
||||
filters = {'tags': 'red'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([0, 1, 2], res)
|
||||
|
||||
# tags multi
|
||||
filters = {'tags': 'red,blue'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([1, 2], res)
|
||||
|
||||
# tags-any single
|
||||
filters = {'tags-any': 'blue'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([1, 2], res)
|
||||
|
||||
# tags-any multi
|
||||
filters = {'tags-any': 'red,blue'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([0, 1, 2], res)
|
||||
|
||||
# not-tags single
|
||||
filters = {'not-tags': 'red'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([3, 4], res)
|
||||
|
||||
# not-tags multi
|
||||
filters = {'not-tags': 'red,blue'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([0, 3, 4], res)
|
||||
|
||||
# not-tags-any single
|
||||
filters = {'not-tags-any': 'blue'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([0, 3, 4], res)
|
||||
|
||||
# not-tags-any multi
|
||||
filters = {'not-tags-any': 'red,blue'}
|
||||
res = self._list_resource(filters)
|
||||
self._assertEqualResources([3, 4], res)
|
||||
|
||||
|
||||
class TagFilterNetworkTestJSON(TagFilterTestJSON):
|
||||
resource = 'networks'
|
||||
|
||||
@classmethod
|
||||
def _create_resource(cls):
|
||||
res = cls.create_network()
|
||||
return res['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_networks(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('a66b5cca-7db2-40f5-a33d-8ac9f864e53e')
|
||||
def test_filter_network_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterSubnetTestJSON(TagFilterTestJSON):
|
||||
resource = 'subnets'
|
||||
|
||||
@classmethod
|
||||
def _create_resource(cls):
|
||||
network = cls.create_network()
|
||||
res = cls.create_subnet(network)
|
||||
return res['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_subnets(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('dd8f9ba7-bcf6-496f-bead-714bd3daac10')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_filter_subnet_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterPortTestJSON(TagFilterTestJSON):
|
||||
resource = 'ports'
|
||||
|
||||
@classmethod
|
||||
def _create_resource(cls):
|
||||
network = cls.create_network()
|
||||
res = cls.create_port(network)
|
||||
return res['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_ports(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('09c036b8-c8d0-4bee-b776-7f4601512898')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_filter_port_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterSubnetpoolTestJSON(TagFilterTestJSON):
|
||||
resource = 'subnetpools'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="subnet_allocation", service="network")
|
||||
def _create_resource(cls):
|
||||
res = cls.create_subnetpool('subnetpool', default_prefixlen=24,
|
||||
prefixes=['10.0.0.0/8'])
|
||||
return res['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_subnetpools(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('16ae7ad2-55c2-4821-9195-bfd04ab245b7')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_filter_subnetpool_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterRouterTestJSON(TagFilterTestJSON):
|
||||
resource = 'routers'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def _create_resource(cls):
|
||||
res = cls.create_router(router_name='test')
|
||||
return res['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_routers(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('cdd3f3ea-073d-4435-a6cb-826a4064193d')
|
||||
@utils.requires_ext(extension="tag-ext", service="network")
|
||||
def test_filter_router_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterSecGroupTestJSON(TagFilterTestJSON):
|
||||
resource = 'security-groups'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="security-group", service="network")
|
||||
def _create_resource(cls):
|
||||
sec_group = cls.create_security_group(name='test')
|
||||
return sec_group['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_security_groups(**filters)
|
||||
resource_key = self.resource.replace('-', '_')
|
||||
return res[resource_key]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('d4d1d681-0116-4800-9725-16cb88f8171a')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_filter_security_group_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterFloatingIpTestJSON(TagFilterTestJSON):
|
||||
resource = 'floatingips'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def _create_resource(cls):
|
||||
cls.ext_net_id = config.CONF.network.public_network_id
|
||||
floatingip = cls.create_floatingip(cls.ext_net_id)
|
||||
return floatingip['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_floatingips(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('01f00afc-dbec-432a-bfee-2a1f0510e7a8')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_filter_floatingip_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterQosPolicyTestJSON(TagFilterTestJSON):
|
||||
resource = 'policies'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="qos", service="network")
|
||||
def _create_resource(cls):
|
||||
qos_policy = cls.create_qos_policy(name='test-policy', shared=True)
|
||||
return qos_policy['id']
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_qos_policies(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('c2f9a6ae-2529-4cb9-a44b-b16f8ba27832')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_filter_qos_policy_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class TagFilterTrunkTestJSON(TagFilterTestJSON):
|
||||
resource = 'trunks'
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="trunk", service="network")
|
||||
def _create_resource(cls):
|
||||
network = cls.create_network()
|
||||
parent_port = cls.create_port(network)
|
||||
trunk = cls.client.create_trunk(parent_port['id'], None)
|
||||
return trunk['trunk']['id']
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
for res_id in cls.res_ids:
|
||||
cls.client.delete_trunk(res_id)
|
||||
super(TagFilterTrunkTestJSON, cls).resource_cleanup()
|
||||
|
||||
def _list_resource(self, filters):
|
||||
res = self.client.list_trunks(**filters)
|
||||
return res[self.resource]
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('3fb3ca3a-8e3a-4565-ba73-16413d445e25')
|
||||
@utils.requires_ext(extension="standard-attr-tag", service="network")
|
||||
def test_filter_trunk_tags(self):
|
||||
self._test_filter_tags()
|
||||
|
||||
|
||||
class UpdateTagsTest(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['tag']
|
||||
|
||||
def _get_and_compare_tags(self, tags, res_id):
|
||||
# nothing specific about networks here, just a resource that is
|
||||
# available in all setups
|
||||
res_body = self.client.get_tags('networks', res_id)
|
||||
self.assertItemsEqual(tags, res_body['tags'])
|
||||
|
||||
@decorators.attr(type='smoke')
|
||||
@decorators.idempotent_id('74c56fb1-a3b1-4a62-a8d2-d04dca6bd4cd')
|
||||
def test_update_tags_affects_only_updated_resource(self):
|
||||
res1 = self.create_network()
|
||||
res2 = self.create_network()
|
||||
|
||||
self.client.update_tags('networks', res1['id'], ['red', 'blue'])
|
||||
self._get_and_compare_tags(['red', 'blue'], res1['id'])
|
||||
|
||||
self.client.update_tags('networks', res2['id'], ['red'])
|
||||
self._get_and_compare_tags(['red'], res2['id'])
|
||||
|
||||
self.client.update_tags('networks', res2['id'], [])
|
||||
self._get_and_compare_tags([], res2['id'])
|
||||
|
||||
# check that updates on res2 hasn't dropped tags from res1
|
||||
self._get_and_compare_tags(['red', 'blue'], res1['id'])
|
@ -1,45 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class BaseRouterTest(base.BaseAdminNetworkTest):
|
||||
# NOTE(salv-orlando): This class inherits from BaseAdminNetworkTest
|
||||
# as some router operations, such as enabling or disabling SNAT
|
||||
# require admin credentials by default
|
||||
|
||||
def _cleanup_router(self, router):
|
||||
self.delete_router(router)
|
||||
self.routers.remove(router)
|
||||
|
||||
def _create_router(self, name, admin_state_up=False,
|
||||
external_network_id=None, enable_snat=None):
|
||||
# associate a cleanup with created routers to avoid quota limits
|
||||
router = self.create_router(name, admin_state_up,
|
||||
external_network_id, enable_snat)
|
||||
self.addCleanup(self._cleanup_router, router)
|
||||
return router
|
||||
|
||||
def _delete_router(self, router_id, network_client=None):
|
||||
client = network_client or self.client
|
||||
client.delete_router(router_id)
|
||||
# Asserting that the router is not found in the list
|
||||
# after deletion
|
||||
list_body = self.client.list_routers()
|
||||
routers_list = list()
|
||||
for router in list_body['routers']:
|
||||
routers_list.append(router['id'])
|
||||
self.assertNotIn(router_id, routers_list)
|
@ -1,93 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib import constants
|
||||
from tempest.lib.common.utils import data_utils
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
V4_PROTOCOL_NAMES = set(key for key in constants.IP_PROTOCOL_MAP if
|
||||
'v6' not in key)
|
||||
V4_PROTOCOL_INTS = set(v for k, v in constants.IP_PROTOCOL_MAP.items()
|
||||
if 'v6' not in k)
|
||||
V6_PROTOCOL_LEGACY = set([constants.PROTO_NAME_IPV6_ICMP_LEGACY])
|
||||
V6_PROTOCOL_NAMES = (
|
||||
set(key for key in constants.IP_PROTOCOL_MAP if 'v6' in key) -
|
||||
V6_PROTOCOL_LEGACY
|
||||
)
|
||||
V6_PROTOCOL_INTS = set(v for k, v in constants.IP_PROTOCOL_MAP.items() if
|
||||
'v6' in k)
|
||||
|
||||
|
||||
class BaseSecGroupTest(base.BaseNetworkTest):
|
||||
|
||||
def _create_security_group(self, **kwargs):
|
||||
# Create a security group
|
||||
name = data_utils.rand_name('secgroup-')
|
||||
group_create_body = self.client.create_security_group(name=name,
|
||||
**kwargs)
|
||||
self.addCleanup(self._delete_security_group,
|
||||
group_create_body['security_group']['id'])
|
||||
self.assertEqual(group_create_body['security_group']['name'], name)
|
||||
return group_create_body, name
|
||||
|
||||
def _delete_security_group(self, secgroup_id):
|
||||
self.client.delete_security_group(secgroup_id)
|
||||
# Asserting that the security group is not found in the list
|
||||
# after deletion
|
||||
list_body = self.client.list_security_groups()
|
||||
secgroup_list = list()
|
||||
for secgroup in list_body['security_groups']:
|
||||
secgroup_list.append(secgroup['id'])
|
||||
self.assertNotIn(secgroup_id, secgroup_list)
|
||||
|
||||
def _create_security_group_rule(self, **kwargs):
|
||||
rule_create_body = self.client.create_security_group_rule(**kwargs)
|
||||
# List rules and verify created rule is in response
|
||||
rule_list_body = (
|
||||
self.client.list_security_group_rules())
|
||||
rule_list = [rule['id']
|
||||
for rule in rule_list_body['security_group_rules']]
|
||||
self.assertIn(rule_create_body['security_group_rule']['id'],
|
||||
rule_list)
|
||||
self.addCleanup(self._delete_security_group_rule,
|
||||
rule_create_body['security_group_rule']['id'])
|
||||
return rule_create_body
|
||||
|
||||
def _show_security_group_rule(self, **kwargs):
|
||||
show_rule_body = self.client.show_security_group_rule(kwargs['id'])
|
||||
for key, value in kwargs.items():
|
||||
self.assertEqual(value,
|
||||
show_rule_body['security_group_rule'][key],
|
||||
"%s does not match." % key)
|
||||
|
||||
def _delete_security_group_rule(self, secgroup_rule_id):
|
||||
self.client.delete_security_group_rule(secgroup_rule_id)
|
||||
rule_list_body = self.client.list_security_group_rules()
|
||||
rule_list = [rule['id']
|
||||
for rule in rule_list_body['security_group_rules']]
|
||||
self.assertNotIn(secgroup_rule_id, rule_list)
|
||||
|
||||
def _test_create_show_delete_security_group_rule(self, **kwargs):
|
||||
# The security group rule is deleted by the cleanup call in
|
||||
# _create_security_group_rule.
|
||||
rule_create_body = (
|
||||
self._create_security_group_rule(**kwargs)['security_group_rule'])
|
||||
self._show_security_group_rule(
|
||||
id=rule_create_body['id'],
|
||||
protocol=rule_create_body['protocol'],
|
||||
direction=rule_create_body['direction'],
|
||||
ethertype=rule_create_body['ethertype'])
|
@ -1,117 +0,0 @@
|
||||
# Copyright (c) 2015 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
ADDRESS_SCOPE_NAME = 'smoke-address-scope'
|
||||
|
||||
|
||||
class AddressScopeTestBase(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['address-scope']
|
||||
|
||||
def _create_address_scope(self, is_admin=False, **kwargs):
|
||||
name = data_utils.rand_name(ADDRESS_SCOPE_NAME)
|
||||
return self.create_address_scope(name=name, is_admin=is_admin,
|
||||
**kwargs)
|
||||
|
||||
def _test_update_address_scope_helper(self, is_admin=False, shared=None):
|
||||
address_scope = self._create_address_scope(is_admin=is_admin,
|
||||
ip_version=4)
|
||||
|
||||
if is_admin:
|
||||
client = self.admin_client
|
||||
else:
|
||||
client = self.client
|
||||
|
||||
kwargs = {'name': 'new_name'}
|
||||
if shared is not None:
|
||||
kwargs['shared'] = shared
|
||||
|
||||
client.update_address_scope(address_scope['id'], **kwargs)
|
||||
body = client.show_address_scope(address_scope['id'])
|
||||
address_scope = body['address_scope']
|
||||
self.assertEqual('new_name', address_scope['name'])
|
||||
return address_scope
|
||||
|
||||
|
||||
class AddressScopeTest(AddressScopeTestBase):
|
||||
|
||||
@decorators.idempotent_id('045f9294-8b1a-4848-b6a8-edf1b41e9d06')
|
||||
def test_tenant_create_list_address_scope(self):
|
||||
address_scope = self._create_address_scope(ip_version=4)
|
||||
body = self.client.list_address_scopes()
|
||||
returned_address_scopes = body['address_scopes']
|
||||
self.assertIn(address_scope['id'],
|
||||
[a_s['id'] for a_s in returned_address_scopes],
|
||||
"Created address scope id should be in the list")
|
||||
self.assertIn(address_scope['name'],
|
||||
[a_s['name'] for a_s in returned_address_scopes],
|
||||
"Created address scope name should be in the list")
|
||||
|
||||
@decorators.idempotent_id('85e0326b-4c75-4b92-bd6e-7c7de6aaf05c')
|
||||
def test_show_address_scope(self):
|
||||
address_scope = self._create_address_scope(ip_version=4)
|
||||
body = self.client.show_address_scope(
|
||||
address_scope['id'])
|
||||
returned_address_scope = body['address_scope']
|
||||
self.assertEqual(address_scope['id'], returned_address_scope['id'])
|
||||
self.assertEqual(address_scope['name'],
|
||||
returned_address_scope['name'])
|
||||
self.assertFalse(returned_address_scope['shared'])
|
||||
|
||||
@decorators.idempotent_id('bbd57364-6d57-48e4-b0f1-8b9a998f5e06')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_show_address_scope_project_id(self):
|
||||
address_scope = self._create_address_scope(ip_version=4)
|
||||
body = self.client.show_address_scope(address_scope['id'])
|
||||
show_addr_scope = body['address_scope']
|
||||
self.assertIn('project_id', show_addr_scope)
|
||||
self.assertIn('tenant_id', show_addr_scope)
|
||||
self.assertEqual(self.client.tenant_id, show_addr_scope['project_id'])
|
||||
self.assertEqual(self.client.tenant_id, show_addr_scope['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('85a259b2-ace6-4e32-9657-a9a392b452aa')
|
||||
def test_tenant_update_address_scope(self):
|
||||
self._test_update_address_scope_helper()
|
||||
|
||||
@decorators.idempotent_id('22b3b600-72a8-4b60-bc94-0f29dd6271df')
|
||||
def test_delete_address_scope(self):
|
||||
address_scope = self._create_address_scope(ip_version=4)
|
||||
self.client.delete_address_scope(address_scope['id'])
|
||||
self.assertRaises(lib_exc.NotFound, self.client.show_address_scope,
|
||||
address_scope['id'])
|
||||
|
||||
@decorators.idempotent_id('5a06c287-8036-4d04-9d78-def8e06d43df')
|
||||
def test_admin_create_shared_address_scope(self):
|
||||
address_scope = self._create_address_scope(is_admin=True, shared=True,
|
||||
ip_version=4)
|
||||
body = self.admin_client.show_address_scope(
|
||||
address_scope['id'])
|
||||
returned_address_scope = body['address_scope']
|
||||
self.assertEqual(address_scope['name'],
|
||||
returned_address_scope['name'])
|
||||
self.assertTrue(returned_address_scope['shared'])
|
||||
|
||||
@decorators.idempotent_id('e9e1ccdd-9ccd-4076-9503-71820529508b')
|
||||
def test_admin_update_shared_address_scope(self):
|
||||
address_scope = self._test_update_address_scope_helper(is_admin=True,
|
||||
shared=True)
|
||||
self.assertTrue(address_scope['shared'])
|
@ -1,92 +0,0 @@
|
||||
# Copyright (c) 2015 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import test_address_scopes
|
||||
|
||||
|
||||
class AddressScopeTestNegative(test_address_scopes.AddressScopeTestBase):
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('9c92ec34-0c50-4104-aa47-9ce98d5088df')
|
||||
def test_tenant_create_shared_address_scope(self):
|
||||
self.assertRaises(lib_exc.Forbidden, self._create_address_scope,
|
||||
shared=True, ip_version=4)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('a857b61e-bf53-4fab-b21a-b0daaf81b5bd')
|
||||
def test_tenant_update_address_scope_shared_true(self):
|
||||
self.assertRaises(lib_exc.Forbidden,
|
||||
self._test_update_address_scope_helper, shared=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('a859ef2f-9c76-4e2e-ba0f-e0339a489e8c')
|
||||
def test_tenant_update_address_scope_shared_false(self):
|
||||
self.assertRaises(lib_exc.Forbidden,
|
||||
self._test_update_address_scope_helper, shared=False)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('9b6dd7ad-cabb-4f55-bd5e-e61176ef41f6')
|
||||
def test_get_non_existent_address_scope(self):
|
||||
non_exist_id = data_utils.rand_name('address_scope')
|
||||
self.assertRaises(lib_exc.NotFound, self.client.show_address_scope,
|
||||
non_exist_id)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('ef213552-f2da-487d-bf4a-e1705d115ff1')
|
||||
def test_tenant_get_not_shared_admin_address_scope(self):
|
||||
address_scope = self._create_address_scope(is_admin=True,
|
||||
ip_version=4)
|
||||
# None-shared admin address scope cannot be retrieved by tenant user.
|
||||
self.assertRaises(lib_exc.NotFound, self.client.show_address_scope,
|
||||
address_scope['id'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('5c25dc6a-1e92-467a-9cc7-cda74b6003db')
|
||||
def test_delete_non_existent_address_scope(self):
|
||||
non_exist_id = data_utils.rand_name('address_scope')
|
||||
self.assertRaises(lib_exc.NotFound, self.client.delete_address_scope,
|
||||
non_exist_id)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('47c25dc5-e886-4a84-88c3-ac5031969661')
|
||||
def test_update_non_existent_address_scope(self):
|
||||
non_exist_id = data_utils.rand_name('address_scope')
|
||||
self.assertRaises(lib_exc.NotFound, self.client.update_address_scope,
|
||||
non_exist_id, name='foo-name')
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('702d0515-82cb-4207-b0d9-703336e54665')
|
||||
def test_update_shared_address_scope_to_unshare(self):
|
||||
address_scope = self._create_address_scope(is_admin=True, shared=True,
|
||||
ip_version=4)
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.admin_client.update_address_scope,
|
||||
address_scope['id'], name='new-name', shared=False)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('1e471e5c-6f9c-437a-9257-fd9bc4b6f0fb')
|
||||
def test_delete_address_scope_associated_with_subnetpool(self):
|
||||
address_scope = self._create_address_scope(ip_version=4)
|
||||
prefixes = [u'10.11.12.0/24']
|
||||
subnetpool_data = {
|
||||
'name': 'foo-subnetpool',
|
||||
'min_prefixlen': '29', 'prefixes': prefixes,
|
||||
'address_scope_id': address_scope['id']}
|
||||
self.create_subnetpool(**subnetpool_data)
|
||||
self.assertRaises(lib_exc.Conflict, self.client.delete_address_scope,
|
||||
address_scope['id'])
|
@ -1,128 +0,0 @@
|
||||
# Copyright 2014 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
|
||||
class AllowedAddressPairTestJSON(base.BaseNetworkTest):
|
||||
|
||||
"""
|
||||
Tests the Neutron Allowed Address Pair API extension using the Tempest
|
||||
REST client. The following API operations are tested with this extension:
|
||||
|
||||
create port
|
||||
list ports
|
||||
update port
|
||||
show port
|
||||
|
||||
v2.0 of the Neutron API is assumed. It is also assumed that the following
|
||||
options are defined in the [network-feature-enabled] section of
|
||||
etc/tempest.conf
|
||||
|
||||
api_extensions
|
||||
"""
|
||||
|
||||
required_extensions = ['allowed-address-pairs']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(AllowedAddressPairTestJSON, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
cls.create_subnet(cls.network)
|
||||
port = cls.create_port(cls.network)
|
||||
cls.ip_address = port['fixed_ips'][0]['ip_address']
|
||||
cls.mac_address = port['mac_address']
|
||||
|
||||
@decorators.idempotent_id('86c3529b-1231-40de-803c-00e40882f043')
|
||||
def test_create_list_port_with_address_pair(self):
|
||||
# Create port with allowed address pair attribute
|
||||
allowed_address_pairs = [{'ip_address': self.ip_address,
|
||||
'mac_address': self.mac_address}]
|
||||
body = self.client.create_port(
|
||||
network_id=self.network['id'],
|
||||
allowed_address_pairs=allowed_address_pairs)
|
||||
port_id = body['port']['id']
|
||||
self.addCleanup(self.client.delete_port, port_id)
|
||||
|
||||
# Confirm port was created with allowed address pair attribute
|
||||
body = self.client.list_ports()
|
||||
ports = body['ports']
|
||||
port = [p for p in ports if p['id'] == port_id]
|
||||
msg = 'Created port not found in list of ports returned by Neutron'
|
||||
self.assertTrue(port, msg)
|
||||
self._confirm_allowed_address_pair(port[0], self.ip_address)
|
||||
|
||||
def _update_port_with_address(self, address, mac_address=None, **kwargs):
|
||||
# Create a port without allowed address pair
|
||||
body = self.client.create_port(network_id=self.network['id'])
|
||||
port_id = body['port']['id']
|
||||
self.addCleanup(self.client.delete_port, port_id)
|
||||
if mac_address is None:
|
||||
mac_address = self.mac_address
|
||||
|
||||
# Update allowed address pair attribute of port
|
||||
allowed_address_pairs = [{'ip_address': address,
|
||||
'mac_address': mac_address}]
|
||||
if kwargs:
|
||||
allowed_address_pairs.append(kwargs['allowed_address_pairs'])
|
||||
body = self.client.update_port(
|
||||
port_id, allowed_address_pairs=allowed_address_pairs)
|
||||
allowed_address_pair = body['port']['allowed_address_pairs']
|
||||
self.assertItemsEqual(allowed_address_pair, allowed_address_pairs)
|
||||
|
||||
@decorators.idempotent_id('9599b337-272c-47fd-b3cf-509414414ac4')
|
||||
def test_update_port_with_address_pair(self):
|
||||
# Update port with allowed address pair
|
||||
self._update_port_with_address(self.ip_address)
|
||||
|
||||
@decorators.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
|
||||
def test_update_port_with_cidr_address_pair(self):
|
||||
# Update allowed address pair with cidr
|
||||
cidr = str(
|
||||
netaddr.IPNetwork(config.safe_get_config_value(
|
||||
'network', 'project_network_cidr')))
|
||||
self._update_port_with_address(cidr)
|
||||
|
||||
@decorators.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
|
||||
def test_update_port_with_multiple_ip_mac_address_pair(self):
|
||||
# Create an ip _address and mac_address through port create
|
||||
resp = self.client.create_port(network_id=self.network['id'])
|
||||
newportid = resp['port']['id']
|
||||
self.addCleanup(self.client.delete_port, newportid)
|
||||
ipaddress = resp['port']['fixed_ips'][0]['ip_address']
|
||||
macaddress = resp['port']['mac_address']
|
||||
|
||||
# Update allowed address pair port with multiple ip and mac
|
||||
allowed_address_pairs = {'ip_address': ipaddress,
|
||||
'mac_address': macaddress}
|
||||
self._update_port_with_address(
|
||||
self.ip_address, self.mac_address,
|
||||
allowed_address_pairs=allowed_address_pairs)
|
||||
|
||||
def _confirm_allowed_address_pair(self, port, ip):
|
||||
msg = 'Port allowed address pairs should not be empty'
|
||||
self.assertTrue(port['allowed_address_pairs'], msg)
|
||||
ip_address = port['allowed_address_pairs'][0]['ip_address']
|
||||
mac_address = port['allowed_address_pairs'][0]['mac_address']
|
||||
self.assertEqual(ip_address, ip)
|
||||
self.assertEqual(mac_address, self.mac_address)
|
||||
|
||||
|
||||
class AllowedAddressPairIpV6TestJSON(AllowedAddressPairTestJSON):
|
||||
_ip_version = 6
|
@ -1,117 +0,0 @@
|
||||
# Copyright 2016 IBM
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import auto_allocated_topology
|
||||
from oslo_config import cfg
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class TestAutoAllocatedTopology(base.BaseAdminNetworkTest):
|
||||
|
||||
"""
|
||||
Tests the Get-Me-A-Network operations in the Neutron API
|
||||
using the REST client for Neutron.
|
||||
"""
|
||||
# NOTE(armax): this is a precaution to avoid interference
|
||||
# from other tests exercising this extension. So long as
|
||||
# all tests are added under TestAutoAllocatedTopology,
|
||||
# nothing bad should happen.
|
||||
force_tenant_isolation = True
|
||||
required_extensions = [auto_allocated_topology.ALIAS]
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestAutoAllocatedTopology, cls).resource_setup()
|
||||
|
||||
# The deployment must contain a default subnetpool
|
||||
body = cls.client.list_subnetpools(is_default=True)
|
||||
# The deployment may contain one or two default subnetpools:
|
||||
# one ipv4 pool, or one ipv6 pool, or one of each.
|
||||
# This run-time dependency should be revisited if the test is
|
||||
# moved over to tempest.
|
||||
cls.num_subnetpools = len(body['subnetpools'])
|
||||
if cls.num_subnetpools == 0:
|
||||
raise cls.skipException("No default subnetpool")
|
||||
|
||||
# Ensure the public external network is the default external network
|
||||
public_net_id = cfg.CONF.network.public_network_id
|
||||
cls.admin_client.update_network(public_net_id, is_default=True)
|
||||
# Ensure that is_default does not accidentally flip back to False
|
||||
# because of network_update requests that do not contain is_default.
|
||||
cls.admin_client.update_network(public_net_id, description="gman")
|
||||
|
||||
def _count_topology_resources(self):
|
||||
'''Count the resources whose names begin with 'auto_allocated_'.'''
|
||||
|
||||
def _count(resources):
|
||||
return len([resource['id'] for resource in resources
|
||||
if resource['name'].startswith('auto_allocated_')])
|
||||
|
||||
up = {'admin_state_up': True}
|
||||
networks = _count(self.client.list_networks(**up)['networks'])
|
||||
subnets = _count(self.client.list_subnets(**up)['subnets'])
|
||||
routers = _count(self.client.list_routers(**up)['routers'])
|
||||
return networks, subnets, routers
|
||||
|
||||
def _add_topology_cleanup(self, client):
|
||||
'''Add the auto-allocated resources to the cleanup lists.'''
|
||||
|
||||
body = client.list_routers(name='auto_allocated_router')
|
||||
self.routers.extend(body['routers'])
|
||||
body = client.list_subnets(name='auto_allocated_subnet_v4')
|
||||
self.subnets.extend(body['subnets'])
|
||||
body = client.list_subnets(name='auto_allocated_subnet_v6')
|
||||
self.subnets.extend(body['subnets'])
|
||||
body = client.list_networks(name='auto_allocated_network')
|
||||
self.networks.extend(body['networks'])
|
||||
|
||||
@decorators.idempotent_id('64bc0b02-cee4-11e5-9f3c-080027605a2b')
|
||||
def test_get_allocated_net_topology_as_tenant(self):
|
||||
resources_before = self._count_topology_resources()
|
||||
self.assertEqual((0, 0, 0), resources_before)
|
||||
|
||||
body = self.client.get_auto_allocated_topology()
|
||||
topology = body[auto_allocated_topology.RESOURCE_NAME]
|
||||
self.assertIsNotNone(topology)
|
||||
self._add_topology_cleanup(self.client)
|
||||
|
||||
network_id1 = topology['id']
|
||||
self.assertIsNotNone(network_id1)
|
||||
network = self.client.show_network(topology['id'])['network']
|
||||
self.assertTrue(network['admin_state_up'])
|
||||
resources_after1 = self._count_topology_resources()
|
||||
# One network, two subnets (v4 and v6) and one router
|
||||
self.assertEqual((1, self.num_subnetpools, 1), resources_after1)
|
||||
|
||||
body = self.client.get_auto_allocated_topology()
|
||||
topology = body[auto_allocated_topology.RESOURCE_NAME]
|
||||
network_id2 = topology['id']
|
||||
resources_after2 = self._count_topology_resources()
|
||||
# After the initial GET, the API should be idempotent
|
||||
self.assertEqual(network_id1, network_id2)
|
||||
self.assertEqual(resources_after1, resources_after2)
|
||||
|
||||
@decorators.idempotent_id('aabc0b02-cee4-11e5-9f3c-091127605a2b')
|
||||
def test_delete_allocated_net_topology_as_tenant(self):
|
||||
resources_before = self._count_topology_resources()
|
||||
self.assertEqual((0, 0, 0), resources_before)
|
||||
body = self.client.get_auto_allocated_topology()
|
||||
topology = body[auto_allocated_topology.RESOURCE_NAME]
|
||||
self.assertIsNotNone(topology)
|
||||
self.client.delete_auto_allocated_topology()
|
||||
resources_after = self._count_topology_resources()
|
||||
self.assertEqual((0, 0, 0), resources_after)
|
@ -1,99 +0,0 @@
|
||||
# Copyright 2014 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from neutron_lib import constants
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class NetworksTestDHCPv6(base.BaseNetworkTest):
|
||||
_ip_version = 6
|
||||
|
||||
def setUp(self):
|
||||
super(NetworksTestDHCPv6, self).setUp()
|
||||
self.addCleanup(self._clean_network)
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(NetworksTestDHCPv6, cls).skip_checks()
|
||||
msg = None
|
||||
if not CONF.network_feature_enabled.ipv6:
|
||||
msg = "IPv6 is not enabled"
|
||||
elif not CONF.network_feature_enabled.ipv6_subnet_attributes:
|
||||
msg = "DHCPv6 attributes are not enabled."
|
||||
if msg:
|
||||
raise cls.skipException(msg)
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(NetworksTestDHCPv6, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
|
||||
def _remove_from_list_by_index(self, things_list, elem):
|
||||
for index, i in enumerate(things_list):
|
||||
if i['id'] == elem['id']:
|
||||
break
|
||||
del things_list[index]
|
||||
|
||||
def _clean_network(self):
|
||||
body = self.client.list_ports()
|
||||
ports = body['ports']
|
||||
for port in ports:
|
||||
if (port['device_owner'].startswith(
|
||||
constants.DEVICE_OWNER_ROUTER_INTF)
|
||||
and port['device_id'] in [r['id'] for r in self.routers]):
|
||||
self.client.remove_router_interface_with_port_id(
|
||||
port['device_id'], port['id']
|
||||
)
|
||||
else:
|
||||
if port['id'] in [p['id'] for p in self.ports]:
|
||||
self.client.delete_port(port['id'])
|
||||
self._remove_from_list_by_index(self.ports, port)
|
||||
body = self.client.list_subnets()
|
||||
subnets = body['subnets']
|
||||
for subnet in subnets:
|
||||
if subnet['id'] in [s['id'] for s in self.subnets]:
|
||||
self.client.delete_subnet(subnet['id'])
|
||||
self._remove_from_list_by_index(self.subnets, subnet)
|
||||
body = self.client.list_routers()
|
||||
routers = body['routers']
|
||||
for router in routers:
|
||||
if router['id'] in [r['id'] for r in self.routers]:
|
||||
self.client.delete_router(router['id'])
|
||||
self._remove_from_list_by_index(self.routers, router)
|
||||
|
||||
@decorators.idempotent_id('98244d88-d990-4570-91d4-6b25d70d08af')
|
||||
def test_dhcp_stateful_fixedips_outrange(self):
|
||||
"""When port gets IP address from fixed IP range it
|
||||
shall be checked if it's from subnets range.
|
||||
"""
|
||||
kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
|
||||
'ipv6_address_mode': 'dhcpv6-stateful'}
|
||||
subnet = self.create_subnet(self.network, **kwargs)
|
||||
ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
|
||||
subnet["allocation_pools"][0]["end"])
|
||||
for i in range(1, 3):
|
||||
ip = netaddr.IPAddress(ip_range.last + i).format()
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.create_port,
|
||||
self.network,
|
||||
fixed_ips=[{'subnet_id': subnet['id'],
|
||||
'ip_address': ip}])
|
@ -1,150 +0,0 @@
|
||||
# Copyright 2015 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import ddt
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest.api import base_security_groups as base_security
|
||||
|
||||
FAKE_IP = '10.0.0.1'
|
||||
FAKE_MAC = '00:25:64:e8:19:dd'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class PortSecTest(base_security.BaseSecGroupTest,
|
||||
base.BaseNetworkTest):
|
||||
|
||||
@decorators.idempotent_id('7c338ddf-e64e-4118-bd33-e49a1f2f1495')
|
||||
@utils.requires_ext(extension='port-security', service='network')
|
||||
def test_port_sec_default_value(self):
|
||||
# Default port-sec value is True, and the attr of the port will inherit
|
||||
# from the port-sec of the network when it not be specified in API
|
||||
network = self.create_network()
|
||||
self.assertTrue(network['port_security_enabled'])
|
||||
self.create_subnet(network)
|
||||
port = self.create_port(network)
|
||||
self.assertTrue(port['port_security_enabled'])
|
||||
|
||||
@decorators.idempotent_id('e60eafd2-31de-4c38-8106-55447d033b57')
|
||||
@utils.requires_ext(extension='port-security', service='network')
|
||||
@ddt.unpack
|
||||
@ddt.data({'port_sec_net': False, 'port_sec_port': True, 'expected': True},
|
||||
{'port_sec_net': True, 'port_sec_port': False,
|
||||
'expected': False})
|
||||
def test_port_sec_specific_value(self, port_sec_net, port_sec_port,
|
||||
expected):
|
||||
network = self.create_network(port_security_enabled=port_sec_net)
|
||||
self.create_subnet(network)
|
||||
port = self.create_port(network, port_security_enabled=port_sec_port)
|
||||
self.assertEqual(network['port_security_enabled'], port_sec_net)
|
||||
self.assertEqual(port['port_security_enabled'], expected)
|
||||
|
||||
@decorators.idempotent_id('fe7c27b9-f320-4daf-b977-b1547c43daf6')
|
||||
@utils.requires_ext(extension='port-security', service='network')
|
||||
def test_create_port_sec_with_security_group(self):
|
||||
network = self.create_network(port_security_enabled=True)
|
||||
self.create_subnet(network)
|
||||
|
||||
port = self.create_port(network, security_groups=[])
|
||||
self.assertTrue(port['port_security_enabled'])
|
||||
self.client.delete_port(port['id'])
|
||||
|
||||
port = self.create_port(network, security_groups=[],
|
||||
port_security_enabled=False)
|
||||
self.assertFalse(port['port_security_enabled'])
|
||||
self.assertEmpty(port['security_groups'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('ff11226c-a5ff-4ad4-8480-0840e36e47a9')
|
||||
@utils.requires_ext(extension='port-security', service='network')
|
||||
def test_port_sec_update_port_failed(self):
|
||||
network = self.create_network()
|
||||
self.create_subnet(network)
|
||||
|
||||
sec_group_body, _ = self._create_security_group()
|
||||
port = self.create_port(network)
|
||||
|
||||
# Exception when set port-sec to False with sec-group defined
|
||||
self.assertRaises(lib_exc.Conflict, self.update_port, port,
|
||||
port_security_enabled=False)
|
||||
|
||||
port = self.update_port(port, security_groups=[],
|
||||
port_security_enabled=False)
|
||||
self.assertEmpty(port['security_groups'])
|
||||
self.assertFalse(port['port_security_enabled'])
|
||||
port = self.update_port(
|
||||
port, security_groups=[sec_group_body['security_group']['id']],
|
||||
port_security_enabled=True)
|
||||
|
||||
self.assertNotEmpty(port['security_groups'])
|
||||
self.assertTrue(port['port_security_enabled'])
|
||||
|
||||
# Remove security group from port before deletion on resource_cleanup
|
||||
self.update_port(port, security_groups=[])
|
||||
|
||||
@decorators.idempotent_id('05642059-1bfc-4581-9bc9-aaa5db08dd60')
|
||||
@utils.requires_ext(extension='port-security', service='network')
|
||||
def test_port_sec_update_pass(self):
|
||||
network = self.create_network()
|
||||
self.create_subnet(network)
|
||||
sec_group, _ = self._create_security_group()
|
||||
sec_group_id = sec_group['security_group']['id']
|
||||
port = self.create_port(network, security_groups=[sec_group_id],
|
||||
port_security_enabled=True)
|
||||
|
||||
self.assertNotEmpty(port['security_groups'])
|
||||
self.assertTrue(port['port_security_enabled'])
|
||||
|
||||
port = self.update_port(port, security_groups=[])
|
||||
self.assertEmpty(port['security_groups'])
|
||||
self.assertTrue(port['port_security_enabled'])
|
||||
|
||||
port = self.update_port(port, security_groups=[sec_group_id])
|
||||
self.assertNotEmpty(port['security_groups'])
|
||||
port = self.update_port(port, security_groups=[],
|
||||
port_security_enabled=False)
|
||||
self.assertEmpty(port['security_groups'])
|
||||
self.assertFalse(port['port_security_enabled'])
|
||||
|
||||
@decorators.idempotent_id('2df6114b-b8c3-48a1-96e8-47f08159d35c')
|
||||
@utils.requires_ext(extension='port-security', service='network')
|
||||
def test_delete_with_port_sec(self):
|
||||
network = self.create_network(port_security_enabled=True)
|
||||
port = self.create_port(network=network,
|
||||
port_security_enabled=True)
|
||||
self.client.delete_port(port['id'])
|
||||
self.assertTrue(self.client.is_resource_deleted('port', port['id']))
|
||||
self.client.delete_network(network['id'])
|
||||
self.assertTrue(
|
||||
self.client.is_resource_deleted('network', network['id']))
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('ed93e453-3f8d-495e-8e7e-b0e268c2ebd9')
|
||||
@utils.requires_ext(extension='port-security', service='network')
|
||||
@utils.requires_ext(extension='allowed-address-pairs', service='network')
|
||||
def test_allowed_address_pairs(self):
|
||||
network = self.create_network()
|
||||
self.create_subnet(network)
|
||||
port = self.create_port(network=network, port_security_enabled=False)
|
||||
allowed_address_pairs = [{'ip_address': FAKE_IP,
|
||||
'mac_address': FAKE_MAC}]
|
||||
|
||||
# Exception when set address-pairs with port-sec is False
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.update_port, port,
|
||||
allowed_address_pairs=allowed_address_pairs)
|
@ -1,41 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class ExtensionsTest(base.BaseNetworkTest):
|
||||
|
||||
def _test_list_extensions_includes(self, ext):
|
||||
body = self.client.list_extensions()
|
||||
extensions = {ext_['alias'] for ext_ in body['extensions']}
|
||||
self.assertNotEmpty(extensions, "Extension list returned is empty")
|
||||
ext_enabled = utils.is_extension_enabled(ext, "network")
|
||||
if ext_enabled:
|
||||
self.assertIn(ext, extensions)
|
||||
else:
|
||||
self.assertNotIn(ext, extensions)
|
||||
|
||||
@decorators.idempotent_id('262420b7-a4bb-4a3e-b4b5-e73bad18df8c')
|
||||
def test_list_extensions_sorting(self):
|
||||
self._test_list_extensions_includes('sorting')
|
||||
|
||||
@decorators.idempotent_id('19db409e-a23f-445d-8bc8-ca3d64c84706')
|
||||
def test_list_extensions_pagination(self):
|
||||
self._test_list_extensions_includes('pagination')
|
||||
|
||||
@decorators.idempotent_id('155b7bc2-e358-4dd8-bf3e-1774c084567f')
|
||||
def test_list_extensions_project_id(self):
|
||||
self._test_list_extensions_includes('project-id')
|
@ -1,98 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class ExtraDHCPOptionsTestJSON(base.BaseNetworkTest):
|
||||
|
||||
"""
|
||||
Tests the following operations with the Extra DHCP Options Neutron API
|
||||
extension:
|
||||
|
||||
port create
|
||||
port list
|
||||
port show
|
||||
port update
|
||||
|
||||
v2.0 of the Neutron API is assumed. It is also assumed that the Extra
|
||||
DHCP Options extension is enabled in the [network-feature-enabled]
|
||||
section of etc/tempest.conf
|
||||
"""
|
||||
|
||||
required_extensions = ['extra_dhcp_opt']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(ExtraDHCPOptionsTestJSON, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
cls.port = cls.create_port(cls.network)
|
||||
cls.ip_tftp = ('123.123.123.123' if cls._ip_version == 4
|
||||
else '2015::dead')
|
||||
cls.ip_server = ('123.123.123.45' if cls._ip_version == 4
|
||||
else '2015::badd')
|
||||
cls.extra_dhcp_opts = [
|
||||
{'opt_value': 'pxelinux.0', 'opt_name': 'bootfile-name'},
|
||||
{'opt_value': cls.ip_tftp, 'opt_name': 'tftp-server'},
|
||||
{'opt_value': cls.ip_server, 'opt_name': 'server-ip-address'}
|
||||
]
|
||||
|
||||
@decorators.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
|
||||
def test_create_list_port_with_extra_dhcp_options(self):
|
||||
# Create a port with Extra DHCP Options
|
||||
body = self.client.create_port(
|
||||
network_id=self.network['id'],
|
||||
extra_dhcp_opts=self.extra_dhcp_opts)
|
||||
port_id = body['port']['id']
|
||||
self.addCleanup(self.client.delete_port, port_id)
|
||||
|
||||
# Confirm port created has Extra DHCP Options
|
||||
body = self.client.list_ports()
|
||||
ports = body['ports']
|
||||
port = [p for p in ports if p['id'] == port_id]
|
||||
self.assertTrue(port)
|
||||
self._confirm_extra_dhcp_options(port[0], self.extra_dhcp_opts)
|
||||
|
||||
@decorators.idempotent_id('9a6aebf4-86ee-4f47-b07a-7f7232c55607')
|
||||
def test_update_show_port_with_extra_dhcp_options(self):
|
||||
# Update port with extra dhcp options
|
||||
name = data_utils.rand_name('new-port-name')
|
||||
body = self.client.update_port(
|
||||
self.port['id'],
|
||||
name=name,
|
||||
extra_dhcp_opts=self.extra_dhcp_opts)
|
||||
# Confirm extra dhcp options were added to the port
|
||||
body = self.client.show_port(self.port['id'])
|
||||
self._confirm_extra_dhcp_options(body['port'], self.extra_dhcp_opts)
|
||||
|
||||
def _confirm_extra_dhcp_options(self, port, extra_dhcp_opts):
|
||||
retrieved = port['extra_dhcp_opts']
|
||||
self.assertEqual(len(retrieved), len(extra_dhcp_opts))
|
||||
for retrieved_option in retrieved:
|
||||
for option in extra_dhcp_opts:
|
||||
if (retrieved_option['opt_value'] == option['opt_value'] and
|
||||
retrieved_option['opt_name'] == option['opt_name']):
|
||||
break
|
||||
else:
|
||||
self.fail('Extra DHCP option not found in port %s' %
|
||||
str(retrieved_option))
|
||||
|
||||
|
||||
class ExtraDHCPOptionsIpV6TestJSON(ExtraDHCPOptionsTestJSON):
|
||||
_ip_version = 6
|
@ -1,155 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class TestFlavorsJson(base.BaseAdminNetworkTest):
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
Neutron:
|
||||
|
||||
List, Show, Create, Update, Delete Flavors
|
||||
List, Show, Create, Update, Delete service profiles
|
||||
"""
|
||||
|
||||
required_extensions = ['flavors']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestFlavorsJson, cls).resource_setup()
|
||||
|
||||
# Use flavors service type as know this is loaded
|
||||
service_type = "FLAVORS"
|
||||
description_flavor = "flavor is created by tempest"
|
||||
name_flavor = "Best flavor created by tempest"
|
||||
|
||||
# The check above will pass if api_extensions=all, which does
|
||||
# not mean flavors extension itself is present.
|
||||
try:
|
||||
cls.flavor = cls.create_flavor(name_flavor, description_flavor,
|
||||
service_type)
|
||||
except lib_exc.NotFound:
|
||||
msg = "flavors plugin not enabled."
|
||||
raise cls.skipException(msg)
|
||||
|
||||
description_sp = "service profile created by tempest"
|
||||
# Drivers are supported as is an empty driver field. Use an
|
||||
# empty field for now since otherwise driver is validated against the
|
||||
# servicetype configuration which may differ in test scenarios.
|
||||
driver = ""
|
||||
metainfo = '{"data": "value"}'
|
||||
cls.service_profile = cls.create_service_profile(
|
||||
description=description_sp, metainfo=metainfo, driver=driver)
|
||||
|
||||
def _delete_service_profile(self, service_profile_id):
|
||||
# Deletes a service profile and verifies if it is deleted or not
|
||||
self.admin_client.delete_service_profile(service_profile_id)
|
||||
# Asserting that service profile is not found in list after deletion
|
||||
labels = self.admin_client.list_service_profiles(id=service_profile_id)
|
||||
self.assertEqual(len(labels['service_profiles']), 0)
|
||||
|
||||
@decorators.idempotent_id('b12a9487-b6a2-4cff-a69a-fe2a0b64fae6')
|
||||
def test_create_update_delete_service_profile(self):
|
||||
# Creates a service profile
|
||||
description = "service_profile created by tempest"
|
||||
driver = ""
|
||||
metainfo = '{"data": "value"}'
|
||||
body = self.admin_client.create_service_profile(
|
||||
description=description, driver=driver, metainfo=metainfo)
|
||||
service_profile = body['service_profile']
|
||||
# Updates a service profile
|
||||
self.admin_client.update_service_profile(service_profile['id'],
|
||||
enabled=False)
|
||||
self.assertTrue(service_profile['enabled'])
|
||||
# Deletes a service profile
|
||||
self.addCleanup(self._delete_service_profile,
|
||||
service_profile['id'])
|
||||
# Assert whether created service profiles are found in service profile
|
||||
# lists or fail if created service profiles are not found in service
|
||||
# profiles list
|
||||
labels = (self.admin_client.list_service_profiles(
|
||||
id=service_profile['id']))
|
||||
self.assertEqual(len(labels['service_profiles']), 1)
|
||||
|
||||
@decorators.idempotent_id('136bcf09-00af-4da7-9b7f-174735d4aebd')
|
||||
def test_create_update_delete_flavor(self):
|
||||
# Creates a flavor
|
||||
description = "flavor created by tempest"
|
||||
service = "FLAVORS"
|
||||
name = "Best flavor created by tempest"
|
||||
body = self.admin_client.create_flavor(name=name, service_type=service,
|
||||
description=description)
|
||||
flavor = body['flavor']
|
||||
# Updates a flavor
|
||||
self.admin_client.update_flavor(flavor['id'], enabled=False)
|
||||
self.assertTrue(flavor['enabled'])
|
||||
# Deletes a flavor
|
||||
self.addCleanup(self._delete_flavor, flavor['id'])
|
||||
# Assert whether created flavors are found in flavor lists or fail
|
||||
# if created flavors are not found in flavors list
|
||||
labels = (self.admin_client.list_flavors(id=flavor['id']))
|
||||
self.assertEqual(len(labels['flavors']), 1)
|
||||
|
||||
@decorators.idempotent_id('30abb445-0eea-472e-bd02-8649f54a5968')
|
||||
def test_show_service_profile(self):
|
||||
# Verifies the details of a service profile
|
||||
body = self.admin_client.show_service_profile(
|
||||
self.service_profile['id'])
|
||||
service_profile = body['service_profile']
|
||||
self.assertEqual(self.service_profile['id'], service_profile['id'])
|
||||
self.assertEqual(self.service_profile['description'],
|
||||
service_profile['description'])
|
||||
self.assertEqual(self.service_profile['metainfo'],
|
||||
service_profile['metainfo'])
|
||||
self.assertTrue(service_profile['enabled'])
|
||||
|
||||
@decorators.idempotent_id('362f9658-164b-44dd-8356-151bc9b7be72')
|
||||
def test_show_flavor(self):
|
||||
# Verifies the details of a flavor
|
||||
body = self.admin_client.show_flavor(self.flavor['id'])
|
||||
flavor = body['flavor']
|
||||
self.assertEqual(self.flavor['id'], flavor['id'])
|
||||
self.assertEqual(self.flavor['description'], flavor['description'])
|
||||
self.assertEqual(self.flavor['name'], flavor['name'])
|
||||
self.assertTrue(flavor['enabled'])
|
||||
|
||||
@decorators.idempotent_id('eb3dd12e-6dfd-45f4-8393-46e0fa19860e')
|
||||
def test_list_flavors(self):
|
||||
# Verify flavor lists
|
||||
body = self.admin_client.list_flavors(id=33)
|
||||
flavors = body['flavors']
|
||||
self.assertEqual(0, len(flavors))
|
||||
|
||||
@decorators.idempotent_id('e2fb2f8c-45bf-429a-9f17-171c70444612')
|
||||
def test_list_service_profiles(self):
|
||||
# Verify service profiles lists
|
||||
body = self.admin_client.list_service_profiles(id=33)
|
||||
service_profiles = body['service_profiles']
|
||||
self.assertEqual(0, len(service_profiles))
|
||||
|
||||
def _delete_flavor(self, flavor_id):
|
||||
# Deletes a flavor and verifies if it is deleted or not
|
||||
self.admin_client.delete_flavor(flavor_id)
|
||||
# Asserting that the flavor is not found in list after deletion
|
||||
labels = self.admin_client.list_flavors(id=flavor_id)
|
||||
self.assertEqual(len(labels['flavors']), 0)
|
||||
|
||||
|
||||
class TestFlavorsIpV6TestJSON(TestFlavorsJson):
|
||||
_ip_version = 6
|
@ -1,107 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class FloatingIPTestJSON(base.BaseNetworkTest):
|
||||
|
||||
required_extensions = ['router']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(FloatingIPTestJSON, cls).resource_setup()
|
||||
cls.ext_net_id = CONF.network.public_network_id
|
||||
|
||||
# Create network, subnet, router and add interface
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
cls.router = cls.create_router(data_utils.rand_name('router'),
|
||||
external_network_id=cls.ext_net_id)
|
||||
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
|
||||
cls.port = list()
|
||||
# Create two ports one each for Creation and Updating of floatingIP
|
||||
for i in range(2):
|
||||
cls.create_port(cls.network)
|
||||
|
||||
@decorators.idempotent_id('f6a0fb6c-cb64-4b81-b0d5-f41d8f69d22d')
|
||||
def test_blank_update_clears_association(self):
|
||||
# originally the floating IP had no attributes other than its
|
||||
# association, so an update with an empty body was a signal to
|
||||
# clear the association. This test ensures we maintain that behavior.
|
||||
body = self.client.create_floatingip(
|
||||
floating_network_id=self.ext_net_id,
|
||||
port_id=self.ports[0]['id'],
|
||||
)['floatingip']
|
||||
self.floating_ips.append(body)
|
||||
self.assertEqual(self.ports[0]['id'], body['port_id'])
|
||||
body = self.client.update_floatingip(body['id'])['floatingip']
|
||||
self.assertFalse(body['port_id'])
|
||||
|
||||
@decorators.idempotent_id('c72c1c0c-2193-4aca-eeee-b1442641ffff')
|
||||
@utils.requires_ext(extension="standard-attr-description",
|
||||
service="network")
|
||||
def test_create_update_floatingip_description(self):
|
||||
body = self.client.create_floatingip(
|
||||
floating_network_id=self.ext_net_id,
|
||||
port_id=self.ports[0]['id'],
|
||||
description='d1'
|
||||
)['floatingip']
|
||||
self.floating_ips.append(body)
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.show_floatingip(body['id'])['floatingip']
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.update_floatingip(body['id'], description='d2')
|
||||
self.assertEqual('d2', body['floatingip']['description'])
|
||||
body = self.client.show_floatingip(body['floatingip']['id'])
|
||||
self.assertEqual('d2', body['floatingip']['description'])
|
||||
# disassociate
|
||||
body = self.client.update_floatingip(body['floatingip']['id'],
|
||||
port_id=None)
|
||||
self.assertEqual('d2', body['floatingip']['description'])
|
||||
|
||||
@decorators.idempotent_id('fd7161e1-2167-4686-a6ff-0f3df08001bb')
|
||||
@utils.requires_ext(extension="standard-attr-description",
|
||||
service="network")
|
||||
def test_floatingip_update_extra_attributes_port_id_not_changed(self):
|
||||
port_id = self.ports[1]['id']
|
||||
body = self.client.create_floatingip(
|
||||
floating_network_id=self.ext_net_id,
|
||||
port_id=port_id,
|
||||
description='d1'
|
||||
)['floatingip']
|
||||
self.floating_ips.append(body)
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.show_floatingip(body['id'])['floatingip']
|
||||
self.assertEqual(port_id, body['port_id'])
|
||||
# Update description
|
||||
body = self.client.update_floatingip(body['id'], description='d2')
|
||||
self.assertEqual('d2', body['floatingip']['description'])
|
||||
# Floating IP association is not changed.
|
||||
self.assertEqual(port_id, body['floatingip']['port_id'])
|
||||
body = self.client.show_floatingip(body['floatingip']['id'])
|
||||
self.assertEqual('d2', body['floatingip']['description'])
|
||||
self.assertEqual(port_id, body['floatingip']['port_id'])
|
||||
# disassociate
|
||||
body = self.client.update_floatingip(body['floatingip']['id'],
|
||||
port_id=None)
|
||||
self.assertIsNone(body['floatingip']['port_id'])
|
@ -1,67 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
# Copyright 2014 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class FloatingIPNegativeTestJSON(base.BaseNetworkTest):
|
||||
|
||||
required_extensions = ['router']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(FloatingIPNegativeTestJSON, cls).resource_setup()
|
||||
cls.ext_net_id = CONF.network.public_network_id
|
||||
# Create a network with a subnet connected to a router.
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
cls.router = cls.create_router(data_utils.rand_name('router'))
|
||||
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
|
||||
cls.port = cls.create_port(cls.network)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('0b5b8797-6de7-4191-905c-a48b888eb429')
|
||||
def test_associate_floatingip_with_port_with_floatingip(self):
|
||||
net = self.create_network()
|
||||
subnet = self.create_subnet(net)
|
||||
r = self.create_router('test')
|
||||
self.create_router_interface(r['id'], subnet['id'])
|
||||
self.client.update_router(
|
||||
r['id'],
|
||||
external_gateway_info={
|
||||
'network_id': self.ext_net_id})
|
||||
self.addCleanup(self.client.update_router, self.router['id'],
|
||||
external_gateway_info={})
|
||||
port = self.create_port(net)
|
||||
body1 = self.client.create_floatingip(
|
||||
floating_network_id=self.ext_net_id)
|
||||
floating_ip1 = body1['floatingip']
|
||||
self.addCleanup(self.client.delete_floatingip, floating_ip1['id'])
|
||||
body2 = self.client.create_floatingip(
|
||||
floating_network_id=self.ext_net_id)
|
||||
floating_ip2 = body2['floatingip']
|
||||
self.addCleanup(self.client.delete_floatingip, floating_ip2['id'])
|
||||
self.client.update_floatingip(floating_ip1['id'],
|
||||
port_id=port['id'])
|
||||
self.assertRaises(lib_exc.Conflict, self.client.update_floatingip,
|
||||
floating_ip2['id'], port_id=port['id'])
|
@ -1,155 +0,0 @@
|
||||
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import metering as metering_apidef
|
||||
from neutron_lib.db import constants as db_const
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
LONG_NAME_OK = 'x' * db_const.NAME_FIELD_SIZE
|
||||
|
||||
|
||||
class MeteringTestJSON(base.BaseAdminNetworkTest):
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
Neutron:
|
||||
|
||||
List, Show, Create, Delete Metering labels
|
||||
List, Show, Create, Delete Metering labels rules
|
||||
"""
|
||||
|
||||
required_extensions = [metering_apidef.ALIAS]
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(MeteringTestJSON, cls).resource_setup()
|
||||
description = "metering label created by tempest"
|
||||
name = data_utils.rand_name("metering-label")
|
||||
cls.metering_label = cls.create_metering_label(name, description)
|
||||
remote_ip_prefix = ("10.0.0.0/24" if cls._ip_version == 4
|
||||
else "fd02::/64")
|
||||
direction = "ingress"
|
||||
cls.metering_label_rule = cls.create_metering_label_rule(
|
||||
remote_ip_prefix, direction,
|
||||
metering_label_id=cls.metering_label['id'])
|
||||
|
||||
def _delete_metering_label(self, metering_label_id):
|
||||
# Deletes a label and verifies if it is deleted or not
|
||||
self.admin_client.delete_metering_label(metering_label_id)
|
||||
# Asserting that the label is not found in list after deletion
|
||||
labels = self.admin_client.list_metering_labels(id=metering_label_id)
|
||||
self.assertEqual(len(labels['metering_labels']), 0)
|
||||
|
||||
def _delete_metering_label_rule(self, metering_label_rule_id):
|
||||
# Deletes a rule and verifies if it is deleted or not
|
||||
self.admin_client.delete_metering_label_rule(
|
||||
metering_label_rule_id)
|
||||
# Asserting that the rule is not found in list after deletion
|
||||
rules = (self.admin_client.list_metering_label_rules(
|
||||
id=metering_label_rule_id))
|
||||
self.assertEqual(len(rules['metering_label_rules']), 0)
|
||||
|
||||
@decorators.idempotent_id('05d7c750-6d26-44d6-82f3-c9dd1f81f358')
|
||||
def test_list_metering_labels(self):
|
||||
# Verify label filtering
|
||||
body = self.admin_client.list_metering_labels(id=33)
|
||||
metering_labels = body['metering_labels']
|
||||
self.assertEqual(0, len(metering_labels))
|
||||
|
||||
@decorators.idempotent_id('ec8e15ff-95d0-433b-b8a6-b466bddb1e50')
|
||||
def test_create_delete_metering_label_with_filters(self):
|
||||
# Creates a label
|
||||
name = data_utils.rand_name('metering-label')
|
||||
description = "label created by tempest"
|
||||
body = self.admin_client.create_metering_label(name=name,
|
||||
description=description)
|
||||
metering_label = body['metering_label']
|
||||
self.addCleanup(self._delete_metering_label,
|
||||
metering_label['id'])
|
||||
# Assert whether created labels are found in labels list or fail
|
||||
# if created labels are not found in labels list
|
||||
labels = (self.admin_client.list_metering_labels(
|
||||
id=metering_label['id']))
|
||||
self.assertEqual(len(labels['metering_labels']), 1)
|
||||
|
||||
@decorators.idempotent_id('46608f8d-2e27-4eb6-a0b4-dbe405144c4d')
|
||||
def test_create_delete_metering_label_with_name_max_length(self):
|
||||
name = LONG_NAME_OK
|
||||
body = self.admin_client.create_metering_label(name=name)
|
||||
metering_label = body['metering_label']
|
||||
self.addCleanup(self._delete_metering_label,
|
||||
metering_label['id'])
|
||||
labels = (self.admin_client.list_metering_labels(
|
||||
id=metering_label['id']))
|
||||
self.assertEqual(len(labels['metering_labels']), 1)
|
||||
|
||||
@decorators.idempotent_id('cfc500d9-9de6-4847-8803-62889c097d45')
|
||||
def test_show_metering_label(self):
|
||||
# Verifies the details of a label
|
||||
body = self.admin_client.show_metering_label(self.metering_label['id'])
|
||||
metering_label = body['metering_label']
|
||||
self.assertEqual(self.metering_label['id'], metering_label['id'])
|
||||
self.assertEqual(self.metering_label['tenant_id'],
|
||||
metering_label['tenant_id'])
|
||||
self.assertEqual(self.metering_label['name'], metering_label['name'])
|
||||
self.assertEqual(self.metering_label['description'],
|
||||
metering_label['description'])
|
||||
|
||||
@decorators.idempotent_id('cc832399-6681-493b-9d79-0202831a1281')
|
||||
def test_list_metering_label_rules(self):
|
||||
# Verify rule filtering
|
||||
body = self.admin_client.list_metering_label_rules(id=33)
|
||||
metering_label_rules = body['metering_label_rules']
|
||||
self.assertEqual(0, len(metering_label_rules))
|
||||
|
||||
@decorators.idempotent_id('f4d547cd-3aee-408f-bf36-454f8825e045')
|
||||
def test_create_delete_metering_label_rule_with_filters(self):
|
||||
# Creates a rule
|
||||
remote_ip_prefix = ("10.0.1.0/24" if self._ip_version == 4
|
||||
else "fd03::/64")
|
||||
body = (self.admin_client.create_metering_label_rule(
|
||||
remote_ip_prefix=remote_ip_prefix,
|
||||
direction="ingress",
|
||||
metering_label_id=self.metering_label['id']))
|
||||
metering_label_rule = body['metering_label_rule']
|
||||
self.addCleanup(self._delete_metering_label_rule,
|
||||
metering_label_rule['id'])
|
||||
# Assert whether created rules are found in rules list or fail
|
||||
# if created rules are not found in rules list
|
||||
rules = (self.admin_client.list_metering_label_rules(
|
||||
id=metering_label_rule['id']))
|
||||
self.assertEqual(len(rules['metering_label_rules']), 1)
|
||||
|
||||
@decorators.idempotent_id('b7354489-96ea-41f3-9452-bace120fb4a7')
|
||||
def test_show_metering_label_rule(self):
|
||||
# Verifies the details of a rule
|
||||
body = (self.admin_client.show_metering_label_rule(
|
||||
self.metering_label_rule['id']))
|
||||
metering_label_rule = body['metering_label_rule']
|
||||
self.assertEqual(self.metering_label_rule['id'],
|
||||
metering_label_rule['id'])
|
||||
self.assertEqual(self.metering_label_rule['remote_ip_prefix'],
|
||||
metering_label_rule['remote_ip_prefix'])
|
||||
self.assertEqual(self.metering_label_rule['direction'],
|
||||
metering_label_rule['direction'])
|
||||
self.assertEqual(self.metering_label_rule['metering_label_id'],
|
||||
metering_label_rule['metering_label_id'])
|
||||
self.assertFalse(metering_label_rule['excluded'])
|
||||
|
||||
|
||||
class MeteringIpV6TestJSON(MeteringTestJSON):
|
||||
_ip_version = 6
|
@ -1,34 +0,0 @@
|
||||
# Copyright 2016 FUJITSU LIMITED
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import metering as metering_apidef
|
||||
from neutron_lib.db import constants as db_const
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
LONG_NAME_NG = 'x' * (db_const.NAME_FIELD_SIZE + 1)
|
||||
|
||||
|
||||
class MeteringNegativeTestJSON(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = [metering_apidef.ALIAS]
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('8b3f7c84-9d37-4771-8681-bfd2c07f3c2d')
|
||||
def test_create_metering_label_with_too_long_name(self):
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.admin_client.create_metering_label,
|
||||
name=LONG_NAME_NG)
|
@ -1,166 +0,0 @@
|
||||
# Copyright 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
|
||||
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
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
from neutron_lib import constants as lib_constants
|
||||
|
||||
# 3 IP addresses are taken from every total for IPv4 these are reserved
|
||||
DEFAULT_IP4_RESERVED = 3
|
||||
# 2 IP addresses are taken from every total for IPv6 these are reserved
|
||||
# I assume the reason for having one less than IPv4 is it does not have
|
||||
# broadcast address
|
||||
DEFAULT_IP6_RESERVED = 2
|
||||
|
||||
DELETE_TIMEOUT = 10
|
||||
DELETE_SLEEP = 2
|
||||
|
||||
|
||||
class NetworksIpAvailabilityTest(base.BaseAdminNetworkTest):
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
Neutron:
|
||||
|
||||
test total and used ips for net create
|
||||
test total and ips for net after subnet create
|
||||
test total and used ips for net after subnet and port create
|
||||
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="network-ip-availability", service="network")
|
||||
def skip_checks(cls):
|
||||
super(NetworksIpAvailabilityTest, cls).skip_checks()
|
||||
|
||||
def _get_used_ips(self, network, net_availability):
|
||||
if network:
|
||||
for availability in net_availability['network_ip_availabilities']:
|
||||
if availability['network_id'] == network['id']:
|
||||
return availability['used_ips']
|
||||
|
||||
def _cleanUp_port(self, port_id):
|
||||
# delete port, any way to avoid race
|
||||
try:
|
||||
self.client.delete_port(port_id)
|
||||
# if port is not found, this means it was deleted in the test
|
||||
except lib_exc.NotFound:
|
||||
pass
|
||||
|
||||
def _assert_total_and_used_ips(self, expected_used, expected_total,
|
||||
network, net_availability):
|
||||
if network:
|
||||
for availability in net_availability['network_ip_availabilities']:
|
||||
if availability['network_id'] == network['id']:
|
||||
self.assertEqual(expected_total, availability['total_ips'])
|
||||
self.assertEqual(expected_used, availability['used_ips'])
|
||||
|
||||
def _create_subnet(self, network, ip_version):
|
||||
if ip_version == lib_constants.IP_VERSION_4:
|
||||
cidr = netaddr.IPNetwork('20.0.0.0/24')
|
||||
mask_bits = config.safe_get_config_value(
|
||||
'network', 'project_network_mask_bits')
|
||||
elif ip_version == lib_constants.IP_VERSION_6:
|
||||
cidr = netaddr.IPNetwork('20:db8::/64')
|
||||
mask_bits = config.safe_get_config_value(
|
||||
'network', 'project_network_v6_mask_bits')
|
||||
|
||||
subnet_cidr = next(cidr.subnet(mask_bits))
|
||||
prefix_len = subnet_cidr.prefixlen
|
||||
subnet = self.create_subnet(network,
|
||||
cidr=subnet_cidr,
|
||||
enable_dhcp=False,
|
||||
mask_bits=mask_bits,
|
||||
ip_version=ip_version)
|
||||
return subnet, prefix_len
|
||||
|
||||
|
||||
def calc_total_ips(prefix, ip_version):
|
||||
# will calculate total ips after removing reserved.
|
||||
if ip_version == lib_constants.IP_VERSION_4:
|
||||
total_ips = 2 ** (lib_constants.IPv4_BITS
|
||||
- prefix) - DEFAULT_IP4_RESERVED
|
||||
elif ip_version == lib_constants.IP_VERSION_6:
|
||||
total_ips = 2 ** (lib_constants.IPv6_BITS
|
||||
- prefix) - DEFAULT_IP6_RESERVED
|
||||
return total_ips
|
||||
|
||||
|
||||
class NetworksIpAvailabilityIPv4Test(NetworksIpAvailabilityTest):
|
||||
|
||||
@decorators.idempotent_id('0f33cc8c-1bf6-47d1-9ce1-010618240599')
|
||||
def test_admin_network_availability_before_subnet(self):
|
||||
net_name = data_utils.rand_name('network')
|
||||
network = self.create_network(network_name=net_name)
|
||||
self.addCleanup(self.client.delete_network, network['id'])
|
||||
net_availability = self.admin_client.list_network_ip_availabilities()
|
||||
self._assert_total_and_used_ips(0, 0, network, net_availability)
|
||||
|
||||
@decorators.idempotent_id('3aecd3b2-16ed-4b87-a54a-91d7b3c2986b')
|
||||
def test_net_ip_availability_after_subnet_and_ports(self):
|
||||
net_name = data_utils.rand_name('network')
|
||||
network = self.create_network(network_name=net_name)
|
||||
self.addCleanup(self.client.delete_network, network['id'])
|
||||
subnet, prefix = self._create_subnet(network, self._ip_version)
|
||||
self.addCleanup(self.client.delete_subnet, subnet['id'])
|
||||
body = self.admin_client.list_network_ip_availabilities()
|
||||
used_ip = self._get_used_ips(network, body)
|
||||
port1 = self.client.create_port(network_id=network['id'])
|
||||
self.addCleanup(self.client.delete_port, port1['port']['id'])
|
||||
port2 = self.client.create_port(network_id=network['id'])
|
||||
self.addCleanup(self.client.delete_port, port2['port']['id'])
|
||||
net_availability = self.admin_client.list_network_ip_availabilities()
|
||||
self._assert_total_and_used_ips(
|
||||
used_ip + 2,
|
||||
calc_total_ips(prefix, self._ip_version),
|
||||
network, net_availability)
|
||||
|
||||
@decorators.idempotent_id('9f11254d-757b-492e-b14b-f52144e4ee7b')
|
||||
def test_net_ip_availability_after_port_delete(self):
|
||||
net_name = data_utils.rand_name('network')
|
||||
network = self.create_network(network_name=net_name)
|
||||
self.addCleanup(self.client.delete_network, network['id'])
|
||||
subnet, prefix = self._create_subnet(network, self._ip_version)
|
||||
self.addCleanup(self.client.delete_subnet, subnet['id'])
|
||||
port = self.client.create_port(network_id=network['id'])
|
||||
self.addCleanup(self._cleanUp_port, port['port']['id'])
|
||||
net_availability = self.admin_client.list_network_ip_availabilities()
|
||||
used_ip = self._get_used_ips(network, net_availability)
|
||||
self.client.delete_port(port['port']['id'])
|
||||
|
||||
def get_net_availability():
|
||||
availabilities = self.admin_client.list_network_ip_availabilities()
|
||||
used_ip_after_port_delete = self._get_used_ips(network,
|
||||
availabilities)
|
||||
return used_ip - 1 == used_ip_after_port_delete
|
||||
|
||||
self.assertTrue(
|
||||
test_utils.call_until_true(
|
||||
get_net_availability, DELETE_TIMEOUT, DELETE_SLEEP),
|
||||
msg="IP address did not become available after port delete")
|
||||
|
||||
|
||||
class NetworksIpAvailabilityIPv6Test(NetworksIpAvailabilityIPv4Test):
|
||||
|
||||
_ip_version = lib_constants.IP_VERSION_6
|
@ -1,29 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import test_network_ip_availability as net_ip
|
||||
|
||||
|
||||
class NetworksIpAvailabilityNegativeTest(net_ip.NetworksIpAvailabilityTest):
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('3b8693eb-6c57-4ea1-ab84-3730c9ee9c84')
|
||||
def test_network_availability_nonexistent_network_id(self):
|
||||
self.assertRaises(lib_exc.NotFound,
|
||||
self.admin_client.show_network_ip_availability,
|
||||
uuidutils.generate_uuid())
|
@ -1,213 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
|
||||
class NetworksTestJSON(base.BaseNetworkTest):
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
Neutron:
|
||||
|
||||
list tenant's networks
|
||||
show a network
|
||||
show a tenant network details
|
||||
|
||||
v2.0 of the Neutron API is assumed.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(NetworksTestJSON, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
|
||||
@decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
|
||||
def test_show_network(self):
|
||||
# Verify the details of a network
|
||||
body = self.client.show_network(self.network['id'])
|
||||
network = body['network']
|
||||
fields = ['id', 'name']
|
||||
if utils.is_extension_enabled('net-mtu', 'network'):
|
||||
fields.append('mtu')
|
||||
for key in fields:
|
||||
self.assertEqual(network[key], self.network[key])
|
||||
project_id = self.client.tenant_id
|
||||
self.assertEqual(project_id, network['tenant_id'])
|
||||
if utils.is_extension_enabled('project-id', 'network'):
|
||||
self.assertEqual(project_id, network['project_id'])
|
||||
|
||||
@decorators.idempotent_id('26f2b7a5-2cd1-4f3a-b11f-ad259b099b11')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_show_network_fields_keystone_v3(self):
|
||||
|
||||
def _check_show_network_fields(fields, expect_project_id,
|
||||
expect_tenant_id):
|
||||
params = {}
|
||||
if fields:
|
||||
params['fields'] = fields
|
||||
body = self.client.show_network(self.network['id'], **params)
|
||||
network = body['network']
|
||||
self.assertEqual(expect_project_id, 'project_id' in network)
|
||||
self.assertEqual(expect_tenant_id, 'tenant_id' in network)
|
||||
|
||||
_check_show_network_fields(None, True, True)
|
||||
_check_show_network_fields(['tenant_id'], False, True)
|
||||
_check_show_network_fields(['project_id'], True, False)
|
||||
_check_show_network_fields(['project_id', 'tenant_id'], True, True)
|
||||
|
||||
@decorators.idempotent_id('0cc0552f-afaf-4231-b7a7-c2a1774616da')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_create_network_keystone_v3(self):
|
||||
project_id = self.client.tenant_id
|
||||
|
||||
name = 'created-with-project_id'
|
||||
new_net = self.create_network_keystone_v3(name, project_id)
|
||||
self.assertEqual(name, new_net['name'])
|
||||
self.assertEqual(project_id, new_net['project_id'])
|
||||
self.assertEqual(project_id, new_net['tenant_id'])
|
||||
|
||||
body = self.client.list_networks(id=new_net['id'])['networks'][0]
|
||||
self.assertEqual(name, body['name'])
|
||||
|
||||
new_name = 'create-with-project_id-2'
|
||||
body = self.client.update_network(new_net['id'], name=new_name)
|
||||
new_net = body['network']
|
||||
self.assertEqual(new_name, new_net['name'])
|
||||
self.assertEqual(project_id, new_net['project_id'])
|
||||
self.assertEqual(project_id, new_net['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('94e2a44c-3367-4253-8c2a-22deaf59e96c')
|
||||
@utils.requires_ext(extension="dns-integration",
|
||||
service="network")
|
||||
def test_create_update_network_dns_domain(self):
|
||||
domain1 = 'test.org.'
|
||||
body = self.create_network(dns_domain=domain1)
|
||||
self.assertEqual(domain1, body['dns_domain'])
|
||||
net_id = body['id']
|
||||
body = self.client.list_networks(id=net_id)['networks'][0]
|
||||
self.assertEqual(domain1, body['dns_domain'])
|
||||
domain2 = 'd.org.'
|
||||
body = self.client.update_network(net_id, dns_domain=domain2)
|
||||
self.assertEqual(domain2, body['network']['dns_domain'])
|
||||
body = self.client.show_network(net_id)['network']
|
||||
self.assertEqual(domain2, body['dns_domain'])
|
||||
|
||||
@decorators.idempotent_id('a23186b9-aa6f-4b08-b877-35ca3b9cd54c')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_list_networks_fields_keystone_v3(self):
|
||||
def _check_list_networks_fields(fields, expect_project_id,
|
||||
expect_tenant_id):
|
||||
params = {}
|
||||
if fields:
|
||||
params['fields'] = fields
|
||||
body = self.client.list_networks(**params)
|
||||
networks = body['networks']
|
||||
self.assertNotEmpty(networks, "Network list returned is empty")
|
||||
for network in networks:
|
||||
self.assertEqual(expect_project_id, 'project_id' in network)
|
||||
self.assertEqual(expect_tenant_id, 'tenant_id' in network)
|
||||
|
||||
_check_list_networks_fields(None, True, True)
|
||||
_check_list_networks_fields(['tenant_id'], False, True)
|
||||
_check_list_networks_fields(['project_id'], True, False)
|
||||
_check_list_networks_fields(['project_id', 'tenant_id'], True, True)
|
||||
|
||||
|
||||
# TODO(ihrachys): check that bad mtu is not allowed; current API extension
|
||||
# definition doesn't enforce values
|
||||
# TODO(ihrachys): check that new segment reservation updates mtu, once
|
||||
# https://review.openstack.org/#/c/353115/ is merged
|
||||
class NetworksMtuTestJSON(base.BaseNetworkTest):
|
||||
required_extensions = ['net-mtu', 'net-mtu-writable']
|
||||
|
||||
@decorators.idempotent_id('c79dbf94-ee26-420f-a56f-382aaccb1a41')
|
||||
def test_create_network_custom_mtu(self):
|
||||
# 68 should be supported by all implementations, as per api-ref
|
||||
network = self.create_network(mtu=68)
|
||||
body = self.client.show_network(network['id'])['network']
|
||||
self.assertEqual(68, body['mtu'])
|
||||
|
||||
@decorators.idempotent_id('2d35d49d-9d16-465c-92c7-4768eb717688')
|
||||
@testtools.skipUnless(config.CONF.network_feature_enabled.ipv6,
|
||||
'IPv6 is not enabled')
|
||||
def test_update_network_custom_mtu(self):
|
||||
# 68 should be supported by all implementations, as per api-ref
|
||||
network = self.create_network(mtu=68)
|
||||
body = self.client.show_network(network['id'])['network']
|
||||
self.assertEqual(68, body['mtu'])
|
||||
|
||||
# 1280 should be supported by all ipv6 compliant implementations
|
||||
self.client.update_network(network['id'], mtu=1280)
|
||||
body = self.client.show_network(network['id'])['network']
|
||||
self.assertEqual(1280, body['mtu'])
|
||||
|
||||
|
||||
class NetworksSearchCriteriaTest(base.BaseSearchCriteriaTest):
|
||||
|
||||
resource = 'network'
|
||||
|
||||
list_kwargs = {'shared': False, 'router:external': False}
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(NetworksSearchCriteriaTest, cls).resource_setup()
|
||||
for name in cls.resource_names:
|
||||
cls.create_network(network_name=name)
|
||||
|
||||
@decorators.idempotent_id('de27d34a-bd9d-4516-83d6-81ef723f7d0d')
|
||||
def test_list_sorts_asc(self):
|
||||
self._test_list_sorts_asc()
|
||||
|
||||
@decorators.idempotent_id('e767a160-59f9-4c4b-8dc1-72124a68640a')
|
||||
def test_list_sorts_desc(self):
|
||||
self._test_list_sorts_desc()
|
||||
|
||||
@decorators.idempotent_id('71389852-f57b-49f2-b109-77b705e9e8af')
|
||||
def test_list_pagination(self):
|
||||
self._test_list_pagination()
|
||||
|
||||
@decorators.idempotent_id('b7e153d2-37c3-48d4-8390-ec13498fee3d')
|
||||
def test_list_pagination_with_marker(self):
|
||||
self._test_list_pagination_with_marker()
|
||||
|
||||
@decorators.idempotent_id('8a9c89df-0ee7-4c0d-8f1d-ec8f27cf362f')
|
||||
def test_list_pagination_with_href_links(self):
|
||||
self._test_list_pagination_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('79a52810-2156-4ab6-b577-9e46e58d4b58')
|
||||
def test_list_pagination_page_reverse_asc(self):
|
||||
self._test_list_pagination_page_reverse_asc()
|
||||
|
||||
@decorators.idempotent_id('36a4671f-a542-442f-bc44-a8873ee778d1')
|
||||
def test_list_pagination_page_reverse_desc(self):
|
||||
self._test_list_pagination_page_reverse_desc()
|
||||
|
||||
@decorators.idempotent_id('13eb066c-aa90-406d-b4c3-39595bf8f910')
|
||||
def test_list_pagination_page_reverse_with_href_links(self):
|
||||
self._test_list_pagination_page_reverse_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('f1867fc5-e1d6-431f-bc9f-8b882e43a7f9')
|
||||
def test_list_no_pagination_limit_0(self):
|
||||
self._test_list_no_pagination_limit_0()
|
||||
|
||||
@decorators.idempotent_id('3574ec9b-a8b8-43e3-9c11-98f5875df6a9')
|
||||
def test_list_validation_filters(self):
|
||||
self._test_list_validation_filters()
|
@ -1,36 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class NetworksNegativeTest(base.BaseNetworkTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(NetworksNegativeTest, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('9f80f25b-5d1b-4f26-9f6b-774b9b270819')
|
||||
def test_delete_network_in_use(self):
|
||||
port = self.client.create_port(network_id=self.network['id'])
|
||||
self.addCleanup(self.client.delete_port, port['port']['id'])
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.client.delete_subnet(self.subnet['id'])
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.client.delete_network(self.network['id'])
|
@ -1,183 +0,0 @@
|
||||
# Copyright 2014 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class PortsTestJSON(base.BaseNetworkTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(PortsTestJSON, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
|
||||
def _confirm_dns_assignment(self, port):
|
||||
# NOTE(manjeets) port created with single subnet
|
||||
# would have only one dns_assignment
|
||||
dns_assignment = port['dns_assignment'][0]
|
||||
ip = port['fixed_ips'][0]['ip_address']
|
||||
if port['dns_name']:
|
||||
hostname = port['dns_name']
|
||||
else:
|
||||
hostname = 'host-%s' % ip.replace('.', '-')
|
||||
self.assertEqual(hostname, dns_assignment['hostname'])
|
||||
|
||||
# To avoid hard coding the expected dns_domain value
|
||||
# in neutron.conf we just check that the fqdn starts
|
||||
# with correct hostname
|
||||
self.assertTrue(dns_assignment['fqdn'].startswith(hostname))
|
||||
self.assertEqual(ip, dns_assignment['ip_address'])
|
||||
|
||||
@decorators.idempotent_id('c72c1c0c-2193-4aca-bbb4-b1442640bbbb')
|
||||
@utils.requires_ext(extension="standard-attr-description",
|
||||
service="network")
|
||||
def test_create_update_port_description(self):
|
||||
body = self.create_port(self.network,
|
||||
description='d1')
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.list_ports(id=body['id'])['ports'][0]
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.update_port(body['id'],
|
||||
description='d2')
|
||||
self.assertEqual('d2', body['port']['description'])
|
||||
body = self.client.list_ports(id=body['port']['id'])['ports'][0]
|
||||
self.assertEqual('d2', body['description'])
|
||||
|
||||
@decorators.idempotent_id('539fbefe-fb36-48aa-9a53-8c5fbd44e492')
|
||||
@utils.requires_ext(extension="dns-integration",
|
||||
service="network")
|
||||
def test_create_update_port_with_dns_name(self):
|
||||
# NOTE(manjeets) dns_domain is set to openstackgate.local
|
||||
# so dns_name for port can be set
|
||||
self.create_subnet(self.network)
|
||||
body = self.create_port(self.network, dns_name='d1')
|
||||
self.assertEqual('d1', body['dns_name'])
|
||||
self._confirm_dns_assignment(body)
|
||||
body = self.client.list_ports(id=body['id'])['ports'][0]
|
||||
self._confirm_dns_assignment(body)
|
||||
self.assertEqual('d1', body['dns_name'])
|
||||
body = self.client.update_port(body['id'],
|
||||
dns_name='d2')
|
||||
self.assertEqual('d2', body['port']['dns_name'])
|
||||
self._confirm_dns_assignment(body['port'])
|
||||
body = self.client.show_port(body['port']['id'])['port']
|
||||
self.assertEqual('d2', body['dns_name'])
|
||||
self._confirm_dns_assignment(body)
|
||||
|
||||
@decorators.idempotent_id('435e89df-a8bb-4b41-801a-9f20d362d777')
|
||||
@utils.requires_ext(extension="dns-integration",
|
||||
service="network")
|
||||
def test_create_update_port_with_no_dns_name(self):
|
||||
self.create_subnet(self.network)
|
||||
body = self.create_port(self.network)
|
||||
self.assertFalse(body['dns_name'])
|
||||
self._confirm_dns_assignment(body)
|
||||
port_body = self.client.show_port(body['id'])
|
||||
self.assertFalse(port_body['port']['dns_name'])
|
||||
self._confirm_dns_assignment(port_body['port'])
|
||||
|
||||
@decorators.idempotent_id('dfe8cc79-18d9-4ae8-acef-3ec6bb719aa7')
|
||||
@utils.requires_ext(extension="dns-domain-ports",
|
||||
service="network")
|
||||
def test_create_update_port_with_dns_domain(self):
|
||||
self.create_subnet(self.network)
|
||||
body = self.create_port(self.network, dns_name='d1',
|
||||
dns_domain='test.org.')
|
||||
self.assertEqual('d1', body['dns_name'])
|
||||
self.assertEqual('test.org.', body['dns_domain'])
|
||||
self._confirm_dns_assignment(body)
|
||||
body = self.client.list_ports(id=body['id'])['ports'][0]
|
||||
self._confirm_dns_assignment(body)
|
||||
self.assertEqual('d1', body['dns_name'])
|
||||
self.assertEqual('test.org.', body['dns_domain'])
|
||||
body = self.client.update_port(body['id'],
|
||||
dns_name='d2', dns_domain='d.org.')
|
||||
self.assertEqual('d2', body['port']['dns_name'])
|
||||
self.assertEqual('d.org.', body['dns_domain'])
|
||||
self._confirm_dns_assignment(body['port'])
|
||||
body = self.client.show_port(body['port']['id'])['port']
|
||||
self.assertEqual('d2', body['dns_name'])
|
||||
self.assertEqual('d.org.', body['dns_domain'])
|
||||
self._confirm_dns_assignment(body)
|
||||
|
||||
@decorators.idempotent_id('c72c1c0c-2193-4aca-bbb4-b1442640c123')
|
||||
def test_change_dhcp_flag_then_create_port(self):
|
||||
s = self.create_subnet(self.network, enable_dhcp=False)
|
||||
self.create_port(self.network)
|
||||
self.client.update_subnet(s['id'], enable_dhcp=True)
|
||||
self.create_port(self.network)
|
||||
|
||||
@decorators.idempotent_id('1d6d8683-8691-43c6-a7ba-c69723258726')
|
||||
def test_add_ips_to_port(self):
|
||||
s = self.create_subnet(self.network)
|
||||
port = self.create_port(self.network)
|
||||
# request another IP on the same subnet
|
||||
port['fixed_ips'].append({'subnet_id': s['id']})
|
||||
updated = self.client.update_port(port['id'],
|
||||
fixed_ips=port['fixed_ips'])
|
||||
subnets = [ip['subnet_id'] for ip in updated['port']['fixed_ips']]
|
||||
expected = [s['id'], s['id']]
|
||||
self.assertEqual(expected, subnets)
|
||||
|
||||
|
||||
class PortsSearchCriteriaTest(base.BaseSearchCriteriaTest):
|
||||
|
||||
resource = 'port'
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(PortsSearchCriteriaTest, cls).resource_setup()
|
||||
net = cls.create_network(network_name='port-search-test-net')
|
||||
for name in cls.resource_names:
|
||||
cls.create_port(net, name=name)
|
||||
|
||||
@decorators.idempotent_id('9ab73df4-960a-4ae3-87d3-60992b8d3e2d')
|
||||
def test_list_sorts_asc(self):
|
||||
self._test_list_sorts_asc()
|
||||
|
||||
@decorators.idempotent_id('b426671d-7270-430f-82ff-8f33eec93010')
|
||||
def test_list_sorts_desc(self):
|
||||
self._test_list_sorts_desc()
|
||||
|
||||
@decorators.idempotent_id('a202fdc8-6616-45df-b6a0-463932de6f94')
|
||||
def test_list_pagination(self):
|
||||
self._test_list_pagination()
|
||||
|
||||
@decorators.idempotent_id('f4723b8e-8186-4b9a-bf9e-57519967e048')
|
||||
def test_list_pagination_with_marker(self):
|
||||
self._test_list_pagination_with_marker()
|
||||
|
||||
@decorators.idempotent_id('fcd02a7a-f07e-4d5e-b0ca-b58e48927a9b')
|
||||
def test_list_pagination_with_href_links(self):
|
||||
self._test_list_pagination_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('3afe7024-77ab-4cfe-824b-0b2bf4217727')
|
||||
def test_list_no_pagination_limit_0(self):
|
||||
self._test_list_no_pagination_limit_0()
|
||||
|
||||
@decorators.idempotent_id('b8857391-dc44-40cc-89b7-2800402e03ce')
|
||||
def test_list_pagination_page_reverse_asc(self):
|
||||
self._test_list_pagination_page_reverse_asc()
|
||||
|
||||
@decorators.idempotent_id('4e51e9c9-ceae-4ec0-afd4-147569247699')
|
||||
def test_list_pagination_page_reverse_desc(self):
|
||||
self._test_list_pagination_page_reverse_desc()
|
||||
|
||||
@decorators.idempotent_id('74293e59-d794-4a93-be09-38667199ef68')
|
||||
def test_list_pagination_page_reverse_with_href_links(self):
|
||||
self._test_list_pagination_page_reverse_with_href_links()
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api.definitions import qos as qos_apidef
|
||||
from neutron_lib.db import constants as db_const
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
LONG_NAME_NG = 'z' * (db_const.NAME_FIELD_SIZE + 1)
|
||||
LONG_DESCRIPTION_NG = 'z' * (db_const.LONG_DESCRIPTION_FIELD_SIZE + 1)
|
||||
LONG_TENANT_ID_NG = 'z' * (db_const.PROJECT_ID_FIELD_SIZE + 1)
|
||||
|
||||
|
||||
class QosNegativeTestJSON(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = [qos_apidef.ALIAS]
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('b9dce555-d3b3-11e5-950a-54ee757c77da')
|
||||
def test_add_policy_with_too_long_name(self):
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.create_qos_policy,
|
||||
LONG_NAME_NG, 'test policy desc1', False)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('b9dce444-d3b3-11e5-950a-54ee747c99db')
|
||||
def test_add_policy_with_too_long_description(self):
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.create_qos_policy,
|
||||
'test-policy', LONG_DESCRIPTION_NG, False)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('b9dce444-d3b3-11e5-950a-54ee757c77dc')
|
||||
def test_add_policy_with_too_long_tenant_id(self):
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.create_qos_policy,
|
||||
'test-policy', 'test policy desc1',
|
||||
False, LONG_TENANT_ID_NG)
|
@ -1,398 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest.api import base_security_groups as bsg
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
|
||||
class TestRevisions(base.BaseAdminNetworkTest, bsg.BaseSecGroupTest):
|
||||
|
||||
required_extensions = ['standard-attr-revisions']
|
||||
|
||||
@decorators.idempotent_id('4a26a4be-9c53-483c-bc50-b53f1db10ac6')
|
||||
def test_update_network_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
self.assertIn('revision_number', net)
|
||||
updated = self.client.update_network(net['id'], name='newnet')
|
||||
self.assertGreater(updated['network']['revision_number'],
|
||||
net['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('4a26a4be-9c53-483c-bc50-b11111113333')
|
||||
def test_update_network_constrained_by_revision(self):
|
||||
net = self.create_network()
|
||||
current = net['revision_number']
|
||||
stale = current - 1
|
||||
# using a stale number should fail
|
||||
self.assertRaises(
|
||||
exceptions.PreconditionFailed,
|
||||
self.client.update_network,
|
||||
net['id'], name='newnet',
|
||||
headers={'If-Match': 'revision_number=%s' % stale}
|
||||
)
|
||||
|
||||
# using current should pass. in case something is updating the network
|
||||
# on the server at the same time, we have to re-read and update to be
|
||||
# safe
|
||||
for i in range(100):
|
||||
current = (self.client.show_network(net['id'])
|
||||
['network']['revision_number'])
|
||||
try:
|
||||
self.client.update_network(
|
||||
net['id'], name='newnet',
|
||||
headers={'If-Match': 'revision_number=%s' % current})
|
||||
except exceptions.UnexpectedResponseCode:
|
||||
continue
|
||||
break
|
||||
else:
|
||||
self.fail("Failed to update network after 100 tries.")
|
||||
|
||||
@decorators.idempotent_id('cac7ecde-12d5-4331-9a03-420899dea077')
|
||||
def test_update_port_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
self.assertIn('revision_number', port)
|
||||
updated = self.client.update_port(port['id'], name='newport')
|
||||
self.assertGreater(updated['port']['revision_number'],
|
||||
port['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('c1c4fa41-8e89-44d0-9bfc-409f3b66dc57')
|
||||
def test_update_subnet_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
subnet = self.create_subnet(net)
|
||||
self.addCleanup(self.client.delete_subnet, subnet['id'])
|
||||
self.assertIn('revision_number', subnet)
|
||||
updated = self.client.update_subnet(subnet['id'], name='newsub')
|
||||
self.assertGreater(updated['subnet']['revision_number'],
|
||||
subnet['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('e8c5d7db-2b8d-4615-a476-6e537437c4f2')
|
||||
def test_update_subnetpool_bumps_revision(self):
|
||||
sp = self.create_subnetpool('subnetpool', default_prefixlen=24,
|
||||
prefixes=['10.0.0.0/8'])
|
||||
self.addCleanup(self.client.delete_subnetpool, sp['id'])
|
||||
self.assertIn('revision_number', sp)
|
||||
updated = self.admin_client.update_subnetpool(sp['id'], name='sp2')
|
||||
self.assertGreater(updated['subnetpool']['revision_number'],
|
||||
sp['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('e8c5d7db-2b8d-4567-a326-6e123437c4d1')
|
||||
def test_update_subnet_bumps_network_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
subnet = self.create_subnet(net)
|
||||
updated = self.client.show_network(net['id'])
|
||||
self.assertGreater(updated['network']['revision_number'],
|
||||
net['revision_number'])
|
||||
self.client.delete_subnet(subnet['id'])
|
||||
updated2 = self.client.show_network(net['id'])
|
||||
self.assertGreater(updated2['network']['revision_number'],
|
||||
updated['network']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('6c256f71-c929-4200-b3dc-4e1843506be5')
|
||||
@utils.requires_ext(extension="security-group", service="network")
|
||||
def test_update_sg_group_bumps_revision(self):
|
||||
sg, name = self._create_security_group()
|
||||
self.assertIn('revision_number', sg['security_group'])
|
||||
update_body = self.client.update_security_group(
|
||||
sg['security_group']['id'], name='new_sg_name')
|
||||
self.assertGreater(update_body['security_group']['revision_number'],
|
||||
sg['security_group']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('6489632f-8550-4453-a674-c98849742967')
|
||||
@utils.requires_ext(extension="security-group", service="network")
|
||||
def test_update_port_sg_binding_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
sg = self._create_security_group()[0]
|
||||
self.client.update_port(
|
||||
port['id'], security_groups=[sg['security_group']['id']])
|
||||
updated = self.client.show_port(port['id'])
|
||||
updated2 = self.client.update_port(port['id'], security_groups=[])
|
||||
self.assertGreater(updated['port']['revision_number'],
|
||||
port['revision_number'])
|
||||
self.assertGreater(updated2['port']['revision_number'],
|
||||
updated['port']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('29c7ab2b-d1d8-425d-8cec-fcf632960f22')
|
||||
@utils.requires_ext(extension="security-group", service="network")
|
||||
def test_update_sg_rule_bumps_sg_revision(self):
|
||||
sg, name = self._create_security_group()
|
||||
rule = self.client.create_security_group_rule(
|
||||
security_group_id=sg['security_group']['id'],
|
||||
protocol='tcp', direction='ingress', ethertype=self.ethertype,
|
||||
port_range_min=60, port_range_max=70)
|
||||
updated = self.client.show_security_group(sg['security_group']['id'])
|
||||
self.assertGreater(updated['security_group']['revision_number'],
|
||||
sg['security_group']['revision_number'])
|
||||
self.client.delete_security_group_rule(
|
||||
rule['security_group_rule']['id'])
|
||||
updated2 = self.client.show_security_group(sg['security_group']['id'])
|
||||
self.assertGreater(updated2['security_group']['revision_number'],
|
||||
updated['security_group']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('db70c285-0365-4fac-9f55-2a0ad8cf55a8')
|
||||
@utils.requires_ext(extension="allowed-address-pairs", service="network")
|
||||
def test_update_allowed_address_pairs_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
updated = self.client.update_port(
|
||||
port['id'], allowed_address_pairs=[{'ip_address': '1.1.1.1/32'}])
|
||||
self.assertGreater(updated['port']['revision_number'],
|
||||
port['revision_number'])
|
||||
updated2 = self.client.update_port(
|
||||
port['id'], allowed_address_pairs=[])
|
||||
self.assertGreater(updated2['port']['revision_number'],
|
||||
updated['port']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('a21ec3b4-3569-4b77-bf29-4177edaa2df5')
|
||||
@utils.requires_ext(extension="extra_dhcp_opt", service="network")
|
||||
def test_update_extra_dhcp_opt_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
opts = [{'opt_value': 'pxelinux.0', 'opt_name': 'bootfile-name'}]
|
||||
updated = self.client.update_port(port['id'], extra_dhcp_opts=opts)
|
||||
self.assertGreater(updated['port']['revision_number'],
|
||||
port['revision_number'])
|
||||
opts[0]['opt_value'] = 'pxelinux.77'
|
||||
updated2 = self.client.update_port(
|
||||
port['id'], extra_dhcp_opts=opts)
|
||||
self.assertGreater(updated2['port']['revision_number'],
|
||||
updated['port']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('40ba648f-f374-4c29-a5b7-489dd5a38a4e')
|
||||
@utils.requires_ext(extension="dns-integration", service="network")
|
||||
def test_update_dns_domain_bumps_revision(self):
|
||||
net = self.create_network(dns_domain='example.test.')
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
updated = self.client.update_network(net['id'], dns_domain='exa.test.')
|
||||
self.assertGreater(updated['network']['revision_number'],
|
||||
net['revision_number'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
updated = self.client.update_port(port['id'], dns_name='port1')
|
||||
if not updated['port']['dns_name']:
|
||||
self.skipTest("Server does not have DNS domain configured.")
|
||||
self.assertGreater(updated['port']['revision_number'],
|
||||
port['revision_number'])
|
||||
updated2 = self.client.update_port(port['id'], dns_name='')
|
||||
self.assertGreater(updated2['port']['revision_number'],
|
||||
updated['port']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('8482324f-cf59-4d73-b98e-d37119255300')
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
@utils.requires_ext(extension="extraroute", service="network")
|
||||
def test_update_router_extra_routes_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
subnet = self.create_subnet(net)
|
||||
self.addCleanup(self.client.delete_subnet, subnet['id'])
|
||||
subgateway = netaddr.IPAddress(subnet['gateway_ip'])
|
||||
router = self.create_router(router_name='test')
|
||||
self.addCleanup(self.client.delete_router, router['id'])
|
||||
self.create_router_interface(router['id'], subnet['id'])
|
||||
self.addCleanup(
|
||||
self.client.remove_router_interface_with_subnet_id,
|
||||
router['id'],
|
||||
subnet['id'])
|
||||
router = self.client.show_router(router['id'])['router']
|
||||
updated = self.client.update_extra_routes(
|
||||
router['id'], str(subgateway + 1), '2.0.0.0/24')
|
||||
self.assertGreater(updated['router']['revision_number'],
|
||||
router['revision_number'])
|
||||
updated2 = self.client.delete_extra_routes(router['id'])
|
||||
self.assertGreater(updated2['router']['revision_number'],
|
||||
updated['router']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('6bd18702-e25a-4b4b-8c0c-680113533511')
|
||||
@utils.requires_ext(extension="subnet-service-types", service="network")
|
||||
def test_update_subnet_service_types_bumps_revisions(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
subnet = self.create_subnet(net)
|
||||
self.addCleanup(self.client.delete_subnet, subnet['id'])
|
||||
updated = self.client.update_subnet(
|
||||
subnet['id'], service_types=['compute:'])
|
||||
self.assertGreater(updated['subnet']['revision_number'],
|
||||
subnet['revision_number'])
|
||||
updated2 = self.client.update_subnet(
|
||||
subnet['id'], service_types=[])
|
||||
self.assertGreater(updated2['subnet']['revision_number'],
|
||||
updated['subnet']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('9c83105c-9973-45ff-9ca2-e66d64700abe')
|
||||
@utils.requires_ext(extension="port-security", service="network")
|
||||
def test_update_port_security_bumps_revisions(self):
|
||||
net = self.create_network(port_security_enabled=False)
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
updated = self.client.update_network(net['id'],
|
||||
port_security_enabled=True)
|
||||
self.assertGreater(updated['network']['revision_number'],
|
||||
net['revision_number'])
|
||||
updated2 = self.client.update_network(net['id'],
|
||||
port_security_enabled=False)
|
||||
self.assertGreater(updated2['network']['revision_number'],
|
||||
updated['network']['revision_number'])
|
||||
port = self.create_port(net, port_security_enabled=False)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
updated = self.client.update_port(port['id'],
|
||||
port_security_enabled=True)
|
||||
self.assertGreater(updated['port']['revision_number'],
|
||||
port['revision_number'])
|
||||
updated2 = self.client.update_port(port['id'],
|
||||
port_security_enabled=False)
|
||||
self.assertGreater(updated2['port']['revision_number'],
|
||||
updated['port']['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('68d5ac3a-11a1-4847-8e2e-5843c043d89b')
|
||||
@utils.requires_ext(extension="binding", service="network")
|
||||
def test_portbinding_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
port = self.admin_client.update_port(
|
||||
port['id'], **{'binding:host_id': 'badhost1'})['port']
|
||||
updated = self.admin_client.update_port(
|
||||
port['id'], **{'binding:host_id': 'badhost2'})['port']
|
||||
self.assertGreater(updated['revision_number'],
|
||||
port['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('4a37bde9-1975-47e0-9b8c-2c9ca36415b0')
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def test_update_router_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
subnet = self.create_subnet(net)
|
||||
self.addCleanup(self.client.delete_subnet, subnet['id'])
|
||||
router = self.create_router(router_name='test')
|
||||
self.addCleanup(self.client.delete_router, router['id'])
|
||||
self.assertIn('revision_number', router)
|
||||
rev1 = router['revision_number']
|
||||
router = self.client.update_router(router['id'],
|
||||
name='test2')['router']
|
||||
self.assertGreater(router['revision_number'], rev1)
|
||||
self.create_router_interface(router['id'], subnet['id'])
|
||||
self.addCleanup(
|
||||
self.client.remove_router_interface_with_subnet_id,
|
||||
router['id'],
|
||||
subnet['id'])
|
||||
updated = self.client.show_router(router['id'])['router']
|
||||
self.assertGreater(updated['revision_number'],
|
||||
router['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('9de71ebc-f5df-4cd0-80bc-60299fce3ce9')
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
@utils.requires_ext(extension="standard-attr-description",
|
||||
service="network")
|
||||
def test_update_floatingip_bumps_revision(self):
|
||||
ext_id = config.CONF.network.public_network_id
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
subnet = self.create_subnet(net)
|
||||
self.addCleanup(self.client.delete_subnet, subnet['id'])
|
||||
router = self.create_router('test', external_network_id=ext_id)
|
||||
self.addCleanup(self.client.delete_router, router['id'])
|
||||
self.create_router_interface(router['id'], subnet['id'])
|
||||
self.addCleanup(
|
||||
self.client.remove_router_interface_with_subnet_id,
|
||||
router['id'],
|
||||
subnet['id'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
body = self.client.create_floatingip(
|
||||
floating_network_id=ext_id,
|
||||
port_id=port['id'],
|
||||
description='d1'
|
||||
)['floatingip']
|
||||
self.floating_ips.append(body)
|
||||
self.assertIn('revision_number', body)
|
||||
b2 = self.client.update_floatingip(body['id'], description='d2')
|
||||
self.assertGreater(b2['floatingip']['revision_number'],
|
||||
body['revision_number'])
|
||||
# disassociate
|
||||
self.client.update_floatingip(b2['floatingip']['id'], port_id=None)
|
||||
|
||||
@decorators.idempotent_id('afb6486c-41b5-483e-a500-3c506f4deb49')
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
@utils.requires_ext(extension="l3-ha", service="network")
|
||||
def test_update_router_extra_attributes_bumps_revision(self):
|
||||
# updates from CVR to CVR-HA are supported on every release,
|
||||
# but only the admin can forcibly create a non-HA router
|
||||
router_args = {'tenant_id': self.client.tenant_id,
|
||||
'ha': False}
|
||||
router = self.admin_client.create_router('r1', True,
|
||||
**router_args)['router']
|
||||
self.addCleanup(self.client.delete_router, router['id'])
|
||||
self.assertIn('revision_number', router)
|
||||
rev1 = router['revision_number']
|
||||
router = self.admin_client.update_router(
|
||||
router['id'], admin_state_up=False)['router']
|
||||
self.assertGreater(router['revision_number'], rev1)
|
||||
self.admin_client.update_router(router['id'], ha=True)['router']
|
||||
updated = self.client.show_router(router['id'])['router']
|
||||
self.assertGreater(updated['revision_number'],
|
||||
router['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('90743b00-b0e2-40e4-9524-1c884fe3ef23')
|
||||
@utils.requires_ext(extension="external-net", service="network")
|
||||
@utils.requires_ext(extension="auto-allocated-topology", service="network")
|
||||
@utils.requires_ext(extension="subnet_allocation", service="network")
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def test_update_external_network_bumps_revision(self):
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
self.assertIn('revision_number', net)
|
||||
updated = self.admin_client.update_network(net['id'],
|
||||
**{'router:external': True})
|
||||
self.assertGreater(updated['network']['revision_number'],
|
||||
net['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('5af6450a-0f61-49c3-b628-38db77c7b856')
|
||||
@utils.requires_ext(extension="qos", service="network")
|
||||
def test_update_qos_port_policy_binding_bumps_revision(self):
|
||||
policy = self.create_qos_policy(name='port-policy', shared=False)
|
||||
net = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, net['id'])
|
||||
port = self.create_port(net)
|
||||
self.addCleanup(self.client.delete_port, port['id'])
|
||||
updated = self.admin_client.update_port(
|
||||
port['id'], qos_policy_id=policy['id'])
|
||||
self.assertGreater(updated['port']['revision_number'],
|
||||
port['revision_number'])
|
||||
|
||||
@decorators.idempotent_id('817da343-c6e4-445c-9519-a621f124dfbe')
|
||||
@utils.requires_ext(extension="qos", service="network")
|
||||
def test_update_qos_network_policy_binding_bumps_revision(self):
|
||||
policy = self.create_qos_policy(name='network-policy', shared=False)
|
||||
network = self.create_network()
|
||||
self.addCleanup(self.client.delete_network, network['id'])
|
||||
updated = self.admin_client.update_network(
|
||||
network['id'], qos_policy_id=policy['id'])
|
||||
self.assertGreater(updated['network']['revision_number'],
|
||||
network['revision_number'])
|
@ -1,327 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from tempest.common import utils as tutils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.common import utils
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest.api import base_routers
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class RoutersTest(base_routers.BaseRouterTest):
|
||||
|
||||
required_extensions = ['router']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(RoutersTest, cls).resource_setup()
|
||||
cls.tenant_cidr = (
|
||||
config.safe_get_config_value('network', 'project_network_cidr')
|
||||
if cls._ip_version == 4 else
|
||||
config.safe_get_config_value('network', 'project_network_v6_cidr'))
|
||||
|
||||
@decorators.idempotent_id('c72c1c0c-2193-4aca-eeee-b1442640eeee')
|
||||
@tutils.requires_ext(extension="standard-attr-description",
|
||||
service="network")
|
||||
def test_create_update_router_description(self):
|
||||
body = self.create_router(description='d1', router_name='test')
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.show_router(body['id'])['router']
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.update_router(body['id'], description='d2')
|
||||
self.assertEqual('d2', body['router']['description'])
|
||||
body = self.client.show_router(body['router']['id'])['router']
|
||||
self.assertEqual('d2', body['description'])
|
||||
|
||||
@decorators.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
|
||||
@tutils.requires_ext(extension='ext-gw-mode', service='network')
|
||||
def test_create_router_with_default_snat_value(self):
|
||||
# Create a router with default snat rule
|
||||
name = data_utils.rand_name('router')
|
||||
router = self._create_router(
|
||||
name, external_network_id=CONF.network.public_network_id)
|
||||
self._verify_router_gateway(
|
||||
router['id'], {'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': True})
|
||||
|
||||
@decorators.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
|
||||
@tutils.requires_ext(extension='ext-gw-mode', service='network')
|
||||
def test_create_router_with_snat_explicit(self):
|
||||
name = data_utils.rand_name('snat-router')
|
||||
# Create a router enabling snat attributes
|
||||
enable_snat_states = [False, True]
|
||||
for enable_snat in enable_snat_states:
|
||||
external_gateway_info = {
|
||||
'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': enable_snat}
|
||||
create_body = self.admin_client.create_router(
|
||||
name, external_gateway_info=external_gateway_info)
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
create_body['router']['id'])
|
||||
# Verify snat attributes after router creation
|
||||
self._verify_router_gateway(create_body['router']['id'],
|
||||
exp_ext_gw_info=external_gateway_info)
|
||||
|
||||
def _verify_router_gateway(self, router_id, exp_ext_gw_info=None):
|
||||
show_body = self.admin_client.show_router(router_id)
|
||||
actual_ext_gw_info = show_body['router']['external_gateway_info']
|
||||
if exp_ext_gw_info is None:
|
||||
self.assertIsNone(actual_ext_gw_info)
|
||||
return
|
||||
# Verify only keys passed in exp_ext_gw_info
|
||||
for k, v in exp_ext_gw_info.items():
|
||||
self.assertEqual(v, actual_ext_gw_info[k])
|
||||
|
||||
def _verify_gateway_port(self, router_id):
|
||||
list_body = self.admin_client.list_ports(
|
||||
network_id=CONF.network.public_network_id,
|
||||
device_id=router_id)
|
||||
self.assertEqual(len(list_body['ports']), 1)
|
||||
gw_port = list_body['ports'][0]
|
||||
fixed_ips = gw_port['fixed_ips']
|
||||
self.assertGreaterEqual(len(fixed_ips), 1)
|
||||
public_net_body = self.admin_client.show_network(
|
||||
CONF.network.public_network_id)
|
||||
public_subnet_ids = public_net_body['network']['subnets']
|
||||
for fixed_ip in fixed_ips:
|
||||
self.assertIn(fixed_ip['subnet_id'],
|
||||
public_subnet_ids)
|
||||
|
||||
@decorators.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
|
||||
@tutils.requires_ext(extension='ext-gw-mode', service='network')
|
||||
def test_update_router_set_gateway_with_snat_explicit(self):
|
||||
router = self._create_router(data_utils.rand_name('router'))
|
||||
self.admin_client.update_router_with_snat_gw_info(
|
||||
router['id'],
|
||||
external_gateway_info={
|
||||
'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': True})
|
||||
self._verify_router_gateway(
|
||||
router['id'],
|
||||
{'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': True})
|
||||
self._verify_gateway_port(router['id'])
|
||||
|
||||
@decorators.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
|
||||
@tutils.requires_ext(extension='ext-gw-mode', service='network')
|
||||
def test_update_router_set_gateway_without_snat(self):
|
||||
router = self._create_router(data_utils.rand_name('router'))
|
||||
self.admin_client.update_router_with_snat_gw_info(
|
||||
router['id'],
|
||||
external_gateway_info={
|
||||
'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': False})
|
||||
self._verify_router_gateway(
|
||||
router['id'],
|
||||
{'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': False})
|
||||
self._verify_gateway_port(router['id'])
|
||||
|
||||
@decorators.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
|
||||
@tutils.requires_ext(extension='ext-gw-mode', service='network')
|
||||
def test_update_router_reset_gateway_without_snat(self):
|
||||
router = self._create_router(
|
||||
data_utils.rand_name('router'),
|
||||
external_network_id=CONF.network.public_network_id)
|
||||
self.admin_client.update_router_with_snat_gw_info(
|
||||
router['id'],
|
||||
external_gateway_info={
|
||||
'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': False})
|
||||
self._verify_router_gateway(
|
||||
router['id'],
|
||||
{'network_id': CONF.network.public_network_id,
|
||||
'enable_snat': False})
|
||||
self._verify_gateway_port(router['id'])
|
||||
|
||||
@decorators.idempotent_id('db3093b1-93b6-4893-be83-c4716c251b3e')
|
||||
def test_router_interface_status(self):
|
||||
network = self.create_network()
|
||||
subnet = self.create_subnet(network)
|
||||
# Add router interface with subnet id
|
||||
router = self._create_router(data_utils.rand_name('router'), True)
|
||||
intf = self.create_router_interface(router['id'], subnet['id'])
|
||||
status_active = lambda: self.client.show_port(
|
||||
intf['port_id'])['port']['status'] == 'ACTIVE'
|
||||
utils.wait_until_true(status_active, exception=AssertionError)
|
||||
|
||||
@decorators.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
|
||||
@tutils.requires_ext(extension='extraroute', service='network')
|
||||
def test_update_extra_route(self):
|
||||
self.network = self.create_network()
|
||||
self.name = self.network['name']
|
||||
self.subnet = self.create_subnet(self.network)
|
||||
# Add router interface with subnet id
|
||||
self.router = self._create_router(
|
||||
data_utils.rand_name('router-'), True)
|
||||
self.create_router_interface(self.router['id'], self.subnet['id'])
|
||||
self.addCleanup(
|
||||
self._delete_extra_routes,
|
||||
self.router['id'])
|
||||
# Update router extra route, second ip of the range is
|
||||
# used as next hop
|
||||
cidr = netaddr.IPNetwork(self.subnet['cidr'])
|
||||
next_hop = str(cidr[2])
|
||||
destination = str(self.subnet['cidr'])
|
||||
extra_route = self.client.update_extra_routes(self.router['id'],
|
||||
next_hop, destination)
|
||||
self.assertEqual(1, len(extra_route['router']['routes']))
|
||||
self.assertEqual(destination,
|
||||
extra_route['router']['routes'][0]['destination'])
|
||||
self.assertEqual(next_hop,
|
||||
extra_route['router']['routes'][0]['nexthop'])
|
||||
show_body = self.client.show_router(self.router['id'])
|
||||
self.assertEqual(destination,
|
||||
show_body['router']['routes'][0]['destination'])
|
||||
self.assertEqual(next_hop,
|
||||
show_body['router']['routes'][0]['nexthop'])
|
||||
|
||||
def _delete_extra_routes(self, router_id):
|
||||
self.client.delete_extra_routes(router_id)
|
||||
|
||||
@decorators.idempotent_id('01f185d1-d1a6-4cf9-abf7-e0e1384c169c')
|
||||
def test_network_attached_with_two_routers(self):
|
||||
network = self.create_network(data_utils.rand_name('network1'))
|
||||
self.create_subnet(network)
|
||||
port1 = self.create_port(network)
|
||||
port2 = self.create_port(network)
|
||||
router1 = self._create_router(data_utils.rand_name('router1'))
|
||||
router2 = self._create_router(data_utils.rand_name('router2'))
|
||||
self.client.add_router_interface_with_port_id(
|
||||
router1['id'], port1['id'])
|
||||
self.client.add_router_interface_with_port_id(
|
||||
router2['id'], port2['id'])
|
||||
self.addCleanup(self.client.remove_router_interface_with_port_id,
|
||||
router1['id'], port1['id'])
|
||||
self.addCleanup(self.client.remove_router_interface_with_port_id,
|
||||
router2['id'], port2['id'])
|
||||
body = self.client.show_port(port1['id'])
|
||||
port_show1 = body['port']
|
||||
body = self.client.show_port(port2['id'])
|
||||
port_show2 = body['port']
|
||||
self.assertEqual(port_show1['network_id'], network['id'])
|
||||
self.assertEqual(port_show2['network_id'], network['id'])
|
||||
self.assertEqual(port_show1['device_id'], router1['id'])
|
||||
self.assertEqual(port_show2['device_id'], router2['id'])
|
||||
|
||||
|
||||
class RoutersIpV6Test(RoutersTest):
|
||||
_ip_version = 6
|
||||
|
||||
|
||||
class DvrRoutersTest(base_routers.BaseRouterTest):
|
||||
|
||||
required_extensions = ['dvr']
|
||||
|
||||
@decorators.idempotent_id('141297aa-3424-455d-aa8d-f2d95731e00a')
|
||||
def test_create_distributed_router(self):
|
||||
name = data_utils.rand_name('router')
|
||||
create_body = self.admin_client.create_router(
|
||||
name, distributed=True)
|
||||
self.addCleanup(self._delete_router,
|
||||
create_body['router']['id'],
|
||||
self.admin_client)
|
||||
self.assertTrue(create_body['router']['distributed'])
|
||||
|
||||
@decorators.idempotent_id('644d7a4a-01a1-4b68-bb8d-0c0042cb1729')
|
||||
def test_convert_centralized_router(self):
|
||||
router_args = {'tenant_id': self.client.tenant_id,
|
||||
'distributed': False, 'ha': False}
|
||||
router = self.admin_client.create_router(
|
||||
data_utils.rand_name('router'), admin_state_up=False,
|
||||
**router_args)['router']
|
||||
self.addCleanup(self.admin_client.delete_router,
|
||||
router['id'])
|
||||
self.assertFalse(router['distributed'])
|
||||
self.assertFalse(router['ha'])
|
||||
update_body = self.admin_client.update_router(router['id'],
|
||||
distributed=True)
|
||||
self.assertTrue(update_body['router']['distributed'])
|
||||
show_body = self.admin_client.show_router(router['id'])
|
||||
self.assertTrue(show_body['router']['distributed'])
|
||||
show_body = self.client.show_router(router['id'])
|
||||
self.assertNotIn('distributed', show_body['router'])
|
||||
self.assertNotIn('ha', show_body['router'])
|
||||
|
||||
|
||||
class HaRoutersTest(base_routers.BaseRouterTest):
|
||||
|
||||
required_extensions = ['l3-ha']
|
||||
|
||||
@decorators.idempotent_id('77db8eae-3aa3-4e61-bf2a-e739ce042e53')
|
||||
def test_convert_legacy_router(self):
|
||||
router = self._create_router(data_utils.rand_name('router'))
|
||||
self.assertNotIn('ha', router)
|
||||
update_body = self.admin_client.update_router(router['id'],
|
||||
ha=True)
|
||||
self.assertTrue(update_body['router']['ha'])
|
||||
show_body = self.admin_client.show_router(router['id'])
|
||||
self.assertTrue(show_body['router']['ha'])
|
||||
show_body = self.client.show_router(router['id'])
|
||||
self.assertNotIn('ha', show_body['router'])
|
||||
|
||||
|
||||
class RoutersSearchCriteriaTest(base.BaseSearchCriteriaTest):
|
||||
|
||||
required_extensions = ['router']
|
||||
resource = 'router'
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(RoutersSearchCriteriaTest, cls).resource_setup()
|
||||
for name in cls.resource_names:
|
||||
cls.create_router(router_name=name)
|
||||
|
||||
@decorators.idempotent_id('03a69efb-90a7-435b-bb5c-3add3612085a')
|
||||
def test_list_sorts_asc(self):
|
||||
self._test_list_sorts_asc()
|
||||
|
||||
@decorators.idempotent_id('95913d30-ff41-4b17-9f44-5258c651e78c')
|
||||
def test_list_sorts_desc(self):
|
||||
self._test_list_sorts_desc()
|
||||
|
||||
@decorators.idempotent_id('7f7d40b1-e165-4817-8dc5-02f8e2f0dff3')
|
||||
def test_list_pagination(self):
|
||||
self._test_list_pagination()
|
||||
|
||||
@decorators.idempotent_id('a5b83e83-3d98-45bb-a2c7-0ee179ffd42c')
|
||||
def test_list_pagination_with_marker(self):
|
||||
self._test_list_pagination_with_marker()
|
||||
|
||||
@decorators.idempotent_id('40804af8-c25d-45f8-b8a8-b4c70345215d')
|
||||
def test_list_pagination_with_href_links(self):
|
||||
self._test_list_pagination_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('77b9676c-d3cb-43af-a0e8-a5b8c6099e70')
|
||||
def test_list_pagination_page_reverse_asc(self):
|
||||
self._test_list_pagination_page_reverse_asc()
|
||||
|
||||
@decorators.idempotent_id('3133a2c5-1bb9-4fc7-833e-cf9a1d160255')
|
||||
def test_list_pagination_page_reverse_desc(self):
|
||||
self._test_list_pagination_page_reverse_desc()
|
||||
|
||||
@decorators.idempotent_id('8252e2f0-b3da-4738-8e25-f6f8d878a2da')
|
||||
def test_list_pagination_page_reverse_with_href_links(self):
|
||||
self._test_list_pagination_page_reverse_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('fb102124-20f8-4cb3-8c81-f16f5e41d192')
|
||||
def test_list_no_pagination_limit_0(self):
|
||||
self._test_list_no_pagination_limit_0()
|
@ -1,92 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import base_routers as base
|
||||
|
||||
|
||||
class RoutersNegativeTestBase(base.BaseRouterTest):
|
||||
|
||||
required_extensions = ['router']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(RoutersNegativeTestBase, cls).resource_setup()
|
||||
cls.router = cls.create_router(data_utils.rand_name('router'))
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
|
||||
|
||||
class RoutersNegativeTest(RoutersNegativeTestBase):
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('e3e751af-15a2-49cc-b214-a7154579e94f')
|
||||
def test_delete_router_in_use(self):
|
||||
# This port is deleted after a test by remove_router_interface.
|
||||
port = self.client.create_port(network_id=self.network['id'])
|
||||
self.client.add_router_interface_with_port_id(
|
||||
self.router['id'], port['port']['id'])
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
self.client.delete_router(self.router['id'])
|
||||
|
||||
|
||||
class RoutersNegativePolicyTest(RoutersNegativeTestBase):
|
||||
|
||||
credentials = ['admin', 'primary', 'alt']
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('159f576d-a423-46b5-b501-622694c02f6b')
|
||||
def test_add_interface_wrong_tenant(self):
|
||||
client2 = self.os_alt.network_client
|
||||
network = client2.create_network()['network']
|
||||
self.addCleanup(client2.delete_network, network['id'])
|
||||
subnet = self.create_subnet(network, client=client2)
|
||||
# This port is deleted after a test by remove_router_interface.
|
||||
port = client2.create_port(network_id=network['id'])['port']
|
||||
self.addCleanup(client2.delete_port, port['id'])
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
client2.add_router_interface_with_port_id(
|
||||
self.router['id'], port['id'])
|
||||
with testtools.ExpectedException(lib_exc.NotFound):
|
||||
client2.add_router_interface_with_subnet_id(
|
||||
self.router['id'], subnet['id'])
|
||||
|
||||
|
||||
class DvrRoutersNegativeTest(RoutersNegativeTestBase):
|
||||
|
||||
required_extensions = ['dvr']
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('4990b055-8fc7-48ab-bba7-aa28beaad0b9')
|
||||
def test_router_create_tenant_distributed_returns_forbidden(self):
|
||||
with testtools.ExpectedException(lib_exc.Forbidden):
|
||||
self.create_router(
|
||||
data_utils.rand_name('router'), distributed=True)
|
||||
|
||||
|
||||
class HaRoutersNegativeTest(RoutersNegativeTestBase):
|
||||
|
||||
required_extensions = ['l3-ha']
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('821b85b9-9c51-40f3-831f-bf223a7e0084')
|
||||
def test_router_create_tenant_ha_returns_forbidden(self):
|
||||
with testtools.ExpectedException(lib_exc.Forbidden):
|
||||
self.create_router(
|
||||
data_utils.rand_name('router'), ha=True)
|
@ -1,124 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib import constants
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base_security_groups as base
|
||||
|
||||
|
||||
class SecGroupTest(base.BaseSecGroupTest):
|
||||
|
||||
required_extensions = ['security-group']
|
||||
|
||||
@decorators.idempotent_id('bfd128e5-3c92-44b6-9d66-7fe29d22c802')
|
||||
def test_create_list_update_show_delete_security_group(self):
|
||||
group_create_body, name = self._create_security_group()
|
||||
|
||||
# List security groups and verify if created group is there in response
|
||||
list_body = self.client.list_security_groups()
|
||||
secgroup_list = list()
|
||||
for secgroup in list_body['security_groups']:
|
||||
secgroup_list.append(secgroup['id'])
|
||||
self.assertIn(group_create_body['security_group']['id'], secgroup_list)
|
||||
# Update the security group
|
||||
new_name = data_utils.rand_name('security')
|
||||
new_description = data_utils.rand_name('security-description')
|
||||
update_body = self.client.update_security_group(
|
||||
group_create_body['security_group']['id'],
|
||||
name=new_name,
|
||||
description=new_description)
|
||||
# Verify if security group is updated
|
||||
self.assertEqual(update_body['security_group']['name'], new_name)
|
||||
self.assertEqual(update_body['security_group']['description'],
|
||||
new_description)
|
||||
# Show details of the updated security group
|
||||
show_body = self.client.show_security_group(
|
||||
group_create_body['security_group']['id'])
|
||||
self.assertEqual(show_body['security_group']['name'], new_name)
|
||||
self.assertEqual(show_body['security_group']['description'],
|
||||
new_description)
|
||||
|
||||
@decorators.idempotent_id('7c0ecb10-b2db-11e6-9b14-000c29248b0d')
|
||||
def test_create_bulk_sec_groups(self):
|
||||
# Creates 2 sec-groups in one request
|
||||
sec_nm = [data_utils.rand_name('secgroup'),
|
||||
data_utils.rand_name('secgroup')]
|
||||
body = self.client.create_bulk_security_groups(sec_nm)
|
||||
created_sec_grps = body['security_groups']
|
||||
self.assertEqual(2, len(created_sec_grps))
|
||||
for secgrp in created_sec_grps:
|
||||
self.addCleanup(self.client.delete_security_group,
|
||||
secgrp['id'])
|
||||
self.assertIn(secgrp['name'], sec_nm)
|
||||
self.assertIsNotNone(secgrp['id'])
|
||||
|
||||
|
||||
class SecGroupProtocolTest(base.BaseSecGroupTest):
|
||||
|
||||
@decorators.idempotent_id('282e3681-aa6e-42a7-b05c-c341aa1e3cdf')
|
||||
def test_create_show_delete_security_group_rule_names(self):
|
||||
group_create_body, _ = self._create_security_group()
|
||||
for protocol in base.V4_PROTOCOL_NAMES:
|
||||
self._test_create_show_delete_security_group_rule(
|
||||
security_group_id=group_create_body['security_group']['id'],
|
||||
protocol=protocol,
|
||||
direction=constants.INGRESS_DIRECTION,
|
||||
ethertype=self.ethertype)
|
||||
|
||||
@decorators.idempotent_id('66e47f1f-20b6-4417-8839-3cc671c7afa3')
|
||||
def test_create_show_delete_security_group_rule_integers(self):
|
||||
group_create_body, _ = self._create_security_group()
|
||||
for protocol in base.V4_PROTOCOL_INTS:
|
||||
self._test_create_show_delete_security_group_rule(
|
||||
security_group_id=group_create_body['security_group']['id'],
|
||||
protocol=protocol,
|
||||
direction=constants.INGRESS_DIRECTION,
|
||||
ethertype=self.ethertype)
|
||||
|
||||
|
||||
class SecGroupProtocolIPv6Test(SecGroupProtocolTest):
|
||||
_ip_version = constants.IP_VERSION_6
|
||||
|
||||
@decorators.idempotent_id('1f7cc9f5-e0d5-487c-8384-3d74060ab530')
|
||||
def test_create_security_group_rule_with_ipv6_protocol_names(self):
|
||||
group_create_body, _ = self._create_security_group()
|
||||
for protocol in base.V6_PROTOCOL_NAMES:
|
||||
self._test_create_show_delete_security_group_rule(
|
||||
security_group_id=group_create_body['security_group']['id'],
|
||||
protocol=protocol,
|
||||
direction=constants.INGRESS_DIRECTION,
|
||||
ethertype=self.ethertype)
|
||||
|
||||
@decorators.idempotent_id('c7d17b41-3b4e-4add-bb3b-6af59baaaffa')
|
||||
def test_create_security_group_rule_with_ipv6_protocol_legacy_names(self):
|
||||
group_create_body, _ = self._create_security_group()
|
||||
for protocol in base.V6_PROTOCOL_LEGACY:
|
||||
self._test_create_show_delete_security_group_rule(
|
||||
security_group_id=group_create_body['security_group']['id'],
|
||||
protocol=protocol,
|
||||
direction=constants.INGRESS_DIRECTION,
|
||||
ethertype=self.ethertype)
|
||||
|
||||
@decorators.idempotent_id('bcfce0b7-bc96-40ae-9b08-3f6774ee0260')
|
||||
def test_create_security_group_rule_with_ipv6_protocol_integers(self):
|
||||
group_create_body, _ = self._create_security_group()
|
||||
for protocol in base.V6_PROTOCOL_INTS:
|
||||
self._test_create_show_delete_security_group_rule(
|
||||
security_group_id=group_create_body['security_group']['id'],
|
||||
protocol=protocol,
|
||||
direction=constants.INGRESS_DIRECTION,
|
||||
ethertype=self.ethertype)
|
@ -1,118 +0,0 @@
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib import constants
|
||||
from neutron_lib.db import constants as db_const
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import base_security_groups as base
|
||||
|
||||
LONG_NAME_NG = 'x' * (db_const.NAME_FIELD_SIZE + 1)
|
||||
|
||||
|
||||
class NegativeSecGroupTest(base.BaseSecGroupTest):
|
||||
|
||||
required_extensions = ['security-group']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(NegativeSecGroupTest, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('594edfa8-9a5b-438e-9344-49aece337d49')
|
||||
def test_create_security_group_with_too_long_name(self):
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.create_security_group,
|
||||
name=LONG_NAME_NG)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('b6b79838-7430-4d3f-8e07-51dfb61802c2')
|
||||
def test_create_security_group_with_boolean_type_name(self):
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.create_security_group,
|
||||
name=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('55100aa8-b24f-333c-0bef-64eefd85f15c')
|
||||
def test_update_default_security_group_name(self):
|
||||
sg_list = self.client.list_security_groups(name='default')
|
||||
sg = sg_list['security_groups'][0]
|
||||
self.assertRaises(lib_exc.Conflict, self.client.update_security_group,
|
||||
sg['id'], name='test')
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('c8510dd8-c3a8-4df9-ae44-24354db50960')
|
||||
def test_update_security_group_with_too_long_name(self):
|
||||
sg_list = self.client.list_security_groups(name='default')
|
||||
sg = sg_list['security_groups'][0]
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.update_security_group,
|
||||
sg['id'], name=LONG_NAME_NG)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('d9a14917-f66f-4eca-ab72-018563917f1b')
|
||||
def test_update_security_group_with_boolean_type_name(self):
|
||||
sg_list = self.client.list_security_groups(name='default')
|
||||
sg = sg_list['security_groups'][0]
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.update_security_group,
|
||||
sg['id'], name=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('3200b1a8-d73b-48e9-b03f-e891a4abe2d3')
|
||||
def test_delete_in_use_sec_group(self):
|
||||
sgroup = self.os_primary.network_client.create_security_group(
|
||||
name='sgroup')
|
||||
self.security_groups.append(sgroup['security_group'])
|
||||
port = self.client.create_port(
|
||||
network_id=self.network['id'],
|
||||
security_groups=[sgroup['security_group']['id']])
|
||||
self.ports.append(port['port'])
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.os_primary.network_client.delete_security_group,
|
||||
security_group_id=sgroup['security_group']['id'])
|
||||
|
||||
|
||||
class NegativeSecGroupIPv6Test(NegativeSecGroupTest):
|
||||
_ip_version = constants.IP_VERSION_6
|
||||
|
||||
|
||||
class NegativeSecGroupProtocolTest(base.BaseSecGroupTest):
|
||||
|
||||
def _test_create_security_group_rule_with_bad_protocols(self, protocols):
|
||||
group_create_body, _ = self._create_security_group()
|
||||
|
||||
# bad protocols can include v6 protocols because self.ethertype is v4
|
||||
for protocol in protocols:
|
||||
self.assertRaises(
|
||||
lib_exc.BadRequest,
|
||||
self.client.create_security_group_rule,
|
||||
security_group_id=group_create_body['security_group']['id'],
|
||||
protocol=protocol, direction=constants.INGRESS_DIRECTION,
|
||||
ethertype=self.ethertype)
|
||||
|
||||
@decorators.attr(type=['negative'])
|
||||
@decorators.idempotent_id('cccbb0f3-c273-43ed-b3fc-1efc48833810')
|
||||
def test_create_security_group_rule_with_ipv6_protocol_names(self):
|
||||
self._test_create_security_group_rule_with_bad_protocols(
|
||||
base.V6_PROTOCOL_NAMES)
|
||||
|
||||
@decorators.attr(type=['negative'])
|
||||
@decorators.idempotent_id('8aa636bd-7060-4fdf-b722-cdae28e2f1ef')
|
||||
def test_create_security_group_rule_with_ipv6_protocol_integers(self):
|
||||
self._test_create_security_group_rule_with_bad_protocols(
|
||||
base.V6_PROTOCOL_INTS)
|
@ -1,25 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class ServiceTypeManagementTest(base.BaseNetworkTest):
|
||||
|
||||
required_extensions = ['service-type']
|
||||
|
||||
@decorators.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
|
||||
def test_service_provider_list(self):
|
||||
body = self.client.list_service_providers()
|
||||
self.assertIsInstance(body['service_providers'], list)
|
@ -1,419 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
SUBNETPOOL_NAME = 'smoke-subnetpool'
|
||||
SUBNET_NAME = 'smoke-subnet'
|
||||
|
||||
|
||||
class SubnetPoolsTestBase(base.BaseAdminNetworkTest):
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(SubnetPoolsTestBase, cls).resource_setup()
|
||||
min_prefixlen = '29'
|
||||
prefixes = [u'10.11.12.0/24']
|
||||
cls._subnetpool_data = {'prefixes': prefixes,
|
||||
'min_prefixlen': min_prefixlen}
|
||||
|
||||
@classmethod
|
||||
def _create_subnetpool(cls, is_admin=False, **kwargs):
|
||||
if 'name' not in kwargs:
|
||||
name = data_utils.rand_name(SUBNETPOOL_NAME)
|
||||
else:
|
||||
name = kwargs.pop('name')
|
||||
|
||||
if 'prefixes' not in kwargs:
|
||||
kwargs['prefixes'] = cls._subnetpool_data['prefixes']
|
||||
|
||||
if 'min_prefixlen' not in kwargs:
|
||||
kwargs['min_prefixlen'] = cls._subnetpool_data['min_prefixlen']
|
||||
|
||||
return cls.create_subnetpool(name=name, is_admin=is_admin, **kwargs)
|
||||
|
||||
|
||||
class SubnetPoolsTest(SubnetPoolsTestBase):
|
||||
|
||||
min_prefixlen = '28'
|
||||
max_prefixlen = '31'
|
||||
_ip_version = 4
|
||||
subnet_cidr = u'10.11.12.0/31'
|
||||
new_prefix = u'10.11.15.0/24'
|
||||
larger_prefix = u'10.11.0.0/16'
|
||||
|
||||
"""
|
||||
Tests the following operations in the Neutron API using the REST client for
|
||||
Neutron:
|
||||
|
||||
create a subnetpool for a tenant
|
||||
list tenant's subnetpools
|
||||
show a tenant subnetpool details
|
||||
subnetpool update
|
||||
delete a subnetpool
|
||||
|
||||
All subnetpool tests are run once with ipv4 and once with ipv6.
|
||||
|
||||
v2.0 of the Neutron API is assumed.
|
||||
|
||||
"""
|
||||
|
||||
def _new_subnetpool_attributes(self):
|
||||
new_name = data_utils.rand_name(SUBNETPOOL_NAME)
|
||||
return {'name': new_name, 'min_prefixlen': self.min_prefixlen,
|
||||
'max_prefixlen': self.max_prefixlen}
|
||||
|
||||
def _check_equality_updated_subnetpool(self, expected_values,
|
||||
updated_pool):
|
||||
self.assertEqual(expected_values['name'],
|
||||
updated_pool['name'])
|
||||
self.assertEqual(expected_values['min_prefixlen'],
|
||||
updated_pool['min_prefixlen'])
|
||||
self.assertEqual(expected_values['max_prefixlen'],
|
||||
updated_pool['max_prefixlen'])
|
||||
# expected_values may not contains all subnetpool values
|
||||
if 'prefixes' in expected_values:
|
||||
self.assertEqual(expected_values['prefixes'],
|
||||
updated_pool['prefixes'])
|
||||
|
||||
@decorators.idempotent_id('6e1781ec-b45b-4042-aebe-f485c022996e')
|
||||
def test_create_list_subnetpool(self):
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
body = self.client.list_subnetpools()
|
||||
subnetpools = body['subnetpools']
|
||||
self.assertIn(created_subnetpool['id'],
|
||||
[sp['id'] for sp in subnetpools],
|
||||
"Created subnetpool id should be in the list")
|
||||
self.assertIn(created_subnetpool['name'],
|
||||
[sp['name'] for sp in subnetpools],
|
||||
"Created subnetpool name should be in the list")
|
||||
|
||||
@decorators.idempotent_id('c72c1c0c-2193-4aca-ddd4-b1442640bbbb')
|
||||
@utils.requires_ext(extension="standard-attr-description",
|
||||
service="network")
|
||||
def test_create_update_subnetpool_description(self):
|
||||
body = self._create_subnetpool(description='d1')
|
||||
self.assertEqual('d1', body['description'])
|
||||
sub_id = body['id']
|
||||
subnet_pools = [x for x in
|
||||
self.client.list_subnetpools()['subnetpools'] if x['id'] == sub_id]
|
||||
body = subnet_pools[0]
|
||||
self.assertEqual('d1', body['description'])
|
||||
body = self.client.update_subnetpool(sub_id, description='d2')
|
||||
self.assertEqual('d2', body['subnetpool']['description'])
|
||||
subnet_pools = [x for x in
|
||||
self.client.list_subnetpools()['subnetpools'] if x['id'] == sub_id]
|
||||
body = subnet_pools[0]
|
||||
self.assertEqual('d2', body['description'])
|
||||
|
||||
@decorators.idempotent_id('741d08c2-1e3f-42be-99c7-0ea93c5b728c')
|
||||
def test_get_subnetpool(self):
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
prefixlen = self._subnetpool_data['min_prefixlen']
|
||||
body = self.client.show_subnetpool(created_subnetpool['id'])
|
||||
subnetpool = body['subnetpool']
|
||||
self.assertEqual(created_subnetpool['name'], subnetpool['name'])
|
||||
self.assertEqual(created_subnetpool['id'], subnetpool['id'])
|
||||
self.assertEqual(prefixlen, subnetpool['min_prefixlen'])
|
||||
self.assertEqual(prefixlen, subnetpool['default_prefixlen'])
|
||||
self.assertFalse(subnetpool['shared'])
|
||||
|
||||
@decorators.idempotent_id('5bf9f1e2-efc8-4195-acf3-d12b2bd68dd3')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_show_subnetpool_has_project_id(self):
|
||||
subnetpool = self._create_subnetpool()
|
||||
body = self.client.show_subnetpool(subnetpool['id'])
|
||||
show_subnetpool = body['subnetpool']
|
||||
self.assertIn('project_id', show_subnetpool)
|
||||
self.assertIn('tenant_id', show_subnetpool)
|
||||
self.assertEqual(self.client.tenant_id, show_subnetpool['project_id'])
|
||||
self.assertEqual(self.client.tenant_id, show_subnetpool['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('764f1b93-1c4a-4513-9e7b-6c2fc5e9270c')
|
||||
def test_tenant_update_subnetpool(self):
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
pool_id = created_subnetpool['id']
|
||||
subnetpool_data = self._new_subnetpool_attributes()
|
||||
self.client.update_subnetpool(created_subnetpool['id'],
|
||||
**subnetpool_data)
|
||||
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
subnetpool = body['subnetpool']
|
||||
self._check_equality_updated_subnetpool(subnetpool_data,
|
||||
subnetpool)
|
||||
self.assertFalse(subnetpool['shared'])
|
||||
|
||||
@decorators.idempotent_id('4b496082-c992-4319-90be-d4a7ce646290')
|
||||
def test_update_subnetpool_prefixes_append(self):
|
||||
# We can append new prefixes to subnetpool
|
||||
create_subnetpool = self._create_subnetpool()
|
||||
pool_id = create_subnetpool['id']
|
||||
old_prefixes = self._subnetpool_data['prefixes']
|
||||
new_prefixes = old_prefixes[:]
|
||||
new_prefixes.append(self.new_prefix)
|
||||
subnetpool_data = {'prefixes': new_prefixes}
|
||||
self.client.update_subnetpool(pool_id, **subnetpool_data)
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
prefixes = body['subnetpool']['prefixes']
|
||||
self.assertIn(self.new_prefix, prefixes)
|
||||
self.assertIn(old_prefixes[0], prefixes)
|
||||
|
||||
@decorators.idempotent_id('2cae5d6a-9d32-42d8-8067-f13970ae13bb')
|
||||
def test_update_subnetpool_prefixes_extend(self):
|
||||
# We can extend current subnetpool prefixes
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
pool_id = created_subnetpool['id']
|
||||
old_prefixes = self._subnetpool_data['prefixes']
|
||||
subnetpool_data = {'prefixes': [self.larger_prefix]}
|
||||
self.client.update_subnetpool(pool_id, **subnetpool_data)
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
prefixes = body['subnetpool']['prefixes']
|
||||
self.assertIn(self.larger_prefix, prefixes)
|
||||
self.assertNotIn(old_prefixes[0], prefixes)
|
||||
|
||||
@decorators.idempotent_id('d70c6c35-913b-4f24-909f-14cd0d29b2d2')
|
||||
def test_admin_create_shared_subnetpool(self):
|
||||
created_subnetpool = self._create_subnetpool(is_admin=True,
|
||||
shared=True)
|
||||
pool_id = created_subnetpool['id']
|
||||
# Shared subnetpool can be retrieved by tenant user.
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
subnetpool = body['subnetpool']
|
||||
self.assertEqual(created_subnetpool['name'], subnetpool['name'])
|
||||
self.assertTrue(subnetpool['shared'])
|
||||
|
||||
def _create_subnet_from_pool(self, subnet_values=None, pool_values=None):
|
||||
if pool_values is None:
|
||||
pool_values = {}
|
||||
|
||||
created_subnetpool = self._create_subnetpool(**pool_values)
|
||||
pool_id = created_subnetpool['id']
|
||||
subnet_name = data_utils.rand_name(SUBNETPOOL_NAME)
|
||||
network = self.create_network()
|
||||
subnet_kwargs = {'name': subnet_name,
|
||||
'subnetpool_id': pool_id}
|
||||
if subnet_values:
|
||||
subnet_kwargs.update(subnet_values)
|
||||
# not creating the subnet using the base.create_subnet because
|
||||
# that function needs to be enhanced to support subnet_create when
|
||||
# prefixlen and subnetpool_id is specified.
|
||||
body = self.client.create_subnet(
|
||||
network_id=network['id'],
|
||||
ip_version=self._ip_version,
|
||||
**subnet_kwargs)
|
||||
subnet = body['subnet']
|
||||
return pool_id, subnet
|
||||
|
||||
@decorators.idempotent_id('1362ed7d-3089-42eb-b3a5-d6cb8398ee77')
|
||||
def test_create_subnet_from_pool_with_prefixlen(self):
|
||||
subnet_values = {"prefixlen": self.max_prefixlen}
|
||||
pool_id, subnet = self._create_subnet_from_pool(
|
||||
subnet_values=subnet_values)
|
||||
cidr = str(subnet['cidr'])
|
||||
self.assertEqual(pool_id, subnet['subnetpool_id'])
|
||||
self.assertTrue(cidr.endswith(str(self.max_prefixlen)))
|
||||
|
||||
@decorators.idempotent_id('86b86189-9789-4582-9c3b-7e2bfe5735ee')
|
||||
def test_create_subnet_from_pool_with_subnet_cidr(self):
|
||||
subnet_values = {"cidr": self.subnet_cidr}
|
||||
pool_id, subnet = self._create_subnet_from_pool(
|
||||
subnet_values=subnet_values)
|
||||
cidr = str(subnet['cidr'])
|
||||
self.assertEqual(pool_id, subnet['subnetpool_id'])
|
||||
self.assertEqual(cidr, self.subnet_cidr)
|
||||
|
||||
@decorators.idempotent_id('83f76e3a-9c40-40c2-a015-b7c5242178d8')
|
||||
def test_create_subnet_from_pool_with_default_prefixlen(self):
|
||||
# If neither cidr nor prefixlen is specified,
|
||||
# subnet will use subnetpool default_prefixlen for cidr.
|
||||
pool_id, subnet = self._create_subnet_from_pool()
|
||||
cidr = str(subnet['cidr'])
|
||||
self.assertEqual(pool_id, subnet['subnetpool_id'])
|
||||
prefixlen = self._subnetpool_data['min_prefixlen']
|
||||
self.assertTrue(cidr.endswith(str(prefixlen)))
|
||||
|
||||
@decorators.idempotent_id('a64af292-ec52-4bde-b654-a6984acaf477')
|
||||
def test_create_subnet_from_pool_with_quota(self):
|
||||
pool_values = {'default_quota': 4}
|
||||
subnet_values = {"prefixlen": self.max_prefixlen}
|
||||
pool_id, subnet = self._create_subnet_from_pool(
|
||||
subnet_values=subnet_values, pool_values=pool_values)
|
||||
cidr = str(subnet['cidr'])
|
||||
self.assertEqual(pool_id, subnet['subnetpool_id'])
|
||||
self.assertTrue(cidr.endswith(str(self.max_prefixlen)))
|
||||
|
||||
@decorators.idempotent_id('49b44c64-1619-4b29-b527-ffc3c3115dc4')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_create_subnetpool_associate_address_scope(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=self._ip_version)
|
||||
created_subnetpool = self._create_subnetpool(
|
||||
address_scope_id=address_scope['id'])
|
||||
body = self.client.show_subnetpool(created_subnetpool['id'])
|
||||
self.assertEqual(address_scope['id'],
|
||||
body['subnetpool']['address_scope_id'])
|
||||
|
||||
@decorators.idempotent_id('910b6393-db24-4f6f-87dc-b36892ad6c8c')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_update_subnetpool_associate_address_scope(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=self._ip_version)
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
pool_id = created_subnetpool['id']
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
self.assertIsNone(body['subnetpool']['address_scope_id'])
|
||||
self.client.update_subnetpool(pool_id,
|
||||
address_scope_id=address_scope['id'])
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
self.assertEqual(address_scope['id'],
|
||||
body['subnetpool']['address_scope_id'])
|
||||
|
||||
@decorators.idempotent_id('18302e80-46a3-4563-82ac-ccd1dd57f652')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_update_subnetpool_associate_another_address_scope(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=self._ip_version)
|
||||
another_address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=self._ip_version)
|
||||
created_subnetpool = self._create_subnetpool(
|
||||
address_scope_id=address_scope['id'])
|
||||
pool_id = created_subnetpool['id']
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
self.assertEqual(address_scope['id'],
|
||||
body['subnetpool']['address_scope_id'])
|
||||
self.client.update_subnetpool(
|
||||
pool_id, address_scope_id=another_address_scope['id'])
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
self.assertEqual(another_address_scope['id'],
|
||||
body['subnetpool']['address_scope_id'])
|
||||
|
||||
@decorators.idempotent_id('f8970048-e41b-42d6-934b-a1297b07706a')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_update_subnetpool_disassociate_address_scope(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=self._ip_version)
|
||||
created_subnetpool = self._create_subnetpool(
|
||||
address_scope_id=address_scope['id'])
|
||||
pool_id = created_subnetpool['id']
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
self.assertEqual(address_scope['id'],
|
||||
body['subnetpool']['address_scope_id'])
|
||||
self.client.update_subnetpool(pool_id,
|
||||
address_scope_id=None)
|
||||
body = self.client.show_subnetpool(pool_id)
|
||||
self.assertIsNone(body['subnetpool']['address_scope_id'])
|
||||
|
||||
@decorators.idempotent_id('4c6963c2-f54c-4347-b288-75d18421c4c4')
|
||||
@utils.requires_ext(extension='default-subnetpools', service='network')
|
||||
def test_tenant_create_non_default_subnetpool(self):
|
||||
"""
|
||||
Test creates a subnetpool, the "is_default" attribute is False.
|
||||
"""
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
self.assertFalse(created_subnetpool['is_default'])
|
||||
|
||||
|
||||
class SubnetPoolsTestV6(SubnetPoolsTest):
|
||||
|
||||
min_prefixlen = '48'
|
||||
max_prefixlen = '64'
|
||||
_ip_version = 6
|
||||
subnet_cidr = '2001:db8:3::/64'
|
||||
new_prefix = u'2001:db8:5::/64'
|
||||
larger_prefix = u'2001:db8::/32'
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(SubnetPoolsTestV6, cls).resource_setup()
|
||||
min_prefixlen = '64'
|
||||
prefixes = [u'2001:db8:3::/48']
|
||||
cls._subnetpool_data = {'min_prefixlen': min_prefixlen,
|
||||
'prefixes': prefixes}
|
||||
|
||||
@decorators.idempotent_id('f62d73dc-cf6f-4879-b94b-dab53982bf3b')
|
||||
def test_create_dual_stack_subnets_from_subnetpools(self):
|
||||
pool_id_v6, subnet_v6 = self._create_subnet_from_pool()
|
||||
pool_values_v4 = {'prefixes': ['192.168.0.0/16'],
|
||||
'min_prefixlen': 21,
|
||||
'max_prefixlen': 32}
|
||||
create_v4_subnetpool = self._create_subnetpool(**pool_values_v4)
|
||||
pool_id_v4 = create_v4_subnetpool['id']
|
||||
subnet_v4 = self.client.create_subnet(
|
||||
network_id=subnet_v6['network_id'], ip_version=4,
|
||||
subnetpool_id=pool_id_v4)['subnet']
|
||||
self.assertEqual(subnet_v4['network_id'], subnet_v6['network_id'])
|
||||
|
||||
|
||||
class SubnetPoolsSearchCriteriaTest(base.BaseSearchCriteriaTest,
|
||||
SubnetPoolsTestBase):
|
||||
|
||||
resource = 'subnetpool'
|
||||
|
||||
list_kwargs = {'shared': False}
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(SubnetPoolsSearchCriteriaTest, cls).resource_setup()
|
||||
for name in cls.resource_names:
|
||||
cls._create_subnetpool(name=name)
|
||||
|
||||
@decorators.idempotent_id('6e3f842e-6bfb-49cb-82d3-0026be4e8e04')
|
||||
def test_list_sorts_asc(self):
|
||||
self._test_list_sorts_asc()
|
||||
|
||||
@decorators.idempotent_id('f336859b-b868-438c-a6fc-2c06374115f2')
|
||||
def test_list_sorts_desc(self):
|
||||
self._test_list_sorts_desc()
|
||||
|
||||
@decorators.idempotent_id('1291fae7-c196-4372-ad59-ce7988518f7b')
|
||||
def test_list_pagination(self):
|
||||
self._test_list_pagination()
|
||||
|
||||
@decorators.idempotent_id('ddb20d14-1952-49b4-a17e-231cc2239a52')
|
||||
def test_list_pagination_with_marker(self):
|
||||
self._test_list_pagination_with_marker()
|
||||
|
||||
@decorators.idempotent_id('b3bd9665-2769-4a43-b50c-31b1add12891')
|
||||
def test_list_pagination_with_href_links(self):
|
||||
self._test_list_pagination_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('1ec1f325-43b0-406e-96ce-20539e38a61d')
|
||||
def test_list_pagination_page_reverse_asc(self):
|
||||
self._test_list_pagination_page_reverse_asc()
|
||||
|
||||
@decorators.idempotent_id('f43a293e-4aaa-48f4-aeaf-de63a676357c')
|
||||
def test_list_pagination_page_reverse_desc(self):
|
||||
self._test_list_pagination_page_reverse_desc()
|
||||
|
||||
@decorators.idempotent_id('73511385-839c-4829-8ac1-b5ad992126c4')
|
||||
def test_list_pagination_page_reverse_with_href_links(self):
|
||||
self._test_list_pagination_page_reverse_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('82a13efc-c18f-4249-b8ec-cec7cf26fbd6')
|
||||
def test_list_no_pagination_limit_0(self):
|
||||
self._test_list_no_pagination_limit_0()
|
||||
|
||||
@decorators.idempotent_id('27feb3f8-40f4-4e50-8cd2-7d0096a98682')
|
||||
def test_list_validation_filters(self):
|
||||
self._test_list_validation_filters()
|
@ -1,288 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from oslo_utils import uuidutils
|
||||
from tempest.common import utils
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from neutron.tests.tempest.api import test_subnetpools
|
||||
|
||||
|
||||
SUBNETPOOL_NAME = 'smoke-subnetpool'
|
||||
|
||||
|
||||
class SubnetPoolsNegativeTestJSON(test_subnetpools.SubnetPoolsTestBase):
|
||||
|
||||
smaller_prefix = u'10.11.12.0/26'
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('0212a042-603a-4f46-99e0-e37de9374d30')
|
||||
def test_get_non_existent_subnetpool(self):
|
||||
non_exist_id = data_utils.rand_name('subnetpool')
|
||||
self.assertRaises(lib_exc.NotFound, self.client.show_subnetpool,
|
||||
non_exist_id)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('dc9336e5-f28f-4658-a0b0-cc79e607007d')
|
||||
def test_tenant_get_not_shared_admin_subnetpool(self):
|
||||
created_subnetpool = self._create_subnetpool(is_admin=True)
|
||||
# None-shared admin subnetpool cannot be retrieved by tenant user.
|
||||
self.assertRaises(lib_exc.NotFound, self.client.show_subnetpool,
|
||||
created_subnetpool['id'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('5e1f2f86-d81a-498c-82ed-32a49f4dc4d3')
|
||||
def test_delete_non_existent_subnetpool(self):
|
||||
non_exist_id = data_utils.rand_name('subnetpool')
|
||||
self.assertRaises(lib_exc.NotFound, self.client.delete_subnetpool,
|
||||
non_exist_id)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('d1143fe2-212b-4e23-a308-d18f7d8d78d6')
|
||||
def test_tenant_create_shared_subnetpool(self):
|
||||
# 'shared' subnetpool can only be created by admin.
|
||||
self.assertRaises(lib_exc.Forbidden, self._create_subnetpool,
|
||||
is_admin=False, shared=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('6ae09d8f-95be-40ed-b1cf-8b850d45bab5')
|
||||
@utils.requires_ext(extension='default-subnetpools', service='network')
|
||||
def test_tenant_create_default_subnetpool(self):
|
||||
# 'default' subnetpool can only be created by admin.
|
||||
self.assertRaises(lib_exc.Forbidden, self._create_subnetpool,
|
||||
is_admin=False, is_default=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('4be84d30-60ca-4bd3-8512-db5b36ce1378')
|
||||
def test_update_non_existent_subnetpool(self):
|
||||
non_exist_id = data_utils.rand_name('subnetpool')
|
||||
self.assertRaises(lib_exc.NotFound, self.client.update_subnetpool,
|
||||
non_exist_id, name='foo-name')
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('e6cd6d87-6173-45dd-bf04-c18ea7ec7537')
|
||||
def test_update_subnetpool_not_modifiable_shared(self):
|
||||
# 'shared' attributes can be specified during creation.
|
||||
# But this attribute is not modifiable after creation.
|
||||
created_subnetpool = self._create_subnetpool(is_admin=True)
|
||||
pool_id = created_subnetpool['id']
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.update_subnetpool,
|
||||
pool_id, shared=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('62f7c43b-bff1-4def-8bb7-4754b840aaad')
|
||||
def test_update_subnetpool_prefixes_shrink(self):
|
||||
# Shrink current subnetpool prefixes is not supported
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
self.assertRaises(lib_exc.BadRequest,
|
||||
self.client.update_subnetpool,
|
||||
created_subnetpool['id'],
|
||||
prefixes=[self.smaller_prefix])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('fc011824-153e-4469-97ad-9808eb88cae1')
|
||||
def test_create_subnet_different_pools_same_network(self):
|
||||
network = self.create_network(network_name='smoke-network')
|
||||
created_subnetpool = self._create_subnetpool(
|
||||
is_admin=True, prefixes=['192.168.0.0/16'])
|
||||
subnet = self.create_subnet(
|
||||
network, cidr=netaddr.IPNetwork('10.10.10.0/24'), ip_version=4,
|
||||
gateway=None, client=self.admin_client)
|
||||
# add the subnet created by admin to the cleanUp because
|
||||
# the base.py doesn't delete it using the admin client
|
||||
self.addCleanup(self.admin_client.delete_subnet, subnet['id'])
|
||||
self.assertRaises(lib_exc.BadRequest, self.create_subnet, network,
|
||||
ip_version=4,
|
||||
subnetpool_id=created_subnetpool['id'],
|
||||
client=self.admin_client)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('9589e332-638e-476e-81bd-013d964aa3cb')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_create_subnetpool_associate_invalid_address_scope(self):
|
||||
self.assertRaises(lib_exc.BadRequest, self._create_subnetpool,
|
||||
address_scope_id='foo-addr-scope')
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('3b6c5942-485d-4964-a560-55608af020b5')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_create_subnetpool_associate_non_exist_address_scope(self):
|
||||
self.assertRaises(lib_exc.NotFound, self._create_subnetpool,
|
||||
address_scope_id=uuidutils.generate_uuid())
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('2dfb4269-8657-485a-a053-b022e911456e')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_create_subnetpool_associate_address_scope_prefix_intersect(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=4)
|
||||
addr_scope_id = address_scope['id']
|
||||
self._create_subnetpool(address_scope_id=addr_scope_id)
|
||||
subnetpool_data = {'name': 'foo-subnetpool',
|
||||
'prefixes': [u'10.11.12.13/24'],
|
||||
'min_prefixlen': '29',
|
||||
'address_scope_id': addr_scope_id}
|
||||
self.assertRaises(lib_exc.Conflict, self._create_subnetpool,
|
||||
**subnetpool_data)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('83a19a13-5384-42e2-b579-43fc69c80914')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_create_sp_associate_address_scope_multiple_prefix_intersect(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=4)
|
||||
addr_scope_id = address_scope['id']
|
||||
self._create_subnetpool(prefixes=[u'20.0.0.0/18', u'30.0.0.0/18'],
|
||||
address_scope_id=addr_scope_id)
|
||||
prefixes = [u'40.0.0.0/18', u'50.0.0.0/18', u'30.0.0.0/12']
|
||||
subnetpool_data = {'name': 'foo-subnetpool',
|
||||
'prefixes': prefixes,
|
||||
'min_prefixlen': '29',
|
||||
'address_scope_id': addr_scope_id}
|
||||
self.assertRaises(lib_exc.Conflict, self._create_subnetpool,
|
||||
**subnetpool_data)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('f06d8e7b-908b-4e94-b570-8156be6a4bf1')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_create_subnetpool_associate_address_scope_of_other_owner(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'), is_admin=True,
|
||||
ip_version=4)
|
||||
self.assertRaises(lib_exc.NotFound, self._create_subnetpool,
|
||||
address_scope_id=address_scope['id'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('3396ec6c-cb80-4ebe-b897-84e904580bdf')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_tenant_create_subnetpool_associate_shared_address_scope(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'), is_admin=True,
|
||||
shared=True, ip_version=4)
|
||||
self.assertRaises(lib_exc.BadRequest, self._create_subnetpool,
|
||||
address_scope_id=address_scope['id'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('6d3d9ad5-32d4-4d63-aa00-8c62f73e2881')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_update_subnetpool_associate_address_scope_of_other_owner(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'), is_admin=True,
|
||||
ip_version=4)
|
||||
address_scope_id = address_scope['id']
|
||||
created_subnetpool = self._create_subnetpool(self.client)
|
||||
self.assertRaises(lib_exc.NotFound, self.client.update_subnetpool,
|
||||
created_subnetpool['id'],
|
||||
address_scope_id=address_scope_id)
|
||||
|
||||
def _test_update_subnetpool_prefix_intersect_helper(
|
||||
self, pool_1_prefixes, pool_2_prefixes, pool_1_updated_prefixes):
|
||||
# create two subnet pools associating to an address scope.
|
||||
# Updating the first subnet pool with the prefix intersecting
|
||||
# with the second one should be a failure
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'), ip_version=4)
|
||||
addr_scope_id = address_scope['id']
|
||||
pool_values = {'address_scope_id': addr_scope_id,
|
||||
'prefixes': pool_1_prefixes}
|
||||
created_subnetpool_1 = self._create_subnetpool(**pool_values)
|
||||
pool_id_1 = created_subnetpool_1['id']
|
||||
pool_values = {'address_scope_id': addr_scope_id,
|
||||
'prefixes': pool_2_prefixes}
|
||||
self._create_subnetpool(**pool_values)
|
||||
# now update the pool_id_1 with the prefix intersecting with
|
||||
# pool_id_2
|
||||
self.assertRaises(lib_exc.Conflict, self.client.update_subnetpool,
|
||||
pool_id_1, prefixes=pool_1_updated_prefixes)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('96006292-7214-40e0-a471-153fb76e6b31')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_update_subnetpool_prefix_intersect(self):
|
||||
pool_1_prefix = [u'20.0.0.0/18']
|
||||
pool_2_prefix = [u'20.10.0.0/24']
|
||||
pool_1_updated_prefix = [u'20.0.0.0/12']
|
||||
self._test_update_subnetpool_prefix_intersect_helper(
|
||||
pool_1_prefix, pool_2_prefix, pool_1_updated_prefix)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('4d3f8a79-c530-4e59-9acf-6c05968adbfe')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_update_subnetpool_multiple_prefix_intersect(self):
|
||||
pool_1_prefixes = [u'20.0.0.0/18', u'30.0.0.0/18']
|
||||
pool_2_prefixes = [u'20.10.0.0/24', u'40.0.0.0/18', '50.0.0.0/18']
|
||||
pool_1_updated_prefixes = [u'20.0.0.0/18', u'30.0.0.0/18',
|
||||
u'50.0.0.0/12']
|
||||
self._test_update_subnetpool_prefix_intersect_helper(
|
||||
pool_1_prefixes, pool_2_prefixes, pool_1_updated_prefixes)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('7438e49e-1351-45d8-937b-892059fb97f5')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_tenant_update_sp_prefix_associated_with_shared_addr_scope(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'), is_admin=True,
|
||||
shared=True, ip_version=4)
|
||||
addr_scope_id = address_scope['id']
|
||||
pool_values = {'prefixes': [u'20.0.0.0/18', u'30.0.0.0/18']}
|
||||
|
||||
created_subnetpool = self._create_subnetpool(**pool_values)
|
||||
pool_id = created_subnetpool['id']
|
||||
# associate the subnetpool to the address scope as an admin
|
||||
self.admin_client.update_subnetpool(pool_id,
|
||||
address_scope_id=addr_scope_id)
|
||||
body = self.admin_client.show_subnetpool(pool_id)
|
||||
self.assertEqual(addr_scope_id,
|
||||
body['subnetpool']['address_scope_id'])
|
||||
|
||||
# updating the subnetpool prefix by the tenant user should fail
|
||||
# since the tenant is not the owner of address scope
|
||||
update_prefixes = [u'20.0.0.0/18', u'30.0.0.0/18', u'40.0.0.0/18']
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.update_subnetpool,
|
||||
pool_id, prefixes=update_prefixes)
|
||||
|
||||
# admin can update the prefixes
|
||||
self.admin_client.update_subnetpool(pool_id, prefixes=update_prefixes)
|
||||
body = self.admin_client.show_subnetpool(pool_id)
|
||||
self.assertEqual(update_prefixes,
|
||||
body['subnetpool']['prefixes'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('648fee7d-a909-4ced-bad3-3a169444c0a8')
|
||||
@utils.requires_ext(extension='address-scope', service='network')
|
||||
def test_update_subnetpool_associate_address_scope_wrong_ip_version(self):
|
||||
address_scope = self.create_address_scope(
|
||||
name=data_utils.rand_name('smoke-address-scope'),
|
||||
ip_version=6)
|
||||
created_subnetpool = self._create_subnetpool()
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.update_subnetpool,
|
||||
created_subnetpool['id'],
|
||||
address_scope_id=address_scope['id'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('2f66dc2f-cc32-4caa-91ec-0c0cd7c46d70')
|
||||
def test_update_subnetpool_tenant_id(self):
|
||||
subnetpool = self._create_subnetpool()
|
||||
self.assertRaises(
|
||||
lib_exc.BadRequest,
|
||||
self.admin_client.update_subnetpool,
|
||||
subnetpool['id'],
|
||||
tenant_id=self.admin_client.tenant_id,
|
||||
)
|
@ -1,69 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
|
||||
|
||||
class SubnetsSearchCriteriaTest(base.BaseSearchCriteriaTest):
|
||||
|
||||
resource = 'subnet'
|
||||
|
||||
list_kwargs = {'shared': False}
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(SubnetsSearchCriteriaTest, cls).resource_setup()
|
||||
net = cls.create_network(network_name='subnet-search-test-net')
|
||||
for name in cls.resource_names:
|
||||
cls.create_subnet(net, name=name)
|
||||
|
||||
@decorators.idempotent_id('d2d61995-5dd5-4b93-bce7-3edefdb79563')
|
||||
def test_list_sorts_asc(self):
|
||||
self._test_list_sorts_asc()
|
||||
|
||||
@decorators.idempotent_id('c3c6b0af-c4ac-4da0-b568-8d08ae550604')
|
||||
def test_list_sorts_desc(self):
|
||||
self._test_list_sorts_desc()
|
||||
|
||||
@decorators.idempotent_id('b93063b3-f713-406e-bf93-e5738e09153c')
|
||||
def test_list_pagination(self):
|
||||
self._test_list_pagination()
|
||||
|
||||
@decorators.idempotent_id('2ddd9aa6-de28-410f-9cbc-ce752893c407')
|
||||
def test_list_pagination_with_marker(self):
|
||||
self._test_list_pagination_with_marker()
|
||||
|
||||
@decorators.idempotent_id('351183ef-6ed9-4d71-a9f2-a5ac049bd7ea')
|
||||
def test_list_pagination_with_href_links(self):
|
||||
self._test_list_pagination_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('dfaa20ca-6d84-4f26-962f-2fee4d247cd9')
|
||||
def test_list_pagination_page_reverse_asc(self):
|
||||
self._test_list_pagination_page_reverse_asc()
|
||||
|
||||
@decorators.idempotent_id('40552213-3e12-4d6a-86f3-dda92f3de88c')
|
||||
def test_list_pagination_page_reverse_desc(self):
|
||||
self._test_list_pagination_page_reverse_desc()
|
||||
|
||||
@decorators.idempotent_id('3cea9053-a731-4480-93ee-19b2c28a9ce4')
|
||||
def test_list_pagination_page_reverse_with_href_links(self):
|
||||
self._test_list_pagination_page_reverse_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('d851937c-9821-4b46-9d18-43e9077ecac0')
|
||||
def test_list_no_pagination_limit_0(self):
|
||||
self._test_list_no_pagination_limit_0()
|
||||
|
||||
@decorators.idempotent_id('c0f9280b-9d81-4728-a967-6be22659d4c8')
|
||||
def test_list_validation_filters(self):
|
||||
self._test_list_validation_filters()
|
@ -1,326 +0,0 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest.api import base_routers
|
||||
from neutron.tests.tempest.api import base_security_groups
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class TestTimeStamp(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ["standard-attr-timestamp"]
|
||||
|
||||
## attributes for subnetpool
|
||||
min_prefixlen = '28'
|
||||
max_prefixlen = '31'
|
||||
_ip_version = 4
|
||||
subnet_cidr = '10.11.12.0/31'
|
||||
new_prefix = '10.11.15.0/24'
|
||||
larger_prefix = '10.11.0.0/16'
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestTimeStamp, cls).resource_setup()
|
||||
prefixes = ['10.11.12.0/24']
|
||||
cls._subnetpool_data = {'min_prefixlen': '29', 'prefixes': prefixes}
|
||||
|
||||
def _create_subnetpool(self, is_admin=False, **kwargs):
|
||||
name = data_utils.rand_name('subnetpool')
|
||||
subnetpool_data = copy.deepcopy(self._subnetpool_data)
|
||||
for key in subnetpool_data.keys():
|
||||
kwargs[key] = subnetpool_data[key]
|
||||
return self.create_subnetpool(name=name, is_admin=is_admin, **kwargs)
|
||||
|
||||
@decorators.idempotent_id('462be770-b310-4df9-9c42-773217e4c8b1')
|
||||
def test_create_network_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(network['created_at'])
|
||||
self.assertIsNotNone(network['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('4db5417a-e11c-474d-a361-af00ebef57c5')
|
||||
def test_update_network_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
origin_updated_at = network['updated_at']
|
||||
update_body = {'name': network['name'] + 'new'}
|
||||
body = self.admin_client.update_network(network['id'],
|
||||
**update_body)
|
||||
updated_network = body['network']
|
||||
new_updated_at = updated_network['updated_at']
|
||||
self.assertEqual(network['created_at'], updated_network['created_at'])
|
||||
# Verify that origin_updated_at is not same with new_updated_at
|
||||
self.assertIsNot(origin_updated_at, new_updated_at)
|
||||
|
||||
@decorators.idempotent_id('2ac50ab2-7ebd-4e27-b3ce-a9e399faaea2')
|
||||
def test_show_networks_attribute_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
body = self.client.show_network(network['id'])
|
||||
show_net = body['network']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(network['created_at'],
|
||||
show_net['created_at'])
|
||||
self.assertEqual(network['updated_at'],
|
||||
show_net['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('8ee55186-454f-4b97-9f9f-eb2772ee891c')
|
||||
def test_create_subnet_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
subnet = self.create_subnet(network)
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(subnet['created_at'])
|
||||
self.assertIsNotNone(subnet['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('a490215a-6f4c-4af9-9a4c-57c41f1c4fa1')
|
||||
def test_update_subnet_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
subnet = self.create_subnet(network)
|
||||
origin_updated_at = subnet['updated_at']
|
||||
update_body = {'name': subnet['name'] + 'new'}
|
||||
body = self.admin_client.update_subnet(subnet['id'],
|
||||
**update_body)
|
||||
updated_subnet = body['subnet']
|
||||
new_updated_at = updated_subnet['updated_at']
|
||||
self.assertEqual(subnet['created_at'], updated_subnet['created_at'])
|
||||
# Verify that origin_updated_at is not same with new_updated_at
|
||||
self.assertIsNot(origin_updated_at, new_updated_at)
|
||||
|
||||
@decorators.idempotent_id('1836a086-e7cf-4141-bf57-0cfe79e8051e')
|
||||
def test_show_subnet_attribute_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
subnet = self.create_subnet(network)
|
||||
body = self.client.show_subnet(subnet['id'])
|
||||
show_subnet = body['subnet']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(subnet['created_at'],
|
||||
show_subnet['created_at'])
|
||||
self.assertEqual(subnet['updated_at'],
|
||||
show_subnet['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('e2450a7b-d84f-4600-a093-45e78597bbac')
|
||||
def test_create_port_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(port['created_at'])
|
||||
self.assertIsNotNone(port['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('4241e0d3-54b4-46ce-a9a7-093fc764161b')
|
||||
def test_update_port_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
origin_updated_at = port['updated_at']
|
||||
update_body = {'name': port['name'] + 'new'}
|
||||
body = self.admin_client.update_port(port['id'],
|
||||
**update_body)
|
||||
updated_port = body['port']
|
||||
new_updated_at = updated_port['updated_at']
|
||||
self.assertEqual(port['created_at'], updated_port['created_at'])
|
||||
# Verify that origin_updated_at is not same with new_updated_at
|
||||
self.assertIsNot(origin_updated_at, new_updated_at)
|
||||
|
||||
@decorators.idempotent_id('584c6723-40b6-4f26-81dd-f508f9d9fb51')
|
||||
def test_show_port_attribute_with_timestamp(self):
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
body = self.client.show_port(port['id'])
|
||||
show_port = body['port']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(port['created_at'],
|
||||
show_port['created_at'])
|
||||
self.assertEqual(port['updated_at'],
|
||||
show_port['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('87a8b196-4b90-44f0-b7f3-d2057d7d658e')
|
||||
def test_create_subnetpool_with_timestamp(self):
|
||||
sp = self._create_subnetpool()
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(sp['created_at'])
|
||||
self.assertIsNotNone(sp['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('d48c7578-c3d2-4f9b-a7a1-be2008c770a0')
|
||||
def test_update_subnetpool_with_timestamp(self):
|
||||
sp = self._create_subnetpool()
|
||||
origin_updated_at = sp['updated_at']
|
||||
update_body = {'name': sp['name'] + 'new',
|
||||
'min_prefixlen': self.min_prefixlen,
|
||||
'max_prefixlen': self.max_prefixlen}
|
||||
body = self.client.update_subnetpool(sp['id'], **update_body)
|
||||
updated_sp = body['subnetpool']
|
||||
new_updated_at = updated_sp['updated_at']
|
||||
self.assertEqual(sp['created_at'], updated_sp['created_at'])
|
||||
# Verify that origin_updated_at is not same with new_updated_at
|
||||
self.assertIsNot(origin_updated_at, new_updated_at)
|
||||
|
||||
@decorators.idempotent_id('1d3970e6-bcf7-46cd-b7d7-0807759c73b4')
|
||||
def test_show_subnetpool_attribute_with_timestamp(self):
|
||||
sp = self._create_subnetpool()
|
||||
body = self.client.show_subnetpool(sp['id'])
|
||||
show_sp = body['subnetpool']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(sp['created_at'], show_sp['created_at'])
|
||||
self.assertEqual(sp['updated_at'], show_sp['updated_at'])
|
||||
|
||||
|
||||
class TestTimeStampWithL3(base_routers.BaseRouterTest):
|
||||
|
||||
required_extensions = ['standard-attr-timestamp']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestTimeStampWithL3, cls).resource_setup()
|
||||
cls.ext_net_id = CONF.network.public_network_id
|
||||
|
||||
@decorators.idempotent_id('433ba770-b310-4da9-5d42-733217a1c7b1')
|
||||
def test_create_router_with_timestamp(self):
|
||||
router = self.create_router(router_name='test')
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(router['created_at'])
|
||||
self.assertIsNotNone(router['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('4a65417a-c11c-4b4d-a351-af01abcf57c6')
|
||||
def test_update_router_with_timestamp(self):
|
||||
router = self.create_router(router_name='test')
|
||||
origin_updated_at = router['updated_at']
|
||||
update_body = {'name': router['name'] + 'new'}
|
||||
body = self.client.update_router(router['id'], **update_body)
|
||||
updated_router = body['router']
|
||||
new_updated_at = updated_router['updated_at']
|
||||
self.assertEqual(router['created_at'], updated_router['created_at'])
|
||||
# Verify that origin_updated_at is not same with new_updated_at
|
||||
self.assertIsNot(origin_updated_at, new_updated_at)
|
||||
|
||||
@decorators.idempotent_id('1ab50ac2-7cbd-4a17-b23e-a9e36cfa4ec2')
|
||||
def test_show_router_attribute_with_timestamp(self):
|
||||
router = self.create_router(router_name='test')
|
||||
body = self.client.show_router(router['id'])
|
||||
show_router = body['router']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(router['created_at'],
|
||||
show_router['created_at'])
|
||||
# 'updated_at' timestamp can change immediately after creation
|
||||
# if environment is HA or DVR, so just make sure it's >=
|
||||
self.assertGreaterEqual(show_router['updated_at'],
|
||||
router['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('8ae55186-464f-4b87-1c9f-eb2765ee81ac')
|
||||
def test_create_floatingip_with_timestamp(self):
|
||||
fip = self.create_floatingip(self.ext_net_id)
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(fip['created_at'])
|
||||
self.assertIsNotNone(fip['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('a3ac215a-61ac-13f9-9d3c-57c51f11afa1')
|
||||
def test_update_floatingip_with_timestamp(self):
|
||||
fip = self.create_floatingip(self.ext_net_id)
|
||||
origin_updated_at = fip['updated_at']
|
||||
update_body = {'description': 'new'}
|
||||
body = self.client.update_floatingip(fip['id'], **update_body)
|
||||
updated_fip = body['floatingip']
|
||||
new_updated_at = updated_fip['updated_at']
|
||||
self.assertEqual(fip['created_at'], updated_fip['created_at'])
|
||||
# Verify that origin_updated_at is not same with new_updated_at
|
||||
self.assertIsNot(origin_updated_at, new_updated_at)
|
||||
|
||||
@decorators.idempotent_id('32a6a086-e1ef-413b-b13a-0cfe13ef051e')
|
||||
def test_show_floatingip_attribute_with_timestamp(self):
|
||||
fip = self.create_floatingip(self.ext_net_id)
|
||||
body = self.client.show_floatingip(fip['id'])
|
||||
show_fip = body['floatingip']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(fip['created_at'],
|
||||
show_fip['created_at'])
|
||||
self.assertEqual(fip['updated_at'],
|
||||
show_fip['updated_at'])
|
||||
|
||||
|
||||
class TestTimeStampWithSecurityGroup(base_security_groups.BaseSecGroupTest):
|
||||
|
||||
required_extensions = ['standard-attr-timestamp']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestTimeStampWithSecurityGroup, cls).resource_setup()
|
||||
cls.ext_net_id = CONF.network.public_network_id
|
||||
|
||||
@decorators.idempotent_id('a3150a7b-d31a-423a-abf3-45e71c97cbac')
|
||||
def test_create_sg_with_timestamp(self):
|
||||
sg, _ = self._create_security_group()
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(sg['security_group']['created_at'])
|
||||
self.assertIsNotNone(sg['security_group']['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('432ae0d3-32b4-413e-a9b3-091ac76da31b')
|
||||
def test_update_sg_with_timestamp(self):
|
||||
sgc, _ = self._create_security_group()
|
||||
sg = sgc['security_group']
|
||||
origin_updated_at = sg['updated_at']
|
||||
update_body = {'name': sg['name'] + 'new'}
|
||||
body = self.client.update_security_group(sg['id'], **update_body)
|
||||
updated_sg = body['security_group']
|
||||
new_updated_at = updated_sg['updated_at']
|
||||
self.assertEqual(sg['created_at'], updated_sg['created_at'])
|
||||
# Verify that origin_updated_at is not same with new_updated_at
|
||||
self.assertIsNot(origin_updated_at, new_updated_at)
|
||||
|
||||
@decorators.idempotent_id('521e6723-43d6-12a6-8c3d-f5042ad9fc32')
|
||||
def test_show_sg_attribute_with_timestamp(self):
|
||||
sg, _ = self._create_security_group()
|
||||
body = self.client.show_security_group(sg['security_group']['id'])
|
||||
show_sg = body['security_group']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(sg['security_group']['created_at'],
|
||||
show_sg['created_at'])
|
||||
self.assertEqual(sg['security_group']['updated_at'],
|
||||
show_sg['updated_at'])
|
||||
|
||||
def _prepare_sgrule_test(self):
|
||||
sg, _ = self._create_security_group()
|
||||
sg_id = sg['security_group']['id']
|
||||
direction = 'ingress'
|
||||
protocol = 'tcp'
|
||||
port_range_min = 77
|
||||
port_range_max = 77
|
||||
rule_create_body = self.client.create_security_group_rule(
|
||||
security_group_id=sg_id,
|
||||
direction=direction,
|
||||
ethertype=self.ethertype,
|
||||
protocol=protocol,
|
||||
port_range_min=port_range_min,
|
||||
port_range_max=port_range_max,
|
||||
remote_group_id=None,
|
||||
remote_ip_prefix=None
|
||||
)
|
||||
return rule_create_body['security_group_rule']
|
||||
|
||||
@decorators.idempotent_id('83e8bd32-43e0-a3f0-1af3-12a5733c653e')
|
||||
def test_create_sgrule_with_timestamp(self):
|
||||
sgrule = self._prepare_sgrule_test()
|
||||
# Verifies body contains timestamp fields
|
||||
self.assertIsNotNone(sgrule['created_at'])
|
||||
self.assertIsNotNone(sgrule['updated_at'])
|
||||
|
||||
@decorators.idempotent_id('143da0e6-ba17-43ad-b3d7-03aa759c3cb4')
|
||||
def test_show_sgrule_attribute_with_timestamp(self):
|
||||
sgrule = self._prepare_sgrule_test()
|
||||
body = self.client.show_security_group_rule(sgrule['id'])
|
||||
show_sgrule = body['security_group_rule']
|
||||
# verify the timestamp from creation and showed is same
|
||||
self.assertEqual(sgrule['created_at'], show_sgrule['created_at'])
|
||||
self.assertEqual(sgrule['updated_at'], show_sgrule['updated_at'])
|
@ -1,390 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
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
|
||||
|
||||
from neutron.tests.tempest.api import base
|
||||
from neutron.tests.tempest import config
|
||||
|
||||
|
||||
def trunks_cleanup(client, trunks):
|
||||
for trunk in trunks:
|
||||
# NOTE(armax): deleting a trunk with subports is permitted, however
|
||||
# for testing purposes it is safer to be explicit and clean all the
|
||||
# resources associated with the trunk beforehand.
|
||||
subports = test_utils.call_and_ignore_notfound_exc(
|
||||
client.get_subports, trunk['id'])
|
||||
if subports:
|
||||
client.remove_subports(
|
||||
trunk['id'], subports['sub_ports'])
|
||||
test_utils.call_and_ignore_notfound_exc(
|
||||
client.delete_trunk, trunk['id'])
|
||||
|
||||
|
||||
class TrunkTestJSONBase(base.BaseAdminNetworkTest):
|
||||
|
||||
required_extensions = ['trunk']
|
||||
|
||||
def setUp(self):
|
||||
self.addCleanup(self.resource_cleanup)
|
||||
super(TrunkTestJSONBase, self).setUp()
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TrunkTestJSONBase, cls).resource_setup()
|
||||
cls.trunks = []
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
trunks_cleanup(cls.client, cls.trunks)
|
||||
super(TrunkTestJSONBase, cls).resource_cleanup()
|
||||
|
||||
def _create_trunk_with_network_and_parent(self, subports, **kwargs):
|
||||
network = self.create_network()
|
||||
parent_port = self.create_port(network)
|
||||
trunk = self.client.create_trunk(parent_port['id'], subports, **kwargs)
|
||||
self.trunks.append(trunk['trunk'])
|
||||
return trunk
|
||||
|
||||
def _show_trunk(self, trunk_id):
|
||||
return self.client.show_trunk(trunk_id)
|
||||
|
||||
def _list_trunks(self):
|
||||
return self.client.list_trunks()
|
||||
|
||||
|
||||
class TrunkTestJSON(TrunkTestJSONBase):
|
||||
|
||||
def _test_create_trunk(self, subports):
|
||||
trunk = self._create_trunk_with_network_and_parent(subports)
|
||||
observed_trunk = self._show_trunk(trunk['trunk']['id'])
|
||||
self.assertEqual(trunk, observed_trunk)
|
||||
|
||||
@decorators.idempotent_id('e1a6355c-4768-41f3-9bf8-0f1d192bd501')
|
||||
def test_create_trunk_empty_subports_list(self):
|
||||
self._test_create_trunk([])
|
||||
|
||||
@decorators.idempotent_id('382dfa39-ca03-4bd3-9a1c-91e36d2e3796')
|
||||
def test_create_trunk_subports_not_specified(self):
|
||||
self._test_create_trunk(None)
|
||||
|
||||
@decorators.idempotent_id('7de46c22-e2b6-4959-ac5a-0e624632ab32')
|
||||
def test_create_show_delete_trunk(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(None)
|
||||
trunk_id = trunk['trunk']['id']
|
||||
parent_port_id = trunk['trunk']['port_id']
|
||||
res = self._show_trunk(trunk_id)
|
||||
self.assertEqual(trunk_id, res['trunk']['id'])
|
||||
self.assertEqual(parent_port_id, res['trunk']['port_id'])
|
||||
self.client.delete_trunk(trunk_id)
|
||||
self.assertRaises(lib_exc.NotFound, self._show_trunk, trunk_id)
|
||||
|
||||
@decorators.idempotent_id('8d83a6ca-662d-45b8-8062-d513077296aa')
|
||||
@utils.requires_ext(extension="project-id", service="network")
|
||||
def test_show_trunk_has_project_id(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(None)
|
||||
body = self._show_trunk(trunk['trunk']['id'])
|
||||
show_trunk = body['trunk']
|
||||
self.assertIn('project_id', show_trunk)
|
||||
self.assertIn('tenant_id', show_trunk)
|
||||
self.assertEqual(self.client.tenant_id, show_trunk['project_id'])
|
||||
self.assertEqual(self.client.tenant_id, show_trunk['tenant_id'])
|
||||
|
||||
@decorators.idempotent_id('4ce46c22-a2b6-4659-bc5a-0ef2463cab32')
|
||||
def test_create_update_trunk(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(None)
|
||||
rev = trunk['trunk']['revision_number']
|
||||
trunk_id = trunk['trunk']['id']
|
||||
res = self._show_trunk(trunk_id)
|
||||
self.assertTrue(res['trunk']['admin_state_up'])
|
||||
self.assertEqual(rev, res['trunk']['revision_number'])
|
||||
self.assertEqual("", res['trunk']['name'])
|
||||
self.assertEqual("", res['trunk']['description'])
|
||||
res = self.client.update_trunk(
|
||||
trunk_id, name='foo', admin_state_up=False)
|
||||
self.assertFalse(res['trunk']['admin_state_up'])
|
||||
self.assertEqual("foo", res['trunk']['name'])
|
||||
self.assertGreater(res['trunk']['revision_number'], rev)
|
||||
# enable the trunk so that it can be managed
|
||||
self.client.update_trunk(trunk_id, admin_state_up=True)
|
||||
|
||||
@decorators.idempotent_id('5ff46c22-a2b6-5559-bc5a-0ef2463cab32')
|
||||
def test_create_update_trunk_with_description(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(
|
||||
None, description="foo description")
|
||||
trunk_id = trunk['trunk']['id']
|
||||
self.assertEqual("foo description", trunk['trunk']['description'])
|
||||
trunk = self.client.update_trunk(trunk_id, description='')
|
||||
self.assertEqual('', trunk['trunk']['description'])
|
||||
|
||||
@decorators.idempotent_id('73365f73-bed6-42cd-960b-ec04e0c99d85')
|
||||
def test_list_trunks(self):
|
||||
trunk1 = self._create_trunk_with_network_and_parent(None)
|
||||
trunk2 = self._create_trunk_with_network_and_parent(None)
|
||||
expected_trunks = {trunk1['trunk']['id']: trunk1['trunk'],
|
||||
trunk2['trunk']['id']: trunk2['trunk']}
|
||||
trunk_list = self._list_trunks()['trunks']
|
||||
matched_trunks = [x for x in trunk_list if x['id'] in expected_trunks]
|
||||
self.assertEqual(2, len(matched_trunks))
|
||||
for trunk in matched_trunks:
|
||||
self.assertEqual(expected_trunks[trunk['id']], trunk)
|
||||
|
||||
@decorators.idempotent_id('bb5fcead-09b5-484a-bbe6-46d1e06d6cc0')
|
||||
def test_add_subport(self):
|
||||
trunk = self._create_trunk_with_network_and_parent([])
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
subports = [{'port_id': port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
self.client.add_subports(trunk['trunk']['id'], subports)
|
||||
trunk = self._show_trunk(trunk['trunk']['id'])
|
||||
observed_subports = trunk['trunk']['sub_ports']
|
||||
self.assertEqual(1, len(observed_subports))
|
||||
created_subport = observed_subports[0]
|
||||
self.assertEqual(subports[0], created_subport)
|
||||
|
||||
@decorators.idempotent_id('ee5fcead-1abf-483a-bce6-43d1e06d6aa0')
|
||||
def test_delete_trunk_with_subport_is_allowed(self):
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
subports = [{'port_id': port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
trunk = self._create_trunk_with_network_and_parent(subports)
|
||||
self.client.delete_trunk(trunk['trunk']['id'])
|
||||
|
||||
@decorators.idempotent_id('96eea398-a03c-4c3e-a99e-864392c2ca53')
|
||||
def test_remove_subport(self):
|
||||
subport_parent1 = self.create_port(self.create_network())
|
||||
subport_parent2 = self.create_port(self.create_network())
|
||||
subports = [{'port_id': subport_parent1['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2},
|
||||
{'port_id': subport_parent2['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 4}]
|
||||
trunk = self._create_trunk_with_network_and_parent(subports)
|
||||
removed_subport = trunk['trunk']['sub_ports'][0]
|
||||
expected_subport = None
|
||||
|
||||
for subport in subports:
|
||||
if subport['port_id'] != removed_subport['port_id']:
|
||||
expected_subport = subport
|
||||
break
|
||||
|
||||
# Remove the subport and validate PUT response
|
||||
res = self.client.remove_subports(trunk['trunk']['id'],
|
||||
[removed_subport])
|
||||
self.assertEqual(1, len(res['sub_ports']))
|
||||
self.assertEqual(expected_subport, res['sub_ports'][0])
|
||||
|
||||
# Validate the results of a subport list
|
||||
trunk = self._show_trunk(trunk['trunk']['id'])
|
||||
observed_subports = trunk['trunk']['sub_ports']
|
||||
self.assertEqual(1, len(observed_subports))
|
||||
self.assertEqual(expected_subport, observed_subports[0])
|
||||
|
||||
@decorators.idempotent_id('bb5fcaad-09b5-484a-dde6-4cd1ea6d6ff0')
|
||||
def test_get_subports(self):
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
subports = [{'port_id': port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
trunk = self._create_trunk_with_network_and_parent(subports)
|
||||
trunk = self.client.get_subports(trunk['trunk']['id'])
|
||||
observed_subports = trunk['sub_ports']
|
||||
self.assertEqual(1, len(observed_subports))
|
||||
|
||||
|
||||
class TrunkTestInheritJSONBase(TrunkTestJSONBase):
|
||||
|
||||
required_extensions = ['provider', 'trunk']
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(TrunkTestInheritJSONBase, cls).skip_checks()
|
||||
if ("vlan" not in
|
||||
config.CONF.neutron_plugin_options.available_type_drivers):
|
||||
raise cls.skipException("VLAN type_driver is not enabled")
|
||||
if not config.CONF.neutron_plugin_options.provider_vlans:
|
||||
raise cls.skipException("No provider VLAN networks available")
|
||||
|
||||
def create_provider_network(self):
|
||||
foo_net = config.CONF.neutron_plugin_options.provider_vlans[0]
|
||||
post_body = {'network_name': data_utils.rand_name('vlan-net'),
|
||||
'provider:network_type': 'vlan',
|
||||
'provider:physical_network': foo_net}
|
||||
return self.create_shared_network(**post_body)
|
||||
|
||||
@decorators.idempotent_id('0f05d98e-41f5-4629-dada-9aee269c9602')
|
||||
def test_add_subport(self):
|
||||
trunk_network = self.create_provider_network()
|
||||
trunk_port = self.create_port(trunk_network)
|
||||
subport_networks = [
|
||||
self.create_provider_network(),
|
||||
self.create_provider_network(),
|
||||
]
|
||||
subport1 = self.create_port(subport_networks[0])
|
||||
subport2 = self.create_port(subport_networks[1])
|
||||
subports = [{'port_id': subport1['id'],
|
||||
'segmentation_type': 'inherit',
|
||||
'segmentation_id': subport1['id']},
|
||||
{'port_id': subport2['id'],
|
||||
'segmentation_type': 'inherit',
|
||||
'segmentation_id': subport2['id']}]
|
||||
trunk = self.client.create_trunk(trunk_port['id'], subports)['trunk']
|
||||
self.trunks.append(trunk)
|
||||
# Validate that subport got segmentation details from the network
|
||||
for i in range(2):
|
||||
self.assertEqual(subport_networks[i]['provider:network_type'],
|
||||
trunk['sub_ports'][i]['segmentation_type'])
|
||||
self.assertEqual(subport_networks[i]['provider:segmentation_id'],
|
||||
trunk['sub_ports'][i]['segmentation_id'])
|
||||
|
||||
|
||||
class TrunkTestMtusJSONBase(TrunkTestJSONBase):
|
||||
|
||||
required_extensions = ['provider', 'trunk']
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(TrunkTestMtusJSONBase, cls).skip_checks()
|
||||
if any(t
|
||||
not in config.CONF.neutron_plugin_options.available_type_drivers
|
||||
for t in ['gre', 'vxlan']):
|
||||
msg = "Either vxlan or gre type driver not enabled."
|
||||
raise cls.skipException(msg)
|
||||
|
||||
def setUp(self):
|
||||
super(TrunkTestMtusJSONBase, self).setUp()
|
||||
|
||||
# VXLAN autocomputed MTU (1450) is smaller than that of GRE (1458)
|
||||
vxlan_kwargs = {'network_name': data_utils.rand_name('vxlan-net'),
|
||||
'provider:network_type': 'vxlan'}
|
||||
self.smaller_mtu_net = self.create_shared_network(**vxlan_kwargs)
|
||||
|
||||
gre_kwargs = {'network_name': data_utils.rand_name('gre-net'),
|
||||
'provider:network_type': 'gre'}
|
||||
self.larger_mtu_net = self.create_shared_network(**gre_kwargs)
|
||||
|
||||
self.smaller_mtu_port = self.create_port(self.smaller_mtu_net)
|
||||
self.smaller_mtu_port_2 = self.create_port(self.smaller_mtu_net)
|
||||
self.larger_mtu_port = self.create_port(self.larger_mtu_net)
|
||||
|
||||
|
||||
class TrunkTestMtusJSON(TrunkTestMtusJSONBase):
|
||||
|
||||
@decorators.idempotent_id('0f05d98e-41f5-4629-ac29-9aee269c9602')
|
||||
def test_create_trunk_with_mtu_greater_than_subport(self):
|
||||
subports = [{'port_id': self.smaller_mtu_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
|
||||
trunk = self.client.create_trunk(self.larger_mtu_port['id'], subports)
|
||||
self.trunks.append(trunk['trunk'])
|
||||
|
||||
@decorators.idempotent_id('2004c5c6-e557-4c43-8100-c820ad4953e8')
|
||||
def test_add_subport_with_mtu_smaller_than_trunk(self):
|
||||
subports = [{'port_id': self.smaller_mtu_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
|
||||
trunk = self.client.create_trunk(self.larger_mtu_port['id'], None)
|
||||
self.trunks.append(trunk['trunk'])
|
||||
|
||||
self.client.add_subports(trunk['trunk']['id'], subports)
|
||||
|
||||
@decorators.idempotent_id('22725101-f4bc-4e00-84ec-4e02cd7e0500')
|
||||
def test_create_trunk_with_mtu_equal_to_subport(self):
|
||||
subports = [{'port_id': self.smaller_mtu_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
|
||||
trunk = self.client.create_trunk(self.smaller_mtu_port_2['id'],
|
||||
subports)
|
||||
self.trunks.append(trunk['trunk'])
|
||||
|
||||
@decorators.idempotent_id('175b05ae-66ad-44c7-857a-a12d16f1058f')
|
||||
def test_add_subport_with_mtu_equal_to_trunk(self):
|
||||
subports = [{'port_id': self.smaller_mtu_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
|
||||
trunk = self.client.create_trunk(self.smaller_mtu_port_2['id'], None)
|
||||
self.trunks.append(trunk['trunk'])
|
||||
|
||||
self.client.add_subports(trunk['trunk']['id'], subports)
|
||||
|
||||
|
||||
class TrunksSearchCriteriaTest(base.BaseSearchCriteriaTest):
|
||||
|
||||
required_extensions = ['trunk']
|
||||
resource = 'trunk'
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TrunksSearchCriteriaTest, cls).resource_setup()
|
||||
cls.trunks = []
|
||||
net = cls.create_network(network_name='trunk-search-test-net')
|
||||
for name in cls.resource_names:
|
||||
parent_port = cls.create_port(net)
|
||||
trunk = cls.client.create_trunk(parent_port['id'], [], name=name)
|
||||
cls.trunks.append(trunk['trunk'])
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
trunks_cleanup(cls.client, cls.trunks)
|
||||
super(TrunksSearchCriteriaTest, cls).resource_cleanup()
|
||||
|
||||
@decorators.idempotent_id('fab73df4-960a-4ae3-87d3-60992b8d3e2d')
|
||||
def test_list_sorts_asc(self):
|
||||
self._test_list_sorts_asc()
|
||||
|
||||
@decorators.idempotent_id('a426671d-7270-430f-82ff-8f33eec93010')
|
||||
def test_list_sorts_desc(self):
|
||||
self._test_list_sorts_desc()
|
||||
|
||||
@decorators.idempotent_id('b202fdc8-6616-45df-b6a0-463932de6f94')
|
||||
def test_list_pagination(self):
|
||||
self._test_list_pagination()
|
||||
|
||||
@decorators.idempotent_id('c4723b8e-8186-4b9a-bf9e-57519967e048')
|
||||
def test_list_pagination_with_marker(self):
|
||||
self._test_list_pagination_with_marker()
|
||||
|
||||
@decorators.idempotent_id('dcd02a7a-f07e-4d5e-b0ca-b58e48927a9b')
|
||||
def test_list_pagination_with_href_links(self):
|
||||
self._test_list_pagination_with_href_links()
|
||||
|
||||
@decorators.idempotent_id('eafe7024-77ab-4cfe-824b-0b2bf4217727')
|
||||
def test_list_no_pagination_limit_0(self):
|
||||
self._test_list_no_pagination_limit_0()
|
||||
|
||||
@decorators.idempotent_id('f8857391-dc44-40cc-89b7-2800402e03ce')
|
||||
def test_list_pagination_page_reverse_asc(self):
|
||||
self._test_list_pagination_page_reverse_asc()
|
||||
|
||||
@decorators.idempotent_id('ae51e9c9-ceae-4ec0-afd4-147569247699')
|
||||
def test_list_pagination_page_reverse_desc(self):
|
||||
self._test_list_pagination_page_reverse_desc()
|
||||
|
||||
@decorators.idempotent_id('b4293e59-d794-4a93-be09-38667199ef68')
|
||||
def test_list_pagination_page_reverse_with_href_links(self):
|
||||
self._test_list_pagination_page_reverse_with_href_links()
|
@ -1,58 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import test_trunk
|
||||
|
||||
|
||||
class TestTrunkDetailsJSON(test_trunk.TrunkTestJSONBase):
|
||||
|
||||
required_extensions = ['trunk-details']
|
||||
|
||||
@decorators.idempotent_id('f0bed24f-d36a-498b-b4e7-0d66e3fb7308')
|
||||
def test_port_resource_trunk_details_no_subports(self):
|
||||
trunk = self._create_trunk_with_network_and_parent([])
|
||||
port = self.client.show_port(trunk['trunk']['port_id'])
|
||||
expected_trunk_details = {'sub_ports': [],
|
||||
'trunk_id': trunk['trunk']['id']}
|
||||
observed_trunk_details = port['port'].get('trunk_details')
|
||||
self.assertIsNotNone(observed_trunk_details)
|
||||
self.assertEqual(expected_trunk_details,
|
||||
observed_trunk_details)
|
||||
|
||||
@decorators.idempotent_id('544bcaf2-86fb-4930-93ab-ece1c3cc33df')
|
||||
def test_port_resource_trunk_details_with_subport(self):
|
||||
subport_network = self.create_network()
|
||||
subport = self.create_port(subport_network)
|
||||
subport_data = {'port_id': subport['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}
|
||||
trunk = self._create_trunk_with_network_and_parent([subport_data])
|
||||
subport_data['mac_address'] = subport['mac_address']
|
||||
parent_port = self.client.show_port(trunk['trunk']['port_id'])
|
||||
expected_trunk_details = {'sub_ports': [subport_data],
|
||||
'trunk_id': trunk['trunk']['id']}
|
||||
observed_trunk_details = parent_port['port'].get('trunk_details')
|
||||
self.assertIsNotNone(observed_trunk_details)
|
||||
self.assertEqual(expected_trunk_details,
|
||||
observed_trunk_details)
|
||||
|
||||
@decorators.idempotent_id('fe6d865f-1d5c-432e-b65d-904157172f24')
|
||||
def test_port_resource_empty_trunk_details(self):
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
port = self.client.show_port(port['id'])
|
||||
observed_trunk_details = port['port'].get('trunk_details')
|
||||
self.assertIsNone(observed_trunk_details)
|
@ -1,282 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
import testtools
|
||||
|
||||
from neutron.tests.tempest.api import test_trunk
|
||||
|
||||
|
||||
class TrunkTestJSON(test_trunk.TrunkTestJSONBase):
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('1b5cf87a-1d3a-4a94-ba64-647153d54f32')
|
||||
def test_create_trunk_nonexistent_port_id(self):
|
||||
self.assertRaises(lib_exc.NotFound, self.client.create_trunk,
|
||||
uuidutils.generate_uuid(), [])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('980bca3b-b0be-45ac-8067-b401e445b796')
|
||||
def test_create_trunk_nonexistent_subport_port_id(self):
|
||||
network = self.create_network()
|
||||
parent_port = self.create_port(network)
|
||||
self.assertRaises(lib_exc.NotFound, self.client.create_trunk,
|
||||
parent_port['id'],
|
||||
[{'port_id': uuidutils.generate_uuid(),
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('a5c5200a-72a0-43c5-a11a-52f808490344')
|
||||
def test_create_subport_nonexistent_port_id(self):
|
||||
trunk = self._create_trunk_with_network_and_parent([])
|
||||
self.assertRaises(lib_exc.NotFound, self.client.add_subports,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': uuidutils.generate_uuid(),
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('80deb6a9-da2a-48db-b7fd-bcef5b14edc1')
|
||||
def test_create_subport_nonexistent_trunk(self):
|
||||
network = self.create_network()
|
||||
parent_port = self.create_port(network)
|
||||
self.assertRaises(lib_exc.NotFound, self.client.add_subports,
|
||||
uuidutils.generate_uuid(),
|
||||
[{'port_id': parent_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('7e0f99ab-fe37-408b-a889-9e44ef300084')
|
||||
def test_create_subport_missing_segmentation_id(self):
|
||||
trunk = self._create_trunk_with_network_and_parent([])
|
||||
subport_network = self.create_network()
|
||||
parent_port = self.create_port(subport_network)
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.add_subports,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': parent_port['id'],
|
||||
'segmentation_type': 'vlan'}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('a315d78b-2f43-4efa-89ae-166044c568aa')
|
||||
def test_create_trunk_with_subport_missing_segmentation_id(self):
|
||||
subport_network = self.create_network()
|
||||
parent_port = self.create_port(subport_network)
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.create_trunk,
|
||||
parent_port['id'],
|
||||
[{'port_id': uuidutils.generate_uuid(),
|
||||
'segmentation_type': 'vlan'}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('33498618-f75a-4796-8ae6-93d4fd203fa4')
|
||||
def test_create_trunk_with_subport_missing_segmentation_type(self):
|
||||
subport_network = self.create_network()
|
||||
parent_port = self.create_port(subport_network)
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.create_trunk,
|
||||
parent_port['id'],
|
||||
[{'port_id': uuidutils.generate_uuid(),
|
||||
'segmentation_id': 3}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('a717691c-4e07-4d81-a98d-6f1c18c5d183')
|
||||
def test_create_trunk_with_subport_missing_port_id(self):
|
||||
subport_network = self.create_network()
|
||||
parent_port = self.create_port(subport_network)
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.create_trunk,
|
||||
parent_port['id'],
|
||||
[{'segmentation_type': 'vlan',
|
||||
'segmentation_id': 3}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('40aed9be-e976-47d0-dada-bde2c7e74e57')
|
||||
def test_create_subport_invalid_inherit_network_segmentation_type(self):
|
||||
trunk = self._create_trunk_with_network_and_parent([])
|
||||
subport_network = self.create_network()
|
||||
parent_port = self.create_port(subport_network)
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.add_subports,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': parent_port['id'],
|
||||
'segmentation_type': 'inherit',
|
||||
'segmentation_id': -1}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('40aed9be-e976-47d0-a555-bde2c7e74e57')
|
||||
def test_create_trunk_duplicate_subport_segmentation_ids(self):
|
||||
trunk = self._create_trunk_with_network_and_parent([])
|
||||
subport_network1 = self.create_network()
|
||||
subport_network2 = self.create_network()
|
||||
parent_port1 = self.create_port(subport_network1)
|
||||
parent_port2 = self.create_port(subport_network2)
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.create_trunk,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': parent_port1['id'],
|
||||
'segmentation_id': 2,
|
||||
'segmentation_type': 'vlan'},
|
||||
{'port_id': parent_port2['id'],
|
||||
'segmentation_id': 2,
|
||||
'segmentation_type': 'vlan'}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('6f132ccc-1380-42d8-9c44-50411612bd01')
|
||||
def test_add_subport_port_id_uses_trunk_port_id(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(None)
|
||||
self.assertRaises(lib_exc.Conflict, self.client.add_subports,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': trunk['trunk']['port_id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('7f132ccc-1380-42d8-9c44-50411612bd01')
|
||||
def test_add_subport_port_id_disabled_trunk(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(
|
||||
None, admin_state_up=False)
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.client.add_subports,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': trunk['trunk']['port_id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
self.client.update_trunk(
|
||||
trunk['trunk']['id'], admin_state_up=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('8f132ccc-1380-42d8-9c44-50411612bd01')
|
||||
def test_remove_subport_port_id_disabled_trunk(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(
|
||||
None, admin_state_up=False)
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.client.remove_subports,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': trunk['trunk']['port_id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
self.client.update_trunk(
|
||||
trunk['trunk']['id'], admin_state_up=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('9f132ccc-1380-42d8-9c44-50411612bd01')
|
||||
def test_delete_trunk_disabled_trunk(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(
|
||||
None, admin_state_up=False)
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.client.delete_trunk,
|
||||
trunk['trunk']['id'])
|
||||
self.client.update_trunk(
|
||||
trunk['trunk']['id'], admin_state_up=True)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('00cb40bb-1593-44c8-808c-72b47e64252f')
|
||||
def test_add_subport_duplicate_segmentation_details(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(None)
|
||||
network = self.create_network()
|
||||
parent_port1 = self.create_port(network)
|
||||
parent_port2 = self.create_port(network)
|
||||
self.client.add_subports(trunk['trunk']['id'],
|
||||
[{'port_id': parent_port1['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
self.assertRaises(lib_exc.Conflict, self.client.add_subports,
|
||||
trunk['trunk']['id'],
|
||||
[{'port_id': parent_port2['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('4eac8c25-83ee-4051-9620-34774f565730')
|
||||
def test_add_subport_passing_dict(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(None)
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.add_subports,
|
||||
trunk['trunk']['id'],
|
||||
{'port_id': trunk['trunk']['port_id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2})
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('17ca7dd7-96a8-445a-941e-53c0c86c2fe2')
|
||||
def test_remove_subport_passing_dict(self):
|
||||
network = self.create_network()
|
||||
parent_port = self.create_port(network)
|
||||
subport_data = {'port_id': parent_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}
|
||||
trunk = self._create_trunk_with_network_and_parent([subport_data])
|
||||
self.assertRaises(lib_exc.BadRequest, self.client.remove_subports,
|
||||
trunk['trunk']['id'], subport_data)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('aaca7dd7-96b8-445a-931e-63f0d86d2fe2')
|
||||
def test_remove_subport_not_found(self):
|
||||
network = self.create_network()
|
||||
parent_port = self.create_port(network)
|
||||
subport_data = {'port_id': parent_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}
|
||||
trunk = self._create_trunk_with_network_and_parent([])
|
||||
self.assertRaises(lib_exc.NotFound, self.client.remove_subports,
|
||||
trunk['trunk']['id'], [subport_data])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('6c9c5126-4f61-11e6-8248-40a8f063c891')
|
||||
def test_delete_port_in_use_by_trunk(self):
|
||||
trunk = self._create_trunk_with_network_and_parent(None)
|
||||
self.assertRaises(lib_exc.Conflict, self.client.delete_port,
|
||||
trunk['trunk']['port_id'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('343a03d0-4f7c-11e6-97fa-40a8f063c891')
|
||||
def test_delete_port_in_use_by_subport(self):
|
||||
network = self.create_network()
|
||||
port = self.create_port(network)
|
||||
subports = [{'port_id': port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
self._create_trunk_with_network_and_parent(subports)
|
||||
self.assertRaises(lib_exc.Conflict, self.client.delete_port,
|
||||
port['id'])
|
||||
|
||||
|
||||
class TrunkTestMtusJSON(test_trunk.TrunkTestMtusJSONBase):
|
||||
|
||||
required_extensions = (
|
||||
['net-mtu'] + test_trunk.TrunkTestMtusJSONBase.required_extensions)
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('228380ef-1b7a-495e-b759-5b1f08e3e858')
|
||||
def test_create_trunk_with_mtu_smaller_than_subport(self):
|
||||
subports = [{'port_id': self.larger_mtu_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
|
||||
with testtools.ExpectedException(lib_exc.Conflict):
|
||||
trunk = self.client.create_trunk(self.smaller_mtu_port['id'],
|
||||
subports)
|
||||
self.trunks.append(trunk['trunk'])
|
||||
|
||||
@decorators.attr(type='negative')
|
||||
@decorators.idempotent_id('3b32bf77-8002-403e-ad01-6f4cf018daa5')
|
||||
def test_add_subport_with_mtu_greater_than_trunk(self):
|
||||
subports = [{'port_id': self.larger_mtu_port['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': 2}]
|
||||
|
||||
trunk = self.client.create_trunk(self.smaller_mtu_port['id'], None)
|
||||
self.trunks.append(trunk['trunk'])
|
||||
|
||||
self.assertRaises(lib_exc.Conflict,
|
||||
self.client.add_subports,
|
||||
trunk['trunk']['id'], subports)
|
@ -1,36 +0,0 @@
|
||||
# Copyright 2015
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import os
|
||||
|
||||
from tempest.test_discover import plugins
|
||||
|
||||
import neutron
|
||||
|
||||
|
||||
class NeutronTempestPlugin(plugins.TempestPlugin):
|
||||
def load_tests(self):
|
||||
base_path = os.path.split(os.path.dirname(
|
||||
os.path.abspath(neutron.__file__)))[0]
|
||||
test_dir = "neutron/tests/tempest"
|
||||
full_test_dir = os.path.join(base_path, test_dir)
|
||||
return full_test_dir, base_path
|
||||
|
||||
def register_opts(self, conf):
|
||||
pass
|
||||
|
||||
def get_opt_lists(self):
|
||||
pass
|
@ -1,35 +0,0 @@
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class NetworkBasicTest(base.BaseTempestTestCase):
|
||||
credentials = ['primary']
|
||||
force_tenant_isolation = False
|
||||
|
||||
# Default to ipv4.
|
||||
_ip_version = 4
|
||||
|
||||
@decorators.idempotent_id('de07fe0a-e955-449e-b48b-8641c14cd52e')
|
||||
def test_basic_instance(self):
|
||||
self.setup_network_and_server()
|
||||
self.check_connectivity(self.fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
@ -1,66 +0,0 @@
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
from neutron_lib import constants
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class NetworkTestMixin(object):
|
||||
def _check_connectivity(self):
|
||||
self.check_connectivity(self.fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
def _check_snat_port_connectivity(self):
|
||||
self._check_connectivity()
|
||||
|
||||
# Put the Router_SNAT port down to make sure the traffic flows through
|
||||
# Compute node.
|
||||
self._put_snat_port_down(self.network['id'])
|
||||
self._check_connectivity()
|
||||
|
||||
def _put_snat_port_down(self, network_id):
|
||||
port_id = self.client.list_ports(
|
||||
network_id=network_id,
|
||||
device_owner=constants.DEVICE_OWNER_ROUTER_SNAT)['ports'][0]['id']
|
||||
self.os_admin.network_client.update_port(
|
||||
port_id, admin_state_up=False)
|
||||
|
||||
|
||||
class NetworkDvrTest(base.BaseTempestTestCase, NetworkTestMixin):
|
||||
credentials = ['primary', 'admin']
|
||||
force_tenant_isolation = False
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="dvr", service="network")
|
||||
def skip_checks(cls):
|
||||
super(NetworkDvrTest, cls).skip_checks()
|
||||
|
||||
@decorators.idempotent_id('3d73ec1a-2ec6-45a9-b0f8-04a283d9d344')
|
||||
def test_vm_reachable_through_compute(self):
|
||||
"""Check that the VM is reachable through compute node.
|
||||
|
||||
The test is done by putting the SNAT port down on controller node.
|
||||
"""
|
||||
router = self.create_router_by_client(
|
||||
distributed=True, tenant_id=self.client.tenant_id, is_admin=True,
|
||||
ha=False)
|
||||
self.setup_network_and_server(router=router)
|
||||
self._check_snat_port_connectivity()
|
@ -1,156 +0,0 @@
|
||||
# Copyright (c) 2017 Midokura SARL
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from tempest.common import utils
|
||||
from tempest.common import waiters
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
import testscenarios
|
||||
from testscenarios.scenarios import multiply_scenarios
|
||||
|
||||
from neutron.tests.tempest.common import ssh
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
from neutron.tests.tempest.scenario import constants
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
load_tests = testscenarios.load_tests_apply_scenarios
|
||||
|
||||
|
||||
class FloatingIpTestCasesMixin(object):
|
||||
credentials = ['primary', 'admin']
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="router", service="network")
|
||||
def resource_setup(cls):
|
||||
super(FloatingIpTestCasesMixin, cls).resource_setup()
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
cls.router = cls.create_router_by_client()
|
||||
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
|
||||
cls.keypair = cls.create_keypair()
|
||||
|
||||
cls.secgroup = cls.os_primary.network_client.create_security_group(
|
||||
name=data_utils.rand_name('secgroup'))['security_group']
|
||||
cls.security_groups.append(cls.secgroup)
|
||||
cls.create_loginable_secgroup_rule(secgroup_id=cls.secgroup['id'])
|
||||
cls.create_pingable_secgroup_rule(secgroup_id=cls.secgroup['id'])
|
||||
|
||||
if cls.same_network:
|
||||
cls._dest_network = cls.network
|
||||
else:
|
||||
cls._dest_network = cls._create_dest_network()
|
||||
|
||||
@classmethod
|
||||
def _create_dest_network(cls):
|
||||
network = cls.create_network()
|
||||
subnet = cls.create_subnet(network,
|
||||
cidr=netaddr.IPNetwork('10.10.0.0/24'))
|
||||
cls.create_router_interface(cls.router['id'], subnet['id'])
|
||||
return network
|
||||
|
||||
def _create_server(self, create_floating_ip=True, network=None):
|
||||
if network is None:
|
||||
network = self.network
|
||||
port = self.create_port(network, security_groups=[self.secgroup['id']])
|
||||
if create_floating_ip:
|
||||
fip = self.create_and_associate_floatingip(port['id'])
|
||||
else:
|
||||
fip = None
|
||||
server = self.create_server(
|
||||
flavor_ref=CONF.compute.flavor_ref,
|
||||
image_ref=CONF.compute.image_ref,
|
||||
key_name=self.keypair['name'],
|
||||
networks=[{'port': port['id']}])['server']
|
||||
waiters.wait_for_server_status(self.os_primary.servers_client,
|
||||
server['id'],
|
||||
constants.SERVER_STATUS_ACTIVE)
|
||||
return {'port': port, 'fip': fip, 'server': server}
|
||||
|
||||
def _test_east_west(self):
|
||||
# The proxy VM is used to control the source VM when it doesn't
|
||||
# have a floating-ip.
|
||||
if self.src_has_fip:
|
||||
proxy = None
|
||||
proxy_client = None
|
||||
else:
|
||||
proxy = self._create_server()
|
||||
proxy_client = ssh.Client(proxy['fip']['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
pkey=self.keypair['private_key'])
|
||||
|
||||
# Source VM
|
||||
if self.src_has_fip:
|
||||
src_server = self._create_server()
|
||||
src_server_ip = src_server['fip']['floating_ip_address']
|
||||
else:
|
||||
src_server = self._create_server(create_floating_ip=False)
|
||||
src_server_ip = src_server['port']['fixed_ips'][0]['ip_address']
|
||||
ssh_client = ssh.Client(src_server_ip,
|
||||
CONF.validation.image_ssh_user,
|
||||
pkey=self.keypair['private_key'],
|
||||
proxy_client=proxy_client)
|
||||
|
||||
# Destination VM
|
||||
if self.dest_has_fip:
|
||||
dest_server = self._create_server(network=self._dest_network)
|
||||
else:
|
||||
dest_server = self._create_server(create_floating_ip=False,
|
||||
network=self._dest_network)
|
||||
|
||||
# Check connectivity
|
||||
self.check_remote_connectivity(ssh_client,
|
||||
dest_server['port']['fixed_ips'][0]['ip_address'])
|
||||
if self.dest_has_fip:
|
||||
self.check_remote_connectivity(ssh_client,
|
||||
dest_server['fip']['floating_ip_address'])
|
||||
|
||||
|
||||
class FloatingIpSameNetwork(FloatingIpTestCasesMixin,
|
||||
base.BaseTempestTestCase):
|
||||
scenarios = multiply_scenarios([
|
||||
('SRC with FIP', dict(src_has_fip=True)),
|
||||
('SRC without FIP', dict(src_has_fip=False)),
|
||||
], [
|
||||
('DEST with FIP', dict(dest_has_fip=True)),
|
||||
('DEST without FIP', dict(dest_has_fip=False)),
|
||||
])
|
||||
|
||||
same_network = True
|
||||
|
||||
@decorators.idempotent_id('05c4e3b3-7319-4052-90ad-e8916436c23b')
|
||||
def test_east_west(self):
|
||||
self._test_east_west()
|
||||
|
||||
|
||||
class FloatingIpSeparateNetwork(FloatingIpTestCasesMixin,
|
||||
base.BaseTempestTestCase):
|
||||
scenarios = multiply_scenarios([
|
||||
('SRC with FIP', dict(src_has_fip=True)),
|
||||
('SRC without FIP', dict(src_has_fip=False)),
|
||||
], [
|
||||
('DEST with FIP', dict(dest_has_fip=True)),
|
||||
('DEST without FIP', dict(dest_has_fip=False)),
|
||||
])
|
||||
|
||||
same_network = False
|
||||
|
||||
@decorators.idempotent_id('f18f0090-3289-4783-b956-a0f8ac511e8b')
|
||||
def test_east_west(self):
|
||||
self._test_east_west()
|
@ -1,200 +0,0 @@
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import functools
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.common import utils as common_utils
|
||||
from neutron.tests.tempest.scenario import base
|
||||
from neutron.tests.tempest.scenario import test_dvr
|
||||
from neutron_lib.api.definitions import portbindings as pb
|
||||
from neutron_lib import constants as const
|
||||
|
||||
|
||||
class NetworkMigrationTestBase(base.BaseTempestTestCase,
|
||||
test_dvr.NetworkTestMixin):
|
||||
credentials = ['primary', 'admin']
|
||||
force_tenant_isolation = False
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension="dvr", service="network")
|
||||
@utils.requires_ext(extension="l3-ha", service="network")
|
||||
def skip_checks(cls):
|
||||
super(NetworkMigrationTestBase, cls).skip_checks()
|
||||
|
||||
def _check_update(self, router, is_dvr, is_ha):
|
||||
router = self.os_admin.network_client.show_router(router['id'])
|
||||
self.assertEqual(is_dvr, router['router']['distributed'])
|
||||
self.assertEqual(is_ha, router['router']['ha'])
|
||||
|
||||
def _wait_until_port_deleted(self, router_id, device_owner):
|
||||
common_utils.wait_until_true(
|
||||
functools.partial(
|
||||
self._is_port_deleted,
|
||||
router_id,
|
||||
device_owner),
|
||||
timeout=300, sleep=5)
|
||||
|
||||
def _is_port_deleted(self, router_id, device_owner):
|
||||
ports = self.os_admin.network_client.list_ports(
|
||||
device_id=router_id,
|
||||
device_owner=device_owner)
|
||||
return not ports.get('ports')
|
||||
|
||||
def _wait_until_port_ready(self, router_id, device_owner):
|
||||
common_utils.wait_until_true(
|
||||
functools.partial(
|
||||
self._is_port_active,
|
||||
router_id,
|
||||
device_owner),
|
||||
timeout=300, sleep=5)
|
||||
|
||||
def _is_port_active(self, router_id, device_owner):
|
||||
ports = self.os_admin.network_client.list_ports(
|
||||
device_id=router_id,
|
||||
device_owner=device_owner,
|
||||
status=const.ACTIVE).get('ports')
|
||||
if ports:
|
||||
if ports[0][pb.VIF_TYPE] not in [pb.VIF_TYPE_UNBOUND,
|
||||
pb.VIF_TYPE_BINDING_FAILED]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _wait_until_router_ports_ready(self, router_id, dvr, ha):
|
||||
if dvr:
|
||||
self._wait_until_port_ready(
|
||||
router_id, const.DEVICE_OWNER_DVR_INTERFACE)
|
||||
if ha:
|
||||
self._wait_until_port_ready(
|
||||
router_id, const.DEVICE_OWNER_ROUTER_HA_INTF)
|
||||
if dvr:
|
||||
self._wait_until_port_ready(
|
||||
router_id, const.DEVICE_OWNER_ROUTER_SNAT)
|
||||
else:
|
||||
self._wait_until_port_ready(
|
||||
router_id, const.DEVICE_OWNER_HA_REPLICATED_INT)
|
||||
self._wait_until_port_ready(
|
||||
router_id, const.DEVICE_OWNER_ROUTER_GW)
|
||||
|
||||
def _wait_until_router_ports_migrated(
|
||||
self, router_id, before_dvr, before_ha, after_dvr, after_ha):
|
||||
if before_ha and not after_ha:
|
||||
self._wait_until_port_deleted(
|
||||
router_id, const.DEVICE_OWNER_ROUTER_HA_INTF)
|
||||
self._wait_until_port_deleted(
|
||||
router_id, const.DEVICE_OWNER_HA_REPLICATED_INT)
|
||||
if before_dvr and not after_dvr:
|
||||
self._wait_until_port_deleted(
|
||||
router_id, const.DEVICE_OWNER_DVR_INTERFACE)
|
||||
self._wait_until_port_deleted(
|
||||
router_id, const.DEVICE_OWNER_ROUTER_SNAT)
|
||||
self._wait_until_router_ports_ready(router_id, after_dvr, after_ha)
|
||||
|
||||
def _test_migration(self, before_dvr, before_ha, after_dvr, after_ha):
|
||||
router = self.create_router_by_client(
|
||||
distributed=before_dvr, ha=before_ha,
|
||||
tenant_id=self.client.tenant_id, is_admin=True)
|
||||
|
||||
self.setup_network_and_server(router=router)
|
||||
self._wait_until_router_ports_ready(
|
||||
router['id'], before_dvr, before_ha)
|
||||
self._check_connectivity()
|
||||
|
||||
self.os_admin.network_client.update_router(
|
||||
router_id=router['id'], admin_state_up=False)
|
||||
self.os_admin.network_client.update_router(
|
||||
router_id=router['id'], distributed=after_dvr, ha=after_ha)
|
||||
self._check_update(router, after_dvr, after_ha)
|
||||
|
||||
self.os_admin.network_client.update_router(
|
||||
router_id=router['id'], admin_state_up=True)
|
||||
|
||||
self._wait_until_router_ports_migrated(
|
||||
router['id'], before_dvr, before_ha, after_dvr, after_ha)
|
||||
self._check_connectivity()
|
||||
|
||||
|
||||
class NetworkMigrationFromLegacy(NetworkMigrationTestBase):
|
||||
|
||||
@decorators.idempotent_id('23724222-483a-4129-bc15-7a9278f3828b')
|
||||
def test_from_legacy_to_dvr(self):
|
||||
self._test_migration(before_dvr=False, before_ha=False,
|
||||
after_dvr=True, after_ha=False)
|
||||
|
||||
@decorators.idempotent_id('09d85102-994f-4ff9-bf3e-17051145ca12')
|
||||
def test_from_legacy_to_ha(self):
|
||||
self._test_migration(before_dvr=False, before_ha=False,
|
||||
after_dvr=False, after_ha=True)
|
||||
|
||||
@decorators.idempotent_id('fe169f2c-6ed3-4eb0-8afe-2d540c4b49e2')
|
||||
def test_from_legacy_to_dvr_ha(self):
|
||||
self._test_migration(before_dvr=False, before_ha=False,
|
||||
after_dvr=True, after_ha=True)
|
||||
|
||||
|
||||
class NetworkMigrationFromHA(NetworkMigrationTestBase):
|
||||
|
||||
@decorators.idempotent_id('b4e68ac0-3b76-4306-ae8a-51cf4d363b22')
|
||||
def test_from_ha_to_legacy(self):
|
||||
self._test_migration(before_dvr=False, before_ha=True,
|
||||
after_dvr=False, after_ha=False)
|
||||
|
||||
@decorators.idempotent_id('42260eea-5d56-4d30-b62a-a62694dfe4d5')
|
||||
def test_from_ha_to_dvr(self):
|
||||
self._test_migration(before_dvr=False, before_ha=True,
|
||||
after_dvr=True, after_ha=False)
|
||||
|
||||
@decorators.idempotent_id('e4149576-248b-43fa-9d0b-a5c2f51967ce')
|
||||
def test_from_ha_to_dvr_ha(self):
|
||||
self._test_migration(before_dvr=False, before_ha=True,
|
||||
after_dvr=True, after_ha=True)
|
||||
|
||||
|
||||
class NetworkMigrationFromDVR(NetworkMigrationTestBase):
|
||||
|
||||
@decorators.idempotent_id('e5cac02c-248d-4aac-bd5e-9d47c5197307')
|
||||
def test_from_dvr_to_legacy(self):
|
||||
self._test_migration(before_dvr=True, before_ha=False,
|
||||
after_dvr=False, after_ha=False)
|
||||
|
||||
@decorators.idempotent_id('a00d5ad7-8509-4bb0-bdd2-7f1ee052d1cd')
|
||||
def test_from_dvr_to_ha(self):
|
||||
self._test_migration(before_dvr=True, before_ha=False,
|
||||
after_dvr=False, after_ha=True)
|
||||
|
||||
@decorators.idempotent_id('25304a51-93a8-4cf3-9523-bce8b4eaecf8')
|
||||
def test_from_dvr_to_dvr_ha(self):
|
||||
self._test_migration(before_dvr=True, before_ha=False,
|
||||
after_dvr=True, after_ha=True)
|
||||
|
||||
|
||||
class NetworkMigrationFromDVRHA(NetworkMigrationTestBase):
|
||||
|
||||
@decorators.idempotent_id('1be9b2e2-379c-40a4-a269-6687b81df691')
|
||||
def test_from_dvr_ha_to_legacy(self):
|
||||
self._test_migration(before_dvr=True, before_ha=True,
|
||||
after_dvr=False, after_ha=False)
|
||||
|
||||
@decorators.idempotent_id('55957267-4e84-4314-a2f7-7cd36a2df04b')
|
||||
def test_from_dvr_ha_to_ha(self):
|
||||
self._test_migration(before_dvr=True, before_ha=True,
|
||||
after_dvr=False, after_ha=True)
|
||||
|
||||
@decorators.idempotent_id('d6bedff1-72be-4a9a-8ea2-dc037cd838e0')
|
||||
def test_from_dvr_ha_to_dvr(self):
|
||||
self._test_migration(before_dvr=True, before_ha=True,
|
||||
after_dvr=True, after_ha=False)
|
@ -1,134 +0,0 @@
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import netaddr
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest.common import waiters
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.common import ssh
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
from neutron.tests.tempest.scenario import constants
|
||||
from neutron_lib.api.definitions import provider_net
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class NetworkMtuBaseTest(base.BaseTempestTestCase):
|
||||
credentials = ['primary', 'admin']
|
||||
servers = []
|
||||
networks = []
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(NetworkMtuBaseTest, cls).skip_checks()
|
||||
if ("vxlan" not in
|
||||
config.CONF.neutron_plugin_options.available_type_drivers
|
||||
or "gre" not in
|
||||
config.CONF.neutron_plugin_options.available_type_drivers):
|
||||
raise cls.skipException("GRE or VXLAN type_driver is not enabled")
|
||||
|
||||
@classmethod
|
||||
@utils.requires_ext(extension=provider_net.ALIAS, service="network")
|
||||
def resource_setup(cls):
|
||||
super(NetworkMtuBaseTest, cls).resource_setup()
|
||||
# setup basic topology for servers we can log into it
|
||||
cls.router = cls.create_router_by_client()
|
||||
cls.keypair = cls.create_keypair()
|
||||
cls.secgroup = cls.os_primary.network_client.create_security_group(
|
||||
name='secgroup_mtu')
|
||||
cls.security_groups.append(cls.secgroup['security_group'])
|
||||
cls.create_loginable_secgroup_rule(
|
||||
secgroup_id=cls.secgroup['security_group']['id'])
|
||||
cls.create_pingable_secgroup_rule(
|
||||
secgroup_id=cls.secgroup['security_group']['id'])
|
||||
|
||||
def _create_setup(self):
|
||||
self.admin_client = self.os_admin.network_client
|
||||
net_kwargs = {'tenant_id': self.client.tenant_id}
|
||||
for sub, net_type in (
|
||||
('10.100.0.0/16', 'vxlan'), ('10.200.0.0/16', 'gre')):
|
||||
net_kwargs['name'] = '-'.join([net_type, 'net'])
|
||||
net_kwargs['provider:network_type'] = net_type
|
||||
network = self.admin_client.create_network(**net_kwargs)[
|
||||
'network']
|
||||
self.networks.append(network)
|
||||
self.addCleanup(self.admin_client.delete_network, network['id'])
|
||||
cidr = netaddr.IPNetwork(sub)
|
||||
subnet = self.create_subnet(network, cidr=cidr)
|
||||
self.create_router_interface(self.router['id'], subnet['id'])
|
||||
self.addCleanup(self.client.remove_router_interface_with_subnet_id,
|
||||
self.router['id'], subnet['id'])
|
||||
# check that MTUs are different for 2 networks
|
||||
self.assertNotEqual(self.networks[0]['mtu'], self.networks[1]['mtu'])
|
||||
self.networks.sort(key=lambda net: net['mtu'])
|
||||
server1, fip1 = self.create_pingable_vm(self.networks[0])
|
||||
server_ssh_client1 = ssh.Client(
|
||||
self.floating_ips[0]['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
pkey=self.keypair['private_key'])
|
||||
server2, fip2 = self.create_pingable_vm(self.networks[1])
|
||||
server_ssh_client2 = ssh.Client(
|
||||
self.floating_ips[0]['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
pkey=self.keypair['private_key'])
|
||||
for fip in (fip1, fip2):
|
||||
self.check_connectivity(fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
return server_ssh_client1, fip1, server_ssh_client2, fip2
|
||||
|
||||
def create_pingable_vm(self, net):
|
||||
server = self.create_server(
|
||||
flavor_ref=CONF.compute.flavor_ref,
|
||||
image_ref=CONF.compute.image_ref,
|
||||
key_name=self.keypair['name'],
|
||||
networks=[{'uuid': net['id']}],
|
||||
security_groups=[{'name': self.secgroup[
|
||||
'security_group']['name']}])
|
||||
waiters.wait_for_server_status(
|
||||
self.os_primary.servers_client, server['server']['id'],
|
||||
constants.SERVER_STATUS_ACTIVE)
|
||||
port = self.client.list_ports(
|
||||
network_id=net['id'], device_id=server['server']['id'])['ports'][0]
|
||||
fip = self.create_and_associate_floatingip(port['id'])
|
||||
return server, fip
|
||||
|
||||
@decorators.idempotent_id('3d73ec1a-2ec6-45a9-b0f8-04a273d9d344')
|
||||
def test_connectivity_min_max_mtu(self):
|
||||
server_ssh_client, _, _, fip2 = self._create_setup()
|
||||
# ping with min mtu of 2 networks succeeds even when
|
||||
# fragmentation is disabled
|
||||
self.check_remote_connectivity(
|
||||
server_ssh_client, fip2['fixed_ip_address'],
|
||||
mtu=self.networks[0]['mtu'], fragmentation=False)
|
||||
|
||||
# ping with the size above min mtu of 2 networks
|
||||
# fails when fragmentation is disabled
|
||||
self.check_remote_connectivity(
|
||||
server_ssh_client, fip2['fixed_ip_address'], should_succeed=False,
|
||||
mtu=self.networks[0]['mtu'] + 1, fragmentation=False)
|
||||
|
||||
# ping with max mtu of 2 networks succeeds when
|
||||
# fragmentation is enabled
|
||||
self.check_remote_connectivity(
|
||||
server_ssh_client, fip2['fixed_ip_address'],
|
||||
mtu=self.networks[1]['mtu'])
|
||||
|
||||
# ping with max mtu of 2 networks fails when fragmentation is disabled
|
||||
self.check_remote_connectivity(
|
||||
server_ssh_client, fip2['fixed_ip_address'], should_succeed=False,
|
||||
mtu=self.networks[1]['mtu'], fragmentation=False)
|
@ -1,53 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class PortSecurityTest(base.BaseTempestTestCase):
|
||||
credentials = ['primary']
|
||||
required_extensions = ['port-security']
|
||||
|
||||
@decorators.idempotent_id('61ab176e-d48b-42b7-b38a-1ba571ecc033')
|
||||
def test_port_security_removed_added(self):
|
||||
"""Test connection works after port security has been removed
|
||||
|
||||
Initial test that vm is accessible. Then port security is removed,
|
||||
checked connectivity. Port security is added back and checked
|
||||
connectivity again.
|
||||
"""
|
||||
self.setup_network_and_server()
|
||||
self.check_connectivity(self.fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
sec_group_id = self.security_groups[0]['id']
|
||||
|
||||
self.port = self.update_port(port=self.port,
|
||||
port_security_enabled=False,
|
||||
security_groups=[])
|
||||
self.check_connectivity(self.fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
self.port = self.update_port(port=self.port,
|
||||
port_security_enabled=True,
|
||||
security_groups=[sec_group_id])
|
||||
self.check_connectivity(self.fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
@ -1,175 +0,0 @@
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import errno
|
||||
import socket
|
||||
import time
|
||||
|
||||
from neutron_lib.services.qos import constants as qos_consts
|
||||
from oslo_log import log as logging
|
||||
from tempest.common import utils as tutils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from neutron.common import utils
|
||||
from neutron.tests.tempest.api import base as base_api
|
||||
from neutron.tests.tempest.common import ssh
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
from neutron.tests.tempest.scenario import constants
|
||||
from neutron.tests.tempest.scenario import exceptions as sc_exceptions
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _try_connect(host_ip, port):
|
||||
try:
|
||||
client_socket = socket.socket(socket.AF_INET,
|
||||
socket.SOCK_STREAM)
|
||||
client_socket.connect((host_ip, port))
|
||||
return client_socket
|
||||
except socket.error as serr:
|
||||
if serr.errno == errno.ECONNREFUSED:
|
||||
raise sc_exceptions.SocketConnectionRefused(host=host_ip,
|
||||
port=port)
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def _connect_socket(host, port):
|
||||
"""Try to initiate a connection to a host using an ip address
|
||||
and a port.
|
||||
|
||||
Trying couple of times until a timeout is reached in case the listening
|
||||
host is not ready yet.
|
||||
"""
|
||||
|
||||
start = time.time()
|
||||
while True:
|
||||
try:
|
||||
return _try_connect(host, port)
|
||||
except sc_exceptions.SocketConnectionRefused:
|
||||
if time.time() - start > constants.SOCKET_CONNECT_TIMEOUT:
|
||||
raise sc_exceptions.ConnectionTimeoutException(host=host,
|
||||
port=port)
|
||||
|
||||
|
||||
class QoSTest(base.BaseTempestTestCase):
|
||||
credentials = ['primary', 'admin']
|
||||
force_tenant_isolation = False
|
||||
|
||||
BUFFER_SIZE = 1024 * 1024
|
||||
TOLERANCE_FACTOR = 1.5
|
||||
BS = 512
|
||||
COUNT = BUFFER_SIZE / BS
|
||||
FILE_SIZE = BS * COUNT
|
||||
LIMIT_BYTES_SEC = (constants.LIMIT_KILO_BITS_PER_SECOND * 1024
|
||||
* TOLERANCE_FACTOR / 8.0)
|
||||
FILE_PATH = "/tmp/img"
|
||||
|
||||
@classmethod
|
||||
@tutils.requires_ext(extension="qos", service="network")
|
||||
@base_api.require_qos_rule_type(qos_consts.RULE_TYPE_BANDWIDTH_LIMIT)
|
||||
def resource_setup(cls):
|
||||
super(QoSTest, cls).resource_setup()
|
||||
|
||||
def _create_file_for_bw_tests(self, ssh_client):
|
||||
cmd = ("(dd if=/dev/zero bs=%(bs)d count=%(count)d of=%(file_path)s) "
|
||||
% {'bs': QoSTest.BS, 'count': QoSTest.COUNT,
|
||||
'file_path': QoSTest.FILE_PATH})
|
||||
ssh_client.exec_command(cmd)
|
||||
cmd = "stat -c %%s %s" % QoSTest.FILE_PATH
|
||||
filesize = ssh_client.exec_command(cmd)
|
||||
if int(filesize.strip()) != QoSTest.FILE_SIZE:
|
||||
raise sc_exceptions.FileCreationFailedException(
|
||||
file=QoSTest.FILE_PATH)
|
||||
|
||||
def _check_bw(self, ssh_client, host, port):
|
||||
cmd = "killall -q nc"
|
||||
try:
|
||||
ssh_client.exec_command(cmd)
|
||||
except exceptions.SSHExecCommandFailed:
|
||||
pass
|
||||
cmd = ("(nc -ll -p %(port)d < %(file_path)s > /dev/null &)" % {
|
||||
'port': port, 'file_path': QoSTest.FILE_PATH})
|
||||
ssh_client.exec_command(cmd)
|
||||
|
||||
start_time = time.time()
|
||||
client_socket = _connect_socket(host, port)
|
||||
total_bytes_read = 0
|
||||
|
||||
while total_bytes_read < QoSTest.FILE_SIZE:
|
||||
data = client_socket.recv(QoSTest.BUFFER_SIZE)
|
||||
total_bytes_read += len(data)
|
||||
|
||||
time_elapsed = time.time() - start_time
|
||||
bytes_per_second = total_bytes_read / time_elapsed
|
||||
|
||||
LOG.debug("time_elapsed = %(time_elapsed)d, "
|
||||
"total_bytes_read = %(total_bytes_read)d, "
|
||||
"bytes_per_second = %(bytes_per_second)d",
|
||||
{'time_elapsed': time_elapsed,
|
||||
'total_bytes_read': total_bytes_read,
|
||||
'bytes_per_second': bytes_per_second})
|
||||
|
||||
return bytes_per_second <= QoSTest.LIMIT_BYTES_SEC
|
||||
|
||||
@decorators.idempotent_id('1f7ed39b-428f-410a-bd2b-db9f465680df')
|
||||
def test_qos(self):
|
||||
"""This is a basic test that check that a QoS policy with
|
||||
|
||||
a bandwidth limit rule is applied correctly by sending
|
||||
a file from the instance to the test node.
|
||||
Then calculating the bandwidth every ~1 sec by the number of bits
|
||||
received / elapsed time.
|
||||
"""
|
||||
|
||||
NC_PORT = 1234
|
||||
|
||||
self.setup_network_and_server()
|
||||
self.check_connectivity(self.fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
rulesets = [{'protocol': 'tcp',
|
||||
'direction': 'ingress',
|
||||
'port_range_min': NC_PORT,
|
||||
'port_range_max': NC_PORT,
|
||||
'remote_ip_prefix': '0.0.0.0/0'}]
|
||||
self.create_secgroup_rules(rulesets,
|
||||
self.security_groups[-1]['id'])
|
||||
|
||||
ssh_client = ssh.Client(self.fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
pkey=self.keypair['private_key'])
|
||||
policy = self.os_admin.network_client.create_qos_policy(
|
||||
name='test-policy',
|
||||
description='test-qos-policy',
|
||||
shared=True)
|
||||
policy_id = policy['policy']['id']
|
||||
self.os_admin.network_client.create_bandwidth_limit_rule(
|
||||
policy_id, max_kbps=constants.LIMIT_KILO_BITS_PER_SECOND,
|
||||
max_burst_kbps=constants.LIMIT_KILO_BITS_PER_SECOND)
|
||||
port = self.client.list_ports(network_id=self.network['id'],
|
||||
device_id=self.server[
|
||||
'server']['id'])['ports'][0]
|
||||
self.os_admin.network_client.update_port(port['id'],
|
||||
qos_policy_id=policy_id)
|
||||
self._create_file_for_bw_tests(ssh_client)
|
||||
utils.wait_until_true(lambda: self._check_bw(
|
||||
ssh_client,
|
||||
self.fip['floating_ip_address'],
|
||||
port=NC_PORT),
|
||||
timeout=120,
|
||||
sleep=1)
|
@ -1,200 +0,0 @@
|
||||
# Copyright 2016 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from neutron_lib import constants
|
||||
|
||||
from tempest.common import waiters
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.common import ssh
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
from neutron.tests.tempest.scenario import constants as const
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class NetworkDefaultSecGroupTest(base.BaseTempestTestCase):
|
||||
credentials = ['primary', 'admin']
|
||||
required_extensions = ['router', 'security-group']
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(NetworkDefaultSecGroupTest, cls).resource_setup()
|
||||
# setup basic topology for servers we can log into it
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
router = cls.create_router_by_client()
|
||||
cls.create_router_interface(router['id'], cls.subnet['id'])
|
||||
cls.keypair = cls.create_keypair()
|
||||
|
||||
def create_vm_testing_sec_grp(self, num_servers=2, security_groups=None):
|
||||
servers, fips, server_ssh_clients = ([], [], [])
|
||||
for i in range(num_servers):
|
||||
servers.append(self.create_server(
|
||||
flavor_ref=CONF.compute.flavor_ref,
|
||||
image_ref=CONF.compute.image_ref,
|
||||
key_name=self.keypair['name'],
|
||||
networks=[{'uuid': self.network['id']}],
|
||||
security_groups=security_groups))
|
||||
for i, server in enumerate(servers):
|
||||
waiters.wait_for_server_status(
|
||||
self.os_primary.servers_client, server['server']['id'],
|
||||
const.SERVER_STATUS_ACTIVE)
|
||||
port = self.client.list_ports(
|
||||
network_id=self.network['id'], device_id=server['server'][
|
||||
'id'])['ports'][0]
|
||||
fips.append(self.create_and_associate_floatingip(port['id']))
|
||||
server_ssh_clients.append(ssh.Client(
|
||||
fips[i]['floating_ip_address'], CONF.validation.image_ssh_user,
|
||||
pkey=self.keypair['private_key']))
|
||||
return server_ssh_clients, fips, servers
|
||||
|
||||
@decorators.idempotent_id('3d73ec1a-2ec6-45a9-b0f8-04a283d9d764')
|
||||
def test_default_sec_grp_scenarios(self):
|
||||
server_ssh_clients, fips, _ = self.create_vm_testing_sec_grp()
|
||||
# Check ssh connectivity when you add sec group rule, enabling ssh
|
||||
self.create_loginable_secgroup_rule(
|
||||
self.os_primary.network_client.list_security_groups()[
|
||||
'security_groups'][0]['id']
|
||||
)
|
||||
self.check_connectivity(fips[0]['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
# make sure ICMP connectivity still fails as only ssh rule was added
|
||||
self.ping_ip_address(fips[0]['floating_ip_address'],
|
||||
should_succeed=False)
|
||||
|
||||
# Check ICMP connectivity between VMs without specific rule for that
|
||||
# It should work though the rule is not configured
|
||||
self.check_remote_connectivity(
|
||||
server_ssh_clients[0], fips[1]['fixed_ip_address'])
|
||||
|
||||
# Check ICMP connectivity from VM to external network
|
||||
subnets = self.os_admin.network_client.list_subnets(
|
||||
network_id=CONF.network.public_network_id)['subnets']
|
||||
ext_net_ip = None
|
||||
for subnet in subnets:
|
||||
if subnet['ip_version'] == 4:
|
||||
ext_net_ip = subnet['gateway_ip']
|
||||
break
|
||||
self.assertTrue(ext_net_ip)
|
||||
self.check_remote_connectivity(server_ssh_clients[0], ext_net_ip)
|
||||
|
||||
@decorators.idempotent_id('3d73ec1a-2ec6-45a9-b0f8-04a283d9d864')
|
||||
def test_protocol_number_rule(self):
|
||||
# protocol number is added instead of str in security rule creation
|
||||
server_ssh_clients, fips, _ = self.create_vm_testing_sec_grp(
|
||||
num_servers=1)
|
||||
self.ping_ip_address(fips[0]['floating_ip_address'],
|
||||
should_succeed=False)
|
||||
rule_list = [{'protocol': constants.PROTO_NUM_ICMP,
|
||||
'direction': constants.INGRESS_DIRECTION,
|
||||
'remote_ip_prefix': '0.0.0.0/0'}]
|
||||
secgroup_id = self.os_primary.network_client.list_security_groups()[
|
||||
'security_groups'][0]['id']
|
||||
self.create_secgroup_rules(rule_list, secgroup_id=secgroup_id)
|
||||
self.ping_ip_address(fips[0]['floating_ip_address'])
|
||||
|
||||
@decorators.idempotent_id('3d73ec1a-2ec6-45a9-b0f8-04a283d9d964')
|
||||
def test_two_sec_groups(self):
|
||||
# add 2 sec groups to VM and test rules of both are working
|
||||
ssh_secgrp_name = data_utils.rand_name('ssh_secgrp')
|
||||
icmp_secgrp_name = data_utils.rand_name('icmp_secgrp')
|
||||
ssh_secgrp = self.os_primary.network_client.create_security_group(
|
||||
name=ssh_secgrp_name)
|
||||
self.create_loginable_secgroup_rule(
|
||||
secgroup_id=ssh_secgrp['security_group']['id'])
|
||||
icmp_secgrp = self.os_primary.network_client.create_security_group(
|
||||
name=icmp_secgrp_name)
|
||||
self.create_pingable_secgroup_rule(
|
||||
secgroup_id=icmp_secgrp['security_group']['id'])
|
||||
for sec_grp in (ssh_secgrp, icmp_secgrp):
|
||||
self.security_groups.append(sec_grp['security_group'])
|
||||
security_groups_list = [{'name': ssh_secgrp_name},
|
||||
{'name': icmp_secgrp_name}]
|
||||
server_ssh_clients, fips, servers = self.create_vm_testing_sec_grp(
|
||||
num_servers=1, security_groups=security_groups_list)
|
||||
# make sure ssh connectivity works
|
||||
self.check_connectivity(fips[0]['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
# make sure ICMP connectivity works
|
||||
self.ping_ip_address(fips[0]['floating_ip_address'],
|
||||
should_succeed=True)
|
||||
ports = self.client.list_ports(device_id=servers[0]['server']['id'])
|
||||
port_id = ports['ports'][0]['id']
|
||||
|
||||
# update port with ssh security group only
|
||||
self.os_primary.network_client.update_port(
|
||||
port_id, security_groups=[ssh_secgrp['security_group']['id']])
|
||||
|
||||
# make sure ssh connectivity works
|
||||
self.check_connectivity(fips[0]['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
# make sure ICMP connectivity doesn't work
|
||||
self.ping_ip_address(fips[0]['floating_ip_address'],
|
||||
should_succeed=False)
|
||||
|
||||
# update port with ssh and ICMP security groups
|
||||
self.os_primary.network_client.update_port(
|
||||
port_id, security_groups=[
|
||||
icmp_secgrp['security_group']['id'],
|
||||
ssh_secgrp['security_group']['id']])
|
||||
|
||||
# make sure ssh connectivity works after update
|
||||
self.check_connectivity(fips[0]['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
# make sure ICMP connectivity works after update
|
||||
self.ping_ip_address(fips[0]['floating_ip_address'])
|
||||
|
||||
@decorators.idempotent_id('3d73ec1a-2ec6-45a9-b0f8-04a283d9d664')
|
||||
def test_ip_prefix(self):
|
||||
# Add specific remote prefix to VMs and check connectivity
|
||||
ssh_secgrp_name = data_utils.rand_name('ssh_secgrp')
|
||||
icmp_secgrp_name = data_utils.rand_name('icmp_secgrp_with_cidr')
|
||||
cidr = self.subnet['cidr']
|
||||
ssh_secgrp = self.os_primary.network_client.create_security_group(
|
||||
name=ssh_secgrp_name)
|
||||
self.create_loginable_secgroup_rule(
|
||||
secgroup_id=ssh_secgrp['security_group']['id'])
|
||||
|
||||
rule_list = [{'protocol': constants.PROTO_NUM_ICMP,
|
||||
'direction': constants.INGRESS_DIRECTION,
|
||||
'remote_ip_prefix': cidr}]
|
||||
icmp_secgrp = self.os_primary.network_client.create_security_group(
|
||||
name=icmp_secgrp_name)
|
||||
self.create_secgroup_rules(
|
||||
rule_list, secgroup_id=icmp_secgrp['security_group']['id'])
|
||||
for sec_grp in (ssh_secgrp, icmp_secgrp):
|
||||
self.security_groups.append(sec_grp['security_group'])
|
||||
security_groups_list = [{'name': ssh_secgrp_name},
|
||||
{'name': icmp_secgrp_name}]
|
||||
server_ssh_clients, fips, servers = self.create_vm_testing_sec_grp(
|
||||
security_groups=security_groups_list)
|
||||
|
||||
# make sure ssh connectivity works
|
||||
self.check_connectivity(fips[0]['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
# make sure ICMP connectivity works
|
||||
self.check_remote_connectivity(server_ssh_clients[0], fips[1][
|
||||
'fixed_ip_address'])
|
@ -1,266 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from oslo_log import log as logging
|
||||
from tempest.common import utils as tutils
|
||||
from tempest.common import waiters
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
import testtools
|
||||
|
||||
from neutron.common import utils
|
||||
from neutron.tests.tempest.common import ssh
|
||||
from neutron.tests.tempest import config
|
||||
from neutron.tests.tempest.scenario import base
|
||||
from neutron.tests.tempest.scenario import constants
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = config.CONF
|
||||
|
||||
CONFIGURE_VLAN_INTERFACE_COMMANDS = (
|
||||
'IFACE=$(PATH=$PATH:/usr/sbin ip l | grep "^[0-9]*: e" |'
|
||||
'cut -d \: -f 2) && '
|
||||
'sudo su -c '
|
||||
'"ip l a link $IFACE name $IFACE.%(tag)d type vlan id %(tag)d &&'
|
||||
'ip l s up dev $IFACE.%(tag)d && '
|
||||
'dhclient $IFACE.%(tag)d"')
|
||||
|
||||
|
||||
def get_next_subnet(cidr):
|
||||
return netaddr.IPNetwork(cidr).next()
|
||||
|
||||
|
||||
class TrunkTest(base.BaseTempestTestCase):
|
||||
credentials = ['primary']
|
||||
force_tenant_isolation = False
|
||||
|
||||
@classmethod
|
||||
@tutils.requires_ext(extension="trunk", service="network")
|
||||
def resource_setup(cls):
|
||||
super(TrunkTest, cls).resource_setup()
|
||||
# setup basic topology for servers we can log into
|
||||
cls.network = cls.create_network()
|
||||
cls.subnet = cls.create_subnet(cls.network)
|
||||
router = cls.create_router_by_client()
|
||||
cls.create_router_interface(router['id'], cls.subnet['id'])
|
||||
cls.keypair = cls.create_keypair()
|
||||
cls.secgroup = cls.os_primary.network_client.create_security_group(
|
||||
name=data_utils.rand_name('secgroup'))
|
||||
cls.security_groups.append(cls.secgroup['security_group'])
|
||||
cls.create_loginable_secgroup_rule(
|
||||
secgroup_id=cls.secgroup['security_group']['id'])
|
||||
|
||||
def _create_server_with_trunk_port(self):
|
||||
port = self.create_port(self.network, security_groups=[
|
||||
self.secgroup['security_group']['id']])
|
||||
trunk = self.client.create_trunk(port['id'], subports=[])['trunk']
|
||||
server, fip = self._create_server_with_fip(port['id'])
|
||||
self.addCleanup(self._detach_and_delete_trunk, server, trunk)
|
||||
return {'port': port, 'trunk': trunk, 'fip': fip,
|
||||
'server': server}
|
||||
|
||||
def _create_server_with_fip(self, port_id, **server_kwargs):
|
||||
fip = self.create_and_associate_floatingip(port_id)
|
||||
return (
|
||||
self.create_server(
|
||||
flavor_ref=CONF.compute.flavor_ref,
|
||||
image_ref=CONF.compute.image_ref,
|
||||
key_name=self.keypair['name'],
|
||||
networks=[{'port': port_id}],
|
||||
security_groups=[{'name': self.secgroup[
|
||||
'security_group']['name']}],
|
||||
**server_kwargs)['server'],
|
||||
fip)
|
||||
|
||||
def _detach_and_delete_trunk(self, server, trunk):
|
||||
# we have to detach the interface from the server before
|
||||
# the trunk can be deleted.
|
||||
self.os_primary.compute.InterfacesClient().delete_interface(
|
||||
server['id'], trunk['port_id'])
|
||||
|
||||
def is_port_detached():
|
||||
p = self.client.show_port(trunk['port_id'])['port']
|
||||
return p['device_id'] == ''
|
||||
utils.wait_until_true(is_port_detached)
|
||||
self.client.delete_trunk(trunk['id'])
|
||||
|
||||
def _is_port_down(self, port_id):
|
||||
p = self.client.show_port(port_id)['port']
|
||||
return p['status'] == 'DOWN'
|
||||
|
||||
def _is_port_active(self, port_id):
|
||||
p = self.client.show_port(port_id)['port']
|
||||
return p['status'] == 'ACTIVE'
|
||||
|
||||
def _is_trunk_active(self, trunk_id):
|
||||
t = self.client.show_trunk(trunk_id)['trunk']
|
||||
return t['status'] == 'ACTIVE'
|
||||
|
||||
def _create_server_with_port_and_subport(self, vlan_network, vlan_tag):
|
||||
parent_port = self.create_port(self.network, security_groups=[
|
||||
self.secgroup['security_group']['id']])
|
||||
port_for_subport = self.create_port(
|
||||
vlan_network,
|
||||
security_groups=[self.secgroup['security_group']['id']],
|
||||
mac_address=parent_port['mac_address'])
|
||||
subport = {
|
||||
'port_id': port_for_subport['id'],
|
||||
'segmentation_type': 'vlan',
|
||||
'segmentation_id': vlan_tag}
|
||||
trunk = self.client.create_trunk(
|
||||
parent_port['id'], subports=[subport])['trunk']
|
||||
|
||||
server, fip = self._create_server_with_fip(parent_port['id'])
|
||||
self.addCleanup(self._detach_and_delete_trunk, server, trunk)
|
||||
|
||||
server_ssh_client = ssh.Client(
|
||||
fip['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
pkey=self.keypair['private_key'])
|
||||
|
||||
return {
|
||||
'server': server,
|
||||
'fip': fip,
|
||||
'ssh_client': server_ssh_client,
|
||||
'subport': port_for_subport,
|
||||
}
|
||||
|
||||
def _wait_for_server(self, server):
|
||||
waiters.wait_for_server_status(self.os_primary.servers_client,
|
||||
server['server']['id'],
|
||||
constants.SERVER_STATUS_ACTIVE)
|
||||
self.check_connectivity(server['fip']['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
@decorators.idempotent_id('bb13fe28-f152-4000-8131-37890a40c79e')
|
||||
def test_trunk_subport_lifecycle(self):
|
||||
"""Test trunk creation and subport transition to ACTIVE status.
|
||||
|
||||
This is a basic test for the trunk extension to ensure that we
|
||||
can create a trunk, attach it to a server, add/remove subports,
|
||||
while ensuring the status transitions as appropriate.
|
||||
|
||||
This test does not assert any dataplane behavior for the subports.
|
||||
It's just a high-level check to ensure the agents claim to have
|
||||
wired the port correctly and that the trunk port itself maintains
|
||||
connectivity.
|
||||
"""
|
||||
server1 = self._create_server_with_trunk_port()
|
||||
server2 = self._create_server_with_trunk_port()
|
||||
for server in (server1, server2):
|
||||
self._wait_for_server(server)
|
||||
trunk1_id, trunk2_id = server1['trunk']['id'], server2['trunk']['id']
|
||||
# trunks should transition to ACTIVE without any subports
|
||||
utils.wait_until_true(
|
||||
lambda: self._is_trunk_active(trunk1_id),
|
||||
exception=RuntimeError("Timed out waiting for trunk %s to "
|
||||
"transition to ACTIVE." % trunk1_id))
|
||||
utils.wait_until_true(
|
||||
lambda: self._is_trunk_active(trunk2_id),
|
||||
exception=RuntimeError("Timed out waiting for trunk %s to "
|
||||
"transition to ACTIVE." % trunk2_id))
|
||||
# create a few more networks and ports for subports
|
||||
subports = [{'port_id': self.create_port(self.create_network())['id'],
|
||||
'segmentation_type': 'vlan', 'segmentation_id': seg_id}
|
||||
for seg_id in range(3, 7)]
|
||||
# add all subports to server1
|
||||
self.client.add_subports(trunk1_id, subports)
|
||||
# ensure trunk transitions to ACTIVE
|
||||
utils.wait_until_true(
|
||||
lambda: self._is_trunk_active(trunk1_id),
|
||||
exception=RuntimeError("Timed out waiting for trunk %s to "
|
||||
"transition to ACTIVE." % trunk1_id))
|
||||
# ensure all underlying subports transitioned to ACTIVE
|
||||
for s in subports:
|
||||
utils.wait_until_true(lambda: self._is_port_active(s['port_id']))
|
||||
# ensure main dataplane wasn't interrupted
|
||||
self.check_connectivity(server1['fip']['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
# move subports over to other server
|
||||
self.client.remove_subports(trunk1_id, subports)
|
||||
# ensure all subports go down
|
||||
for s in subports:
|
||||
utils.wait_until_true(
|
||||
lambda: self._is_port_down(s['port_id']),
|
||||
exception=RuntimeError("Timed out waiting for subport %s to "
|
||||
"transition to DOWN." % s['port_id']))
|
||||
self.client.add_subports(trunk2_id, subports)
|
||||
# wait for both trunks to go back to ACTIVE
|
||||
utils.wait_until_true(
|
||||
lambda: self._is_trunk_active(trunk1_id),
|
||||
exception=RuntimeError("Timed out waiting for trunk %s to "
|
||||
"transition to ACTIVE." % trunk1_id))
|
||||
utils.wait_until_true(
|
||||
lambda: self._is_trunk_active(trunk2_id),
|
||||
exception=RuntimeError("Timed out waiting for trunk %s to "
|
||||
"transition to ACTIVE." % trunk2_id))
|
||||
# ensure subports come up on other trunk
|
||||
for s in subports:
|
||||
utils.wait_until_true(
|
||||
lambda: self._is_port_active(s['port_id']),
|
||||
exception=RuntimeError("Timed out waiting for subport %s to "
|
||||
"transition to ACTIVE." % s['port_id']))
|
||||
# final connectivity check
|
||||
self.check_connectivity(server1['fip']['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
self.check_connectivity(server2['fip']['floating_ip_address'],
|
||||
CONF.validation.image_ssh_user,
|
||||
self.keypair['private_key'])
|
||||
|
||||
@testtools.skipUnless(
|
||||
CONF.neutron_plugin_options.image_is_advanced,
|
||||
"Advanced image is required to run this test.")
|
||||
@decorators.idempotent_id('a8a02c9b-b453-49b5-89a2-cce7da66aafb')
|
||||
def test_subport_connectivity(self):
|
||||
vlan_tag = 10
|
||||
|
||||
vlan_network = self.create_network()
|
||||
new_subnet_cidr = get_next_subnet(
|
||||
config.safe_get_config_value('network', 'project_network_cidr'))
|
||||
self.create_subnet(vlan_network, gateway=None, cidr=new_subnet_cidr)
|
||||
|
||||
servers = [
|
||||
self._create_server_with_port_and_subport(vlan_network, vlan_tag)
|
||||
for i in range(2)]
|
||||
|
||||
for server in servers:
|
||||
self._wait_for_server(server)
|
||||
# Configure VLAN interfaces on server
|
||||
command = CONFIGURE_VLAN_INTERFACE_COMMANDS % {'tag': vlan_tag}
|
||||
server['ssh_client'].exec_command(command)
|
||||
out = server['ssh_client'].exec_command(
|
||||
'PATH=$PATH:/usr/sbin;ip addr list')
|
||||
LOG.debug("Interfaces on server %s: %s", server, out)
|
||||
|
||||
# Ping from server1 to server2 via VLAN interface should fail because
|
||||
# we haven't allowed ICMP
|
||||
self.check_remote_connectivity(
|
||||
servers[0]['ssh_client'],
|
||||
servers[1]['subport']['fixed_ips'][0]['ip_address'],
|
||||
should_succeed=False
|
||||
)
|
||||
# allow intra-securitygroup traffic
|
||||
self.client.create_security_group_rule(
|
||||
security_group_id=self.secgroup['security_group']['id'],
|
||||
direction='ingress', ethertype='IPv4', protocol='icmp',
|
||||
remote_group_id=self.secgroup['security_group']['id'])
|
||||
self.check_remote_connectivity(
|
||||
servers[0]['ssh_client'],
|
||||
servers[1]['subport']['fixed_ips'][0]['ip_address'],
|
||||
should_succeed=True
|
||||
)
|
@ -158,8 +158,6 @@ neutron.agent.firewall_drivers =
|
||||
neutron.services.metering_drivers =
|
||||
noop = neutron.services.metering.drivers.noop.noop_driver:NoopMeteringDriver
|
||||
iptables = neutron.services.metering.iptables.iptables_driver:IptablesMeteringDriver
|
||||
tempest.test_plugins =
|
||||
neutron_tests = neutron.tests.tempest.plugin:NeutronTempestPlugin
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
|
@ -23,5 +23,4 @@ pylint==1.4.5 # GPLv2
|
||||
reno>=2.5.0 # Apache-2.0
|
||||
# Needed to run DB commands in virtualenvs
|
||||
PyMySQL>=0.7.6 # MIT License
|
||||
tempest>=17.1.0 # Apache-2.0
|
||||
bashate>=0.5.1 # Apache-2.0
|
||||
|
@ -57,22 +57,10 @@ check_identical_policy_files () {
|
||||
fi
|
||||
}
|
||||
|
||||
check_no_duplicate_api_test_idempotent_ids() {
|
||||
# For API tests, an idempotent ID is assigned to each single API test,
|
||||
# those IDs should be unique
|
||||
output=$(check-uuid --package neutron.tests.tempest)
|
||||
if [ "$?" -ne 0 ]; then
|
||||
echo "There are duplicate idempotent ids in the API tests" >>$FAILURES
|
||||
echo "please, assign unique uuids to each API test:" >>$FAILURES
|
||||
echo "$output" >>$FAILURES
|
||||
fi
|
||||
}
|
||||
|
||||
# Add your checks here...
|
||||
check_no_symlinks_allowed
|
||||
check_pot_files_errors
|
||||
check_identical_policy_files
|
||||
check_no_duplicate_api_test_idempotent_ids
|
||||
|
||||
# Fail, if there are emitted failures
|
||||
if [ -f $FAILURES ]; then
|
||||
|
Loading…
Reference in New Issue
Block a user