blob: 14267987eedc11702ee51e1f0c991e82c6dc83f5 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Jay Pipesf4dad392012-06-05 16:03:58 -04002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
Miguel Lavallecc939612013-02-22 17:27:20 -060015import netaddr
Matthew Treinish71426682015-04-23 11:19:38 -040016import six
Kevin Benton6919da42016-03-05 18:00:03 -080017import testtools
Jay Pipesf4dad392012-06-05 16:03:58 -040018
Sean Dague1937d092013-05-17 16:36:38 -040019from tempest.api.network import base
Rohan Kanade35589aa2014-08-19 14:56:12 +020020from tempest.common import custom_matchers
Fei Long Wangd39431f2015-05-14 11:30:48 +120021from tempest.common.utils import data_utils
Matthew Treinish03b48df2014-01-29 16:59:49 +000022from tempest import config
Jordan Pittier9e227c52016-02-09 14:35:18 +010023from tempest.lib.common.utils import test_utils
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -080024from tempest.lib import decorators
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050025from tempest.lib import exceptions as lib_exc
Masayuki Igawa6d495d62014-03-19 16:38:57 +090026from tempest import test
Unmesh Gurjar44986832012-05-08 19:57:10 +053027
Matthew Treinish03b48df2014-01-29 16:59:49 +000028CONF = config.CONF
29
Unmesh Gurjar44986832012-05-08 19:57:10 +053030
Jonte Watford871547c2016-10-10 20:11:04 +000031class BaseNetworkTestResources(base.BaseNetworkTest):
Miguel Lavallecc939612013-02-22 17:27:20 -060032
Unmesh Gurjar44986832012-05-08 19:57:10 +053033 @classmethod
Andrea Frittolida4a2452014-09-15 13:12:08 +010034 def resource_setup(cls):
Jonte Watford871547c2016-10-10 20:11:04 +000035 super(BaseNetworkTestResources, cls).resource_setup()
Jay Pipesf4dad392012-06-05 16:03:58 -040036 cls.network = cls.create_network()
37 cls.name = cls.network['name']
venakata anil1a2a64a2014-12-02 07:25:59 +000038 cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
39 cls._ip_version)
Rohan Kanade35589aa2014-08-19 14:56:12 +020040 cls._subnet_data = {6: {'gateway':
41 str(cls._get_gateway_from_tempest_conf(6)),
42 'allocation_pools':
43 cls._get_allocation_pools_from_gateway(6),
44 'dns_nameservers': ['2001:4860:4860::8844',
45 '2001:4860:4860::8888'],
46 'host_routes': [{'destination': '2001::/64',
47 'nexthop': '2003::1'}],
48 'new_host_routes': [{'destination':
49 '2001::/64',
50 'nexthop': '2005::1'}],
51 'new_dns_nameservers':
52 ['2001:4860:4860::7744',
53 '2001:4860:4860::7888']},
54 4: {'gateway':
55 str(cls._get_gateway_from_tempest_conf(4)),
56 'allocation_pools':
57 cls._get_allocation_pools_from_gateway(4),
58 'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
59 'host_routes': [{'destination': '10.20.0.0/32',
60 'nexthop': '10.100.1.1'}],
61 'new_host_routes': [{'destination':
62 '10.20.0.0/32',
63 'nexthop':
64 '10.100.1.2'}],
65 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
66
67 @classmethod
venakata anil1a2a64a2014-12-02 07:25:59 +000068 def _create_subnet_with_last_subnet_block(cls, network, ip_version):
Sean Dagueed6e5862016-04-04 10:49:13 -040069 # Derive last subnet CIDR block from project CIDR and
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +000070 # create the subnet with that derived CIDR
venakata anil1a2a64a2014-12-02 07:25:59 +000071 if ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -040072 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
73 mask_bits = CONF.network.project_network_mask_bits
venakata anil1a2a64a2014-12-02 07:25:59 +000074 elif ip_version == 6:
Sean Dagueed6e5862016-04-04 10:49:13 -040075 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
76 mask_bits = CONF.network.project_network_v6_mask_bits
venakata anil1a2a64a2014-12-02 07:25:59 +000077
78 subnet_cidr = list(cidr.subnet(mask_bits))[-1]
79 gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
80 return cls.create_subnet(network, gateway=gateway_ip,
81 cidr=subnet_cidr, mask_bits=mask_bits)
82
83 @classmethod
Rohan Kanade35589aa2014-08-19 14:56:12 +020084 def _get_gateway_from_tempest_conf(cls, ip_version):
85 """Return first subnet gateway for configured CIDR """
86 if ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -040087 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
88 mask_bits = CONF.network.project_network_mask_bits
Rohan Kanade35589aa2014-08-19 14:56:12 +020089 elif ip_version == 6:
Sean Dagueed6e5862016-04-04 10:49:13 -040090 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
91 mask_bits = CONF.network.project_network_v6_mask_bits
Rohan Kanade35589aa2014-08-19 14:56:12 +020092
93 if mask_bits >= cidr.prefixlen:
94 return netaddr.IPAddress(cidr) + 1
95 else:
96 for subnet in cidr.subnet(mask_bits):
97 return netaddr.IPAddress(subnet) + 1
98
99 @classmethod
100 def _get_allocation_pools_from_gateway(cls, ip_version):
101 """Return allocation range for subnet of given gateway"""
102 gateway = cls._get_gateway_from_tempest_conf(ip_version)
Hynek Mlnarikbe634fc2016-06-27 09:34:15 +0200103 return [{'start': str(gateway + 2), 'end': str(gateway + 6)}]
Rohan Kanade35589aa2014-08-19 14:56:12 +0200104
105 def subnet_dict(self, include_keys):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000106 # Return a subnet dict which has include_keys and their corresponding
107 # value from self._subnet_data
Rohan Kanade35589aa2014-08-19 14:56:12 +0200108 return dict((key, self._subnet_data[self._ip_version][key])
109 for key in include_keys)
110
111 def _compare_resource_attrs(self, actual, expected):
112 exclude_keys = set(actual).symmetric_difference(expected)
113 self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
114 expected, exclude_keys))
115
venakata anil1a2a64a2014-12-02 07:25:59 +0000116 def _delete_network(self, network):
117 # Deleting network also deletes its subnets if exists
John Warren94d8faf2015-09-15 12:22:24 -0400118 self.networks_client.delete_network(network['id'])
venakata anil1a2a64a2014-12-02 07:25:59 +0000119 if network in self.networks:
120 self.networks.remove(network)
121 for subnet in self.subnets:
122 if subnet['network_id'] == network['id']:
123 self.subnets.remove(subnet)
124
Rohan Kanade35589aa2014-08-19 14:56:12 +0200125 def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
126 **kwargs):
127 network = self.create_network()
128 net_id = network['id']
129 gateway = kwargs.pop('gateway', None)
130 subnet = self.create_subnet(network, gateway, cidr, mask_bits,
131 **kwargs)
132 compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
133 mask_bits=mask_bits, **kwargs)
guo yunxian7bbbec12016-08-21 20:03:10 +0800134 compare_args = dict((k, v) for k, v in compare_args_full.items()
Rohan Kanade35589aa2014-08-19 14:56:12 +0200135 if v is not None)
136
137 if 'dns_nameservers' in set(subnet).intersection(compare_args):
138 self.assertEqual(sorted(compare_args['dns_nameservers']),
139 sorted(subnet['dns_nameservers']))
140 del subnet['dns_nameservers'], compare_args['dns_nameservers']
141
142 self._compare_resource_attrs(subnet, compare_args)
John Warren94d8faf2015-09-15 12:22:24 -0400143 self.networks_client.delete_network(net_id)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200144 self.networks.pop()
145 self.subnets.pop()
Unmesh Gurjar44986832012-05-08 19:57:10 +0530146
Jonte Watford871547c2016-10-10 20:11:04 +0000147
148class NetworksTest(BaseNetworkTestResources):
149 """Tests the following operations in the Neutron API:
150
151 create a network for a project
152 list project's networks
153 show a project network details
154 create a subnet for a project
155 list project's subnets
156 show a project subnet details
157 network update
158 subnet update
159 delete a network also deletes its subnets
160 list external networks
161
162 All subnet tests are run once with ipv4 and once with ipv6.
163
164 v2.0 of the Neutron API is assumed. It is also assumed that the following
165 options are defined in the [network] section of etc/tempest.conf:
166
167 project_network_cidr with a block of cidr's from which smaller blocks
168 can be allocated for project ipv4 subnets
169
170 project_network_v6_cidr is the equivalent for ipv6 subnets
171
172 project_network_mask_bits with the mask bits to be used to partition
173 the block defined by project_network_cidr
174
175 project_network_v6_mask_bits is the equivalent for ipv6 subnets
176 """
177
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900178 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800179 @decorators.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
raiesmh08e1aad982013-08-05 14:19:36 +0530180 def test_create_update_delete_network_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800181 # Create a network
zhufld2c40ca2016-10-18 17:03:07 +0800182 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000183 self.addCleanup(self._delete_network, network)
raiesmh08e1aad982013-08-05 14:19:36 +0530184 net_id = network['id']
Santosh Kumar42c94802014-08-08 04:31:42 -0700185 self.assertEqual('ACTIVE', network['status'])
Mark Maglana5885eb32014-02-28 10:57:34 -0800186 # Verify network update
raiesmh08e1aad982013-08-05 14:19:36 +0530187 new_name = "New_network"
John Warren94d8faf2015-09-15 12:22:24 -0400188 body = self.networks_client.update_network(net_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530189 updated_net = body['network']
190 self.assertEqual(updated_net['name'], new_name)
Miguel Lavallecc939612013-02-22 17:27:20 -0600191 # Find a cidr that is not in use yet and create a subnet with it
Matthew Treinish6b8cd2a2014-03-03 20:45:56 +0000192 subnet = self.create_subnet(network)
raiesmh08e1aad982013-08-05 14:19:36 +0530193 subnet_id = subnet['id']
Mark Maglana5885eb32014-02-28 10:57:34 -0800194 # Verify subnet update
195 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400196 body = self.subnets_client.update_subnet(subnet_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530197 updated_subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800198 self.assertEqual(updated_subnet['name'], new_name)
Unmesh Gurjar44986832012-05-08 19:57:10 +0530199
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900200 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800201 @decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530202 def test_show_network(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800203 # Verify the details of a network
John Warren94d8faf2015-09-15 12:22:24 -0400204 body = self.networks_client.show_network(self.network['id'])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530205 network = body['network']
Mark Maglana5885eb32014-02-28 10:57:34 -0800206 for key in ['id', 'name']:
207 self.assertEqual(network[key], self.network[key])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530208
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800209 @decorators.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
jun xied557d9b2014-01-09 14:00:36 +0800210 def test_show_network_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800211 # Verify specific fields of a network
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500212 fields = ['id', 'name']
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000213 if test.is_extension_enabled('net-mtu', 'network'):
214 fields.append('mtu')
John Warren94d8faf2015-09-15 12:22:24 -0400215 body = self.networks_client.show_network(self.network['id'],
216 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800217 network = body['network']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500218 self.assertEqual(sorted(network.keys()), sorted(fields))
219 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800220 self.assertEqual(network[field_name], self.network[field_name])
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000221 self.assertNotIn('tenant_id', network)
222 self.assertNotIn('project_id', network)
jun xied557d9b2014-01-09 14:00:36 +0800223
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900224 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800225 @decorators.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530226 def test_list_networks(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500227 # Verify the network exists in the list of all networks
John Warren94d8faf2015-09-15 12:22:24 -0400228 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800229 networks = [network['id'] for network in body['networks']
230 if network['id'] == self.network['id']]
231 self.assertNotEmpty(networks, "Created network not found in the list")
Unmesh Gurjar44986832012-05-08 19:57:10 +0530232
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800233 @decorators.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
jun xie0b4735d2014-01-07 15:42:58 +0800234 def test_list_networks_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800235 # Verify specific fields of the networks
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500236 fields = ['id', 'name']
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000237 if test.is_extension_enabled('net-mtu', 'network'):
238 fields.append('mtu')
John Warren94d8faf2015-09-15 12:22:24 -0400239 body = self.networks_client.list_networks(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800240 networks = body['networks']
Mark Maglana5885eb32014-02-28 10:57:34 -0800241 self.assertNotEmpty(networks, "Network list returned is empty")
242 for network in networks:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500243 self.assertEqual(sorted(network.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800244
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900245 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800246 @decorators.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
Miguel Lavallecc939612013-02-22 17:27:20 -0600247 def test_show_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800248 # Verify the details of a subnet
John Warren3961acd2015-10-02 14:38:53 -0400249 body = self.subnets_client.show_subnet(self.subnet['id'])
Miguel Lavallecc939612013-02-22 17:27:20 -0600250 subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800251 self.assertNotEmpty(subnet, "Subnet returned has no fields")
252 for key in ['id', 'cidr']:
253 self.assertIn(key, subnet)
254 self.assertEqual(subnet[key], self.subnet[key])
Miguel Lavallecc939612013-02-22 17:27:20 -0600255
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800256 @decorators.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
jun xied557d9b2014-01-09 14:00:36 +0800257 def test_show_subnet_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800258 # Verify specific fields of a subnet
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500259 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400260 body = self.subnets_client.show_subnet(self.subnet['id'],
261 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800262 subnet = body['subnet']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500263 self.assertEqual(sorted(subnet.keys()), sorted(fields))
264 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800265 self.assertEqual(subnet[field_name], self.subnet[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800266
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900267 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800268 @decorators.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
Miguel Lavallecc939612013-02-22 17:27:20 -0600269 def test_list_subnets(self):
270 # Verify the subnet exists in the list of all subnets
John Warren3961acd2015-10-02 14:38:53 -0400271 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800272 subnets = [subnet['id'] for subnet in body['subnets']
273 if subnet['id'] == self.subnet['id']]
274 self.assertNotEmpty(subnets, "Created subnet not found in the list")
raiesmh08e1aad982013-08-05 14:19:36 +0530275
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800276 @decorators.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
jun xie0b4735d2014-01-07 15:42:58 +0800277 def test_list_subnets_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800278 # Verify specific fields of subnets
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500279 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400280 body = self.subnets_client.list_subnets(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800281 subnets = body['subnets']
Mark Maglana5885eb32014-02-28 10:57:34 -0800282 self.assertNotEmpty(subnets, "Subnet list returned is empty")
283 for subnet in subnets:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500284 self.assertEqual(sorted(subnet.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800285
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800286 @decorators.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
sukhdevc704a702014-01-15 11:50:56 -0800287 def test_delete_network_with_subnet(self):
288 # Creates a network
Tianbiao Qi309ac412016-10-31 19:42:37 +0800289 network = self.create_network()
sukhdevc704a702014-01-15 11:50:56 -0800290 net_id = network['id']
Jordan Pittier9e227c52016-02-09 14:35:18 +0100291 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
Tianbiao Qi309ac412016-10-31 19:42:37 +0800292 self._delete_network, network)
sukhdevc704a702014-01-15 11:50:56 -0800293
294 # Find a cidr that is not in use yet and create a subnet with it
295 subnet = self.create_subnet(network)
296 subnet_id = subnet['id']
297
298 # Delete network while the subnet still exists
Tianbiao Qi309ac412016-10-31 19:42:37 +0800299 self.networks_client.delete_network(net_id)
sukhdevc704a702014-01-15 11:50:56 -0800300
301 # Verify that the subnet got automatically deleted.
John Warren3961acd2015-10-02 14:38:53 -0400302 self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
sukhdevc704a702014-01-15 11:50:56 -0800303 subnet_id)
304
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800305 @decorators.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400306 def test_create_delete_subnet_without_gateway(self):
307 self._create_verify_delete_subnet()
308
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800309 @decorators.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800310 def test_create_delete_subnet_with_gw(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200311 self._create_verify_delete_subnet(
312 **self.subnet_dict(['gateway']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800313
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800314 @decorators.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200315 def test_create_delete_subnet_with_allocation_pools(self):
316 self._create_verify_delete_subnet(
317 **self.subnet_dict(['allocation_pools']))
318
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800319 @decorators.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200320 def test_create_delete_subnet_with_gw_and_allocation_pools(self):
321 self._create_verify_delete_subnet(**self.subnet_dict(
322 ['gateway', 'allocation_pools']))
323
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800324 @decorators.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200325 def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
326 self._create_verify_delete_subnet(
327 **self.subnet_dict(['host_routes', 'dns_nameservers']))
328
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800329 @decorators.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200330 def test_create_delete_subnet_with_dhcp_enabled(self):
331 self._create_verify_delete_subnet(enable_dhcp=True)
332
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800333 @decorators.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200334 def test_update_subnet_gw_dns_host_routes_dhcp(self):
335 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000336 self.addCleanup(self._delete_network, network)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200337
338 subnet = self.create_subnet(
339 network, **self.subnet_dict(['gateway', 'host_routes',
340 'dns_nameservers',
341 'allocation_pools']))
342 subnet_id = subnet['id']
343 new_gateway = str(netaddr.IPAddress(
344 self._subnet_data[self._ip_version]['gateway']) + 1)
345 # Verify subnet update
346 new_host_routes = self._subnet_data[self._ip_version][
347 'new_host_routes']
348
349 new_dns_nameservers = self._subnet_data[self._ip_version][
350 'new_dns_nameservers']
351 kwargs = {'host_routes': new_host_routes,
352 'dns_nameservers': new_dns_nameservers,
353 'gateway_ip': new_gateway, 'enable_dhcp': True}
354
355 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400356 body = self.subnets_client.update_subnet(subnet_id, name=new_name,
357 **kwargs)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200358 updated_subnet = body['subnet']
359 kwargs['name'] = new_name
360 self.assertEqual(sorted(updated_subnet['dns_nameservers']),
361 sorted(kwargs['dns_nameservers']))
362 del subnet['dns_nameservers'], kwargs['dns_nameservers']
363
364 self._compare_resource_attrs(updated_subnet, kwargs)
365
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800366 @decorators.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200367 def test_create_delete_subnet_all_attributes(self):
368 self._create_verify_delete_subnet(
369 enable_dhcp=True,
370 **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800371
Yair Friedbfdfc752014-09-28 13:56:45 +0300372 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800373 @decorators.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
Kevin Benton6919da42016-03-05 18:00:03 -0800374 @test.requires_ext(extension='external-net', service='network')
375 @testtools.skipUnless(CONF.network.public_network_id,
376 'The public_network_id option must be specified.')
Yair Friedbfdfc752014-09-28 13:56:45 +0300377 def test_external_network_visibility(self):
378 """Verifies user can see external networks but not subnets."""
John Warren94d8faf2015-09-15 12:22:24 -0400379 body = self.networks_client.list_networks(**{'router:external': True})
Yair Friedbfdfc752014-09-28 13:56:45 +0300380 networks = [network['id'] for network in body['networks']]
381 self.assertNotEmpty(networks, "No external networks found")
382
383 nonexternal = [net for net in body['networks'] if
384 not net['router:external']]
385 self.assertEmpty(nonexternal, "Found non-external networks"
386 " in filtered list (%s)." % nonexternal)
387 self.assertIn(CONF.network.public_network_id, networks)
Kevin Benton6919da42016-03-05 18:00:03 -0800388 # only check the public network ID because the other networks may
389 # belong to other tests and their state may have changed during this
390 # test
391 body = self.subnets_client.list_subnets(
392 network_id=CONF.network.public_network_id)
393 self.assertEmpty(body['subnets'], "Public subnets visible")
Yair Friedbfdfc752014-09-28 13:56:45 +0300394
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800395 @decorators.idempotent_id('c72c1c0c-2193-4aca-ccc4-b1442640bbbb')
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000396 @test.requires_ext(extension="standard-attr-description",
397 service="network")
398 def test_create_update_network_description(self):
399 body = self.create_network(description='d1')
400 self.assertEqual('d1', body['description'])
401 net_id = body['id']
402 body = self.networks_client.list_networks(id=net_id)['networks'][0]
403 self.assertEqual('d1', body['description'])
404 body = self.networks_client.update_network(body['id'],
405 description='d2')
406 self.assertEqual('d2', body['network']['description'])
407 body = self.networks_client.list_networks(id=net_id)['networks'][0]
408 self.assertEqual('d2', body['description'])
409
raiesmh086b055e22013-09-16 12:59:57 +0530410
Tong Liu7012c862016-04-11 22:32:05 +0000411class BulkNetworkOpsTest(base.BaseNetworkTest):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000412 """Tests the following operations in the Neutron API:
raiesmh086b055e22013-09-16 12:59:57 +0530413
414 bulk network creation
415 bulk subnet creation
Eugene Nikanorove9d255a2013-12-18 16:31:42 +0400416 bulk port creation
Sean Dagueed6e5862016-04-04 10:49:13 -0400417 list project's networks
raiesmh086b055e22013-09-16 12:59:57 +0530418
419 v2.0 of the Neutron API is assumed. It is also assumed that the following
420 options are defined in the [network] section of etc/tempest.conf:
421
Sean Dagueed6e5862016-04-04 10:49:13 -0400422 project_network_cidr with a block of cidr's from which smaller blocks
423 can be allocated for project networks
raiesmh086b055e22013-09-16 12:59:57 +0530424
Sean Dagueed6e5862016-04-04 10:49:13 -0400425 project_network_mask_bits with the mask bits to be used to partition
426 the block defined by project-network_cidr
raiesmh086b055e22013-09-16 12:59:57 +0530427 """
428
raiesmh086b055e22013-09-16 12:59:57 +0530429 def _delete_networks(self, created_networks):
430 for n in created_networks:
John Warren94d8faf2015-09-15 12:22:24 -0400431 self.networks_client.delete_network(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530432 # Asserting that the networks are not found in the list after deletion
John Warren94d8faf2015-09-15 12:22:24 -0400433 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800434 networks_list = [network['id'] for network in body['networks']]
raiesmh086b055e22013-09-16 12:59:57 +0530435 for n in created_networks:
436 self.assertNotIn(n['id'], networks_list)
437
438 def _delete_subnets(self, created_subnets):
439 for n in created_subnets:
John Warren3961acd2015-10-02 14:38:53 -0400440 self.subnets_client.delete_subnet(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530441 # Asserting that the subnets are not found in the list after deletion
John Warren3961acd2015-10-02 14:38:53 -0400442 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800443 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh086b055e22013-09-16 12:59:57 +0530444 for n in created_subnets:
445 self.assertNotIn(n['id'], subnets_list)
446
447 def _delete_ports(self, created_ports):
448 for n in created_ports:
John Warren49c0fe52015-10-22 12:35:54 -0400449 self.ports_client.delete_port(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530450 # Asserting that the ports are not found in the list after deletion
John Warren49c0fe52015-10-22 12:35:54 -0400451 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800452 ports_list = [port['id'] for port in body['ports']]
raiesmh086b055e22013-09-16 12:59:57 +0530453 for n in created_ports:
454 self.assertNotIn(n['id'], ports_list)
455
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900456 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800457 @decorators.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
Nayna Patelb03eab42013-08-08 08:58:48 +0000458 def test_bulk_create_delete_network(self):
459 # Creates 2 networks in one request
piyush1107867584aa72015-12-15 18:46:38 +0530460 network_list = [{'name': data_utils.rand_name('network-')},
461 {'name': data_utils.rand_name('network-')}]
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800462 body = self.networks_client.create_bulk_networks(networks=network_list)
Nayna Patelb03eab42013-08-08 08:58:48 +0000463 created_networks = body['networks']
Nayna Patelb03eab42013-08-08 08:58:48 +0000464 self.addCleanup(self._delete_networks, created_networks)
465 # Asserting that the networks are found in the list after creation
John Warren94d8faf2015-09-15 12:22:24 -0400466 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800467 networks_list = [network['id'] for network in body['networks']]
Nayna Patelb03eab42013-08-08 08:58:48 +0000468 for n in created_networks:
469 self.assertIsNotNone(n['id'])
470 self.assertIn(n['id'], networks_list)
raiesmh0867698322013-08-20 13:09:01 +0530471
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900472 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800473 @decorators.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
raiesmh082d5c6512013-09-06 15:35:05 +0530474 def test_bulk_create_delete_subnet(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300475 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530476 # Creates 2 subnets in one request
Rohan Kanade0efb0232015-02-19 13:33:31 +0530477 if self._ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -0400478 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
479 mask_bits = CONF.network.project_network_mask_bits
Rohan Kanade0efb0232015-02-19 13:33:31 +0530480 else:
Sean Dagueed6e5862016-04-04 10:49:13 -0400481 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
482 mask_bits = CONF.network.project_network_v6_mask_bits
Rohan Kanade0efb0232015-02-19 13:33:31 +0530483
Mark Maglana5885eb32014-02-28 10:57:34 -0800484 cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
Rohan Kanade0efb0232015-02-19 13:33:31 +0530485
Mark Maglana5885eb32014-02-28 10:57:34 -0800486 names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
487 subnets_list = []
raiesmh082d5c6512013-09-06 15:35:05 +0530488 for i in range(len(names)):
489 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300490 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530491 'cidr': str(cidrs[(i)]),
492 'name': names[i],
Rohan Kanade0efb0232015-02-19 13:33:31 +0530493 'ip_version': self._ip_version
raiesmh082d5c6512013-09-06 15:35:05 +0530494 }
Mark Maglana5885eb32014-02-28 10:57:34 -0800495 subnets_list.append(p1)
496 del subnets_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800497 body = self.subnets_client.create_bulk_subnets(subnets=subnets_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530498 created_subnets = body['subnets']
499 self.addCleanup(self._delete_subnets, created_subnets)
raiesmh082d5c6512013-09-06 15:35:05 +0530500 # Asserting that the subnets are found in the list after creation
John Warren3961acd2015-10-02 14:38:53 -0400501 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800502 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh082d5c6512013-09-06 15:35:05 +0530503 for n in created_subnets:
504 self.assertIsNotNone(n['id'])
505 self.assertIn(n['id'], subnets_list)
506
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900507 @test.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800508 @decorators.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
raiesmh082d5c6512013-09-06 15:35:05 +0530509 def test_bulk_create_delete_port(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300510 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530511 # Creates 2 ports in one request
Mark Maglana5885eb32014-02-28 10:57:34 -0800512 names = [data_utils.rand_name('port-') for i in range(len(networks))]
raiesmh082d5c6512013-09-06 15:35:05 +0530513 port_list = []
514 state = [True, False]
515 for i in range(len(names)):
516 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300517 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530518 'name': names[i],
519 'admin_state_up': state[i],
520 }
521 port_list.append(p1)
522 del port_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800523 body = self.ports_client.create_bulk_ports(ports=port_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530524 created_ports = body['ports']
525 self.addCleanup(self._delete_ports, created_ports)
raiesmh082d5c6512013-09-06 15:35:05 +0530526 # Asserting that the ports are found in the list after creation
John Warren49c0fe52015-10-22 12:35:54 -0400527 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800528 ports_list = [port['id'] for port in body['ports']]
raiesmh082d5c6512013-09-06 15:35:05 +0530529 for n in created_ports:
530 self.assertIsNotNone(n['id'])
531 self.assertIn(n['id'], ports_list)
532
raiesmh0867698322013-08-20 13:09:01 +0530533
Tong Liu7012c862016-04-11 22:32:05 +0000534class BulkNetworkOpsIpV6Test(BulkNetworkOpsTest):
Rohan Kanade0efb0232015-02-19 13:33:31 +0530535 _ip_version = 6
536
537
Tong Liu7012c862016-04-11 22:32:05 +0000538class NetworksIpV6Test(NetworksTest):
Henry Gessauffda37a2014-01-16 11:17:55 -0500539 _ip_version = 6
Henry Gessauffda37a2014-01-16 11:17:55 -0500540
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800541 @decorators.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800542 def test_create_delete_subnet_with_gw(self):
Sean Dagueed6e5862016-04-04 10:49:13 -0400543 net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
sridhargaddamea73d532014-05-13 14:48:30 +0530544 gateway = str(netaddr.IPAddress(net.first + 2))
zhufld2c40ca2016-10-18 17:03:07 +0800545 network = self.create_network()
Edgar Magana6a9ac342014-01-16 13:52:49 -0800546 subnet = self.create_subnet(network, gateway)
547 # Verifies Subnet GW in IPv6
548 self.assertEqual(subnet['gateway_ip'], gateway)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800549
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800550 @decorators.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400551 def test_create_delete_subnet_with_default_gw(self):
Sean Dagueed6e5862016-04-04 10:49:13 -0400552 net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
sridhargaddamea73d532014-05-13 14:48:30 +0530553 gateway_ip = str(netaddr.IPAddress(net.first + 1))
zhufld2c40ca2016-10-18 17:03:07 +0800554 network = self.create_network()
Edgar Magana6a9ac342014-01-16 13:52:49 -0800555 subnet = self.create_subnet(network)
556 # Verifies Subnet GW in IPv6
sridhargaddamea73d532014-05-13 14:48:30 +0530557 self.assertEqual(subnet['gateway_ip'], gateway_ip)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800558
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800559 @decorators.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400560 def test_create_list_subnet_with_no_gw64_one_network(self):
zhufld2c40ca2016-10-18 17:03:07 +0800561 network = self.create_network()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400562 ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
563 subnet1 = self.create_subnet(network,
564 ip_version=6,
565 gateway=ipv6_gateway)
566 self.assertEqual(netaddr.IPNetwork(subnet1['cidr']).version, 6,
567 'The created subnet is not IPv6')
568 subnet2 = self.create_subnet(network,
569 gateway=None,
570 ip_version=4)
571 self.assertEqual(netaddr.IPNetwork(subnet2['cidr']).version, 4,
572 'The created subnet is not IPv4')
573 # Verifies Subnet GW is set in IPv6
574 self.assertEqual(subnet1['gateway_ip'], ipv6_gateway)
575 # Verifies Subnet GW is None in IPv4
guo yunxian0306a4a2016-07-29 16:32:28 +0800576 self.assertIsNone(subnet2['gateway_ip'])
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400577 # Verifies all 2 subnets in the same network
John Warren3961acd2015-10-02 14:38:53 -0400578 body = self.subnets_client.list_subnets()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400579 subnets = [sub['id'] for sub in body['subnets']
580 if sub['network_id'] == network['id']]
581 test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
ghanshyam2dee5e32016-06-24 14:42:56 +0900582 six.assertCountEqual(self, subnets,
583 test_subnet_ids,
584 'Subnet are not in the same network')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400585
Sergey She757c332014-11-25 01:16:32 +0300586
Jonte Watford871547c2016-10-10 20:11:04 +0000587class NetworksIpV6TestAttrs(BaseNetworkTestResources):
588
589 _ip_version = 6
Sergey She757c332014-11-25 01:16:32 +0300590
591 @classmethod
Rohan Kanadea565e452015-01-27 14:00:13 +0530592 def skip_checks(cls):
593 super(NetworksIpV6TestAttrs, cls).skip_checks()
Sergey She757c332014-11-25 01:16:32 +0300594 if not CONF.network_feature_enabled.ipv6_subnet_attributes:
595 raise cls.skipException("IPv6 extended attributes for "
596 "subnets not available")
Sergey She757c332014-11-25 01:16:32 +0300597
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800598 @decorators.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400599 def test_create_delete_subnet_with_v6_attributes_stateful(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200600 self._create_verify_delete_subnet(
601 gateway=self._subnet_data[self._ip_version]['gateway'],
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400602 ipv6_ra_mode='dhcpv6-stateful',
603 ipv6_address_mode='dhcpv6-stateful')
604
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800605 @decorators.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400606 def test_create_delete_subnet_with_v6_attributes_slaac(self):
607 self._create_verify_delete_subnet(
Rohan Kanade35589aa2014-08-19 14:56:12 +0200608 ipv6_ra_mode='slaac',
609 ipv6_address_mode='slaac')
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400610
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800611 @decorators.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400612 def test_create_delete_subnet_with_v6_attributes_stateless(self):
613 self._create_verify_delete_subnet(
614 ipv6_ra_mode='dhcpv6-stateless',
615 ipv6_address_mode='dhcpv6-stateless')
Sergey She757c332014-11-25 01:16:32 +0300616
617 def _test_delete_subnet_with_ports(self, mode):
618 """Create subnet and delete it with existing ports"""
619 slaac_network = self.create_network()
620 subnet_slaac = self.create_subnet(slaac_network,
621 **{'ipv6_ra_mode': mode,
622 'ipv6_address_mode': mode})
623 port = self.create_port(slaac_network)
624 self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
John Warren3961acd2015-10-02 14:38:53 -0400625 self.subnets_client.delete_subnet(subnet_slaac['id'])
Sergey She757c332014-11-25 01:16:32 +0300626 self.subnets.pop()
John Warren3961acd2015-10-02 14:38:53 -0400627 subnets = self.subnets_client.list_subnets()
Sergey She757c332014-11-25 01:16:32 +0300628 subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
629 self.assertNotIn(subnet_slaac['id'], subnet_ids,
630 "Subnet wasn't deleted")
reedip6fb7e1a2016-03-10 13:32:01 +0900631 self.assertRaisesRegex(
Masayuki Igawad9388762015-01-20 14:56:42 +0900632 lib_exc.Conflict,
Sergey She757c332014-11-25 01:16:32 +0300633 "There are one or more ports still in use on the network",
John Warren94d8faf2015-09-15 12:22:24 -0400634 self.networks_client.delete_network,
Sergey She757c332014-11-25 01:16:32 +0300635 slaac_network['id'])
636
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800637 @decorators.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
Sergey She757c332014-11-25 01:16:32 +0300638 def test_create_delete_slaac_subnet_with_ports(self):
639 """Test deleting subnet with SLAAC ports
640
641 Create subnet with SLAAC, create ports in network
642 and then you shall be able to delete subnet without port
643 deletion. But you still can not delete the network.
644 """
645 self._test_delete_subnet_with_ports("slaac")
646
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800647 @decorators.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
Sergey She757c332014-11-25 01:16:32 +0300648 def test_create_delete_stateless_subnet_with_ports(self):
649 """Test deleting subnet with DHCPv6 stateless ports
650
651 Create subnet with DHCPv6 stateless, create ports in network
652 and then you shall be able to delete subnet without port
653 deletion. But you still can not delete the network.
654 """
655 self._test_delete_subnet_with_ports("dhcpv6-stateless")