Merge "Remove the bundled intree neutron tempest plugin"
This commit is contained in:
commit
bb1c7f3d3d
|
@ -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