blob: 206d1a84669fc11e52c5c0c0e13b8e127ed12347 [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
Andrea Frittolicd368412017-08-14 21:37:56 +010021from tempest.common import utils
Matthew Treinish03b48df2014-01-29 16:59:49 +000022from tempest import config
Ken'ichi Ohmichif50e4df2017-03-10 10:52:53 -080023from tempest.lib.common.utils import data_utils
Jordan Pittier9e227c52016-02-09 14:35:18 +010024from tempest.lib.common.utils import test_utils
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -080025from tempest.lib import decorators
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050026from tempest.lib import exceptions as lib_exc
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()
venakata anil1a2a64a2014-12-02 07:25:59 +000037 cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
38 cls._ip_version)
Rohan Kanade35589aa2014-08-19 14:56:12 +020039 cls._subnet_data = {6: {'gateway':
40 str(cls._get_gateway_from_tempest_conf(6)),
41 'allocation_pools':
42 cls._get_allocation_pools_from_gateway(6),
43 'dns_nameservers': ['2001:4860:4860::8844',
44 '2001:4860:4860::8888'],
45 'host_routes': [{'destination': '2001::/64',
46 'nexthop': '2003::1'}],
47 'new_host_routes': [{'destination':
48 '2001::/64',
49 'nexthop': '2005::1'}],
50 'new_dns_nameservers':
51 ['2001:4860:4860::7744',
52 '2001:4860:4860::7888']},
53 4: {'gateway':
54 str(cls._get_gateway_from_tempest_conf(4)),
55 'allocation_pools':
56 cls._get_allocation_pools_from_gateway(4),
57 'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
58 'host_routes': [{'destination': '10.20.0.0/32',
59 'nexthop': '10.100.1.1'}],
60 'new_host_routes': [{'destination':
61 '10.20.0.0/32',
62 'nexthop':
63 '10.100.1.2'}],
64 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
65
66 @classmethod
venakata anil1a2a64a2014-12-02 07:25:59 +000067 def _create_subnet_with_last_subnet_block(cls, network, ip_version):
Sean Dagueed6e5862016-04-04 10:49:13 -040068 # Derive last subnet CIDR block from project CIDR and
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +000069 # create the subnet with that derived CIDR
venakata anil1a2a64a2014-12-02 07:25:59 +000070 if ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -040071 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
72 mask_bits = CONF.network.project_network_mask_bits
venakata anil1a2a64a2014-12-02 07:25:59 +000073 elif ip_version == 6:
Sean Dagueed6e5862016-04-04 10:49:13 -040074 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
75 mask_bits = CONF.network.project_network_v6_mask_bits
venakata anil1a2a64a2014-12-02 07:25:59 +000076
77 subnet_cidr = list(cidr.subnet(mask_bits))[-1]
78 gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
79 return cls.create_subnet(network, gateway=gateway_ip,
80 cidr=subnet_cidr, mask_bits=mask_bits)
81
82 @classmethod
Rohan Kanade35589aa2014-08-19 14:56:12 +020083 def _get_gateway_from_tempest_conf(cls, ip_version):
84 """Return first subnet gateway for configured CIDR """
85 if ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -040086 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
87 mask_bits = CONF.network.project_network_mask_bits
Rohan Kanade35589aa2014-08-19 14:56:12 +020088 elif ip_version == 6:
Sean Dagueed6e5862016-04-04 10:49:13 -040089 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
90 mask_bits = CONF.network.project_network_v6_mask_bits
Rohan Kanade35589aa2014-08-19 14:56:12 +020091
92 if mask_bits >= cidr.prefixlen:
93 return netaddr.IPAddress(cidr) + 1
94 else:
95 for subnet in cidr.subnet(mask_bits):
96 return netaddr.IPAddress(subnet) + 1
97
98 @classmethod
99 def _get_allocation_pools_from_gateway(cls, ip_version):
100 """Return allocation range for subnet of given gateway"""
101 gateway = cls._get_gateway_from_tempest_conf(ip_version)
Hynek Mlnarikbe634fc2016-06-27 09:34:15 +0200102 return [{'start': str(gateway + 2), 'end': str(gateway + 6)}]
Rohan Kanade35589aa2014-08-19 14:56:12 +0200103
104 def subnet_dict(self, include_keys):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000105 # Return a subnet dict which has include_keys and their corresponding
106 # value from self._subnet_data
Rohan Kanade35589aa2014-08-19 14:56:12 +0200107 return dict((key, self._subnet_data[self._ip_version][key])
108 for key in include_keys)
109
110 def _compare_resource_attrs(self, actual, expected):
111 exclude_keys = set(actual).symmetric_difference(expected)
112 self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
113 expected, exclude_keys))
114
venakata anil1a2a64a2014-12-02 07:25:59 +0000115 def _delete_network(self, network):
116 # Deleting network also deletes its subnets if exists
John Warren94d8faf2015-09-15 12:22:24 -0400117 self.networks_client.delete_network(network['id'])
venakata anil1a2a64a2014-12-02 07:25:59 +0000118 if network in self.networks:
119 self.networks.remove(network)
120 for subnet in self.subnets:
121 if subnet['network_id'] == network['id']:
122 self.subnets.remove(subnet)
123
Rohan Kanade35589aa2014-08-19 14:56:12 +0200124 def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
125 **kwargs):
126 network = self.create_network()
127 net_id = network['id']
128 gateway = kwargs.pop('gateway', None)
129 subnet = self.create_subnet(network, gateway, cidr, mask_bits,
130 **kwargs)
131 compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
132 mask_bits=mask_bits, **kwargs)
guo yunxian7bbbec12016-08-21 20:03:10 +0800133 compare_args = dict((k, v) for k, v in compare_args_full.items()
Rohan Kanade35589aa2014-08-19 14:56:12 +0200134 if v is not None)
135
136 if 'dns_nameservers' in set(subnet).intersection(compare_args):
137 self.assertEqual(sorted(compare_args['dns_nameservers']),
138 sorted(subnet['dns_nameservers']))
139 del subnet['dns_nameservers'], compare_args['dns_nameservers']
140
141 self._compare_resource_attrs(subnet, compare_args)
John Warren94d8faf2015-09-15 12:22:24 -0400142 self.networks_client.delete_network(net_id)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200143 self.networks.pop()
144 self.subnets.pop()
Unmesh Gurjar44986832012-05-08 19:57:10 +0530145
Jonte Watford871547c2016-10-10 20:11:04 +0000146
147class NetworksTest(BaseNetworkTestResources):
148 """Tests the following operations in the Neutron API:
149
150 create a network for a project
151 list project's networks
152 show a project network details
153 create a subnet for a project
154 list project's subnets
155 show a project subnet details
156 network update
157 subnet update
158 delete a network also deletes its subnets
159 list external networks
160
161 All subnet tests are run once with ipv4 and once with ipv6.
162
163 v2.0 of the Neutron API is assumed. It is also assumed that the following
164 options are defined in the [network] section of etc/tempest.conf:
165
166 project_network_cidr with a block of cidr's from which smaller blocks
167 can be allocated for project ipv4 subnets
168
169 project_network_v6_cidr is the equivalent for ipv6 subnets
170
171 project_network_mask_bits with the mask bits to be used to partition
172 the block defined by project_network_cidr
173
174 project_network_v6_mask_bits is the equivalent for ipv6 subnets
175 """
176
Jordan Pittier3b46d272017-04-12 16:17:28 +0200177 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800178 @decorators.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
raiesmh08e1aad982013-08-05 14:19:36 +0530179 def test_create_update_delete_network_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800180 # Create a network
zhufld2c40ca2016-10-18 17:03:07 +0800181 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000182 self.addCleanup(self._delete_network, network)
raiesmh08e1aad982013-08-05 14:19:36 +0530183 net_id = network['id']
Santosh Kumar42c94802014-08-08 04:31:42 -0700184 self.assertEqual('ACTIVE', network['status'])
Mark Maglana5885eb32014-02-28 10:57:34 -0800185 # Verify network update
raiesmh08e1aad982013-08-05 14:19:36 +0530186 new_name = "New_network"
John Warren94d8faf2015-09-15 12:22:24 -0400187 body = self.networks_client.update_network(net_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530188 updated_net = body['network']
189 self.assertEqual(updated_net['name'], new_name)
Miguel Lavallecc939612013-02-22 17:27:20 -0600190 # Find a cidr that is not in use yet and create a subnet with it
Matthew Treinish6b8cd2a2014-03-03 20:45:56 +0000191 subnet = self.create_subnet(network)
raiesmh08e1aad982013-08-05 14:19:36 +0530192 subnet_id = subnet['id']
Mark Maglana5885eb32014-02-28 10:57:34 -0800193 # Verify subnet update
194 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400195 body = self.subnets_client.update_subnet(subnet_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530196 updated_subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800197 self.assertEqual(updated_subnet['name'], new_name)
Unmesh Gurjar44986832012-05-08 19:57:10 +0530198
Jordan Pittier3b46d272017-04-12 16:17:28 +0200199 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800200 @decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530201 def test_show_network(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800202 # Verify the details of a network
John Warren94d8faf2015-09-15 12:22:24 -0400203 body = self.networks_client.show_network(self.network['id'])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530204 network = body['network']
Mark Maglana5885eb32014-02-28 10:57:34 -0800205 for key in ['id', 'name']:
206 self.assertEqual(network[key], self.network[key])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530207
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800208 @decorators.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
jun xied557d9b2014-01-09 14:00:36 +0800209 def test_show_network_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800210 # Verify specific fields of a network
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500211 fields = ['id', 'name']
Andrea Frittolicd368412017-08-14 21:37:56 +0100212 if utils.is_extension_enabled('net-mtu', 'network'):
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000213 fields.append('mtu')
John Warren94d8faf2015-09-15 12:22:24 -0400214 body = self.networks_client.show_network(self.network['id'],
215 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800216 network = body['network']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500217 self.assertEqual(sorted(network.keys()), sorted(fields))
218 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800219 self.assertEqual(network[field_name], self.network[field_name])
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000220 self.assertNotIn('tenant_id', network)
221 self.assertNotIn('project_id', network)
jun xied557d9b2014-01-09 14:00:36 +0800222
Jordan Pittier3b46d272017-04-12 16:17:28 +0200223 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800224 @decorators.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530225 def test_list_networks(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500226 # Verify the network exists in the list of all networks
John Warren94d8faf2015-09-15 12:22:24 -0400227 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800228 networks = [network['id'] for network in body['networks']
229 if network['id'] == self.network['id']]
230 self.assertNotEmpty(networks, "Created network not found in the list")
Unmesh Gurjar44986832012-05-08 19:57:10 +0530231
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800232 @decorators.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
jun xie0b4735d2014-01-07 15:42:58 +0800233 def test_list_networks_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800234 # Verify specific fields of the networks
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500235 fields = ['id', 'name']
Andrea Frittolicd368412017-08-14 21:37:56 +0100236 if utils.is_extension_enabled('net-mtu', 'network'):
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000237 fields.append('mtu')
John Warren94d8faf2015-09-15 12:22:24 -0400238 body = self.networks_client.list_networks(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800239 networks = body['networks']
Mark Maglana5885eb32014-02-28 10:57:34 -0800240 self.assertNotEmpty(networks, "Network list returned is empty")
241 for network in networks:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500242 self.assertEqual(sorted(network.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800243
Jordan Pittier3b46d272017-04-12 16:17:28 +0200244 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800245 @decorators.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
Miguel Lavallecc939612013-02-22 17:27:20 -0600246 def test_show_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800247 # Verify the details of a subnet
John Warren3961acd2015-10-02 14:38:53 -0400248 body = self.subnets_client.show_subnet(self.subnet['id'])
Miguel Lavallecc939612013-02-22 17:27:20 -0600249 subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800250 self.assertNotEmpty(subnet, "Subnet returned has no fields")
251 for key in ['id', 'cidr']:
252 self.assertIn(key, subnet)
253 self.assertEqual(subnet[key], self.subnet[key])
Miguel Lavallecc939612013-02-22 17:27:20 -0600254
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800255 @decorators.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
jun xied557d9b2014-01-09 14:00:36 +0800256 def test_show_subnet_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800257 # Verify specific fields of a subnet
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500258 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400259 body = self.subnets_client.show_subnet(self.subnet['id'],
260 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800261 subnet = body['subnet']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500262 self.assertEqual(sorted(subnet.keys()), sorted(fields))
263 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800264 self.assertEqual(subnet[field_name], self.subnet[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800265
Jordan Pittier3b46d272017-04-12 16:17:28 +0200266 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800267 @decorators.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
Miguel Lavallecc939612013-02-22 17:27:20 -0600268 def test_list_subnets(self):
269 # Verify the subnet exists in the list of all subnets
John Warren3961acd2015-10-02 14:38:53 -0400270 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800271 subnets = [subnet['id'] for subnet in body['subnets']
272 if subnet['id'] == self.subnet['id']]
273 self.assertNotEmpty(subnets, "Created subnet not found in the list")
raiesmh08e1aad982013-08-05 14:19:36 +0530274
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800275 @decorators.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
jun xie0b4735d2014-01-07 15:42:58 +0800276 def test_list_subnets_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800277 # Verify specific fields of subnets
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500278 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400279 body = self.subnets_client.list_subnets(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800280 subnets = body['subnets']
Mark Maglana5885eb32014-02-28 10:57:34 -0800281 self.assertNotEmpty(subnets, "Subnet list returned is empty")
282 for subnet in subnets:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500283 self.assertEqual(sorted(subnet.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800284
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800285 @decorators.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
sukhdevc704a702014-01-15 11:50:56 -0800286 def test_delete_network_with_subnet(self):
287 # Creates a network
Tianbiao Qi309ac412016-10-31 19:42:37 +0800288 network = self.create_network()
sukhdevc704a702014-01-15 11:50:56 -0800289 net_id = network['id']
Jordan Pittier9e227c52016-02-09 14:35:18 +0100290 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
Tianbiao Qi309ac412016-10-31 19:42:37 +0800291 self._delete_network, network)
sukhdevc704a702014-01-15 11:50:56 -0800292
293 # Find a cidr that is not in use yet and create a subnet with it
294 subnet = self.create_subnet(network)
295 subnet_id = subnet['id']
296
297 # Delete network while the subnet still exists
Tianbiao Qi309ac412016-10-31 19:42:37 +0800298 self.networks_client.delete_network(net_id)
sukhdevc704a702014-01-15 11:50:56 -0800299
300 # Verify that the subnet got automatically deleted.
John Warren3961acd2015-10-02 14:38:53 -0400301 self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
sukhdevc704a702014-01-15 11:50:56 -0800302 subnet_id)
303
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800304 @decorators.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400305 def test_create_delete_subnet_without_gateway(self):
306 self._create_verify_delete_subnet()
307
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800308 @decorators.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800309 def test_create_delete_subnet_with_gw(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200310 self._create_verify_delete_subnet(
311 **self.subnet_dict(['gateway']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800312
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800313 @decorators.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200314 def test_create_delete_subnet_with_allocation_pools(self):
315 self._create_verify_delete_subnet(
316 **self.subnet_dict(['allocation_pools']))
317
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800318 @decorators.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200319 def test_create_delete_subnet_with_gw_and_allocation_pools(self):
320 self._create_verify_delete_subnet(**self.subnet_dict(
321 ['gateway', 'allocation_pools']))
322
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800323 @decorators.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200324 def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
325 self._create_verify_delete_subnet(
326 **self.subnet_dict(['host_routes', 'dns_nameservers']))
327
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800328 @decorators.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200329 def test_create_delete_subnet_with_dhcp_enabled(self):
330 self._create_verify_delete_subnet(enable_dhcp=True)
331
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800332 @decorators.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200333 def test_update_subnet_gw_dns_host_routes_dhcp(self):
334 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000335 self.addCleanup(self._delete_network, network)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200336
337 subnet = self.create_subnet(
338 network, **self.subnet_dict(['gateway', 'host_routes',
339 'dns_nameservers',
340 'allocation_pools']))
341 subnet_id = subnet['id']
342 new_gateway = str(netaddr.IPAddress(
343 self._subnet_data[self._ip_version]['gateway']) + 1)
344 # Verify subnet update
345 new_host_routes = self._subnet_data[self._ip_version][
346 'new_host_routes']
347
348 new_dns_nameservers = self._subnet_data[self._ip_version][
349 'new_dns_nameservers']
350 kwargs = {'host_routes': new_host_routes,
351 'dns_nameservers': new_dns_nameservers,
352 'gateway_ip': new_gateway, 'enable_dhcp': True}
353
354 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400355 body = self.subnets_client.update_subnet(subnet_id, name=new_name,
356 **kwargs)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200357 updated_subnet = body['subnet']
358 kwargs['name'] = new_name
359 self.assertEqual(sorted(updated_subnet['dns_nameservers']),
360 sorted(kwargs['dns_nameservers']))
361 del subnet['dns_nameservers'], kwargs['dns_nameservers']
362
363 self._compare_resource_attrs(updated_subnet, kwargs)
364
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800365 @decorators.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200366 def test_create_delete_subnet_all_attributes(self):
367 self._create_verify_delete_subnet(
368 enable_dhcp=True,
369 **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800370
Jordan Pittier3b46d272017-04-12 16:17:28 +0200371 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800372 @decorators.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
Andrea Frittolicd368412017-08-14 21:37:56 +0100373 @utils.requires_ext(extension='external-net', service='network')
Kevin Benton6919da42016-03-05 18:00:03 -0800374 @testtools.skipUnless(CONF.network.public_network_id,
375 'The public_network_id option must be specified.')
Yair Friedbfdfc752014-09-28 13:56:45 +0300376 def test_external_network_visibility(self):
377 """Verifies user can see external networks but not subnets."""
John Warren94d8faf2015-09-15 12:22:24 -0400378 body = self.networks_client.list_networks(**{'router:external': True})
Yair Friedbfdfc752014-09-28 13:56:45 +0300379 networks = [network['id'] for network in body['networks']]
380 self.assertNotEmpty(networks, "No external networks found")
381
382 nonexternal = [net for net in body['networks'] if
383 not net['router:external']]
384 self.assertEmpty(nonexternal, "Found non-external networks"
385 " in filtered list (%s)." % nonexternal)
386 self.assertIn(CONF.network.public_network_id, networks)
Kevin Benton6919da42016-03-05 18:00:03 -0800387 # only check the public network ID because the other networks may
388 # belong to other tests and their state may have changed during this
389 # test
390 body = self.subnets_client.list_subnets(
391 network_id=CONF.network.public_network_id)
392 self.assertEmpty(body['subnets'], "Public subnets visible")
Yair Friedbfdfc752014-09-28 13:56:45 +0300393
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800394 @decorators.idempotent_id('c72c1c0c-2193-4aca-ccc4-b1442640bbbb')
Andrea Frittolicd368412017-08-14 21:37:56 +0100395 @utils.requires_ext(extension="standard-attr-description",
396 service="network")
Bruce Tand3e9b4a2016-09-22 09:17:06 +0000397 def test_create_update_network_description(self):
398 body = self.create_network(description='d1')
399 self.assertEqual('d1', body['description'])
400 net_id = body['id']
401 body = self.networks_client.list_networks(id=net_id)['networks'][0]
402 self.assertEqual('d1', body['description'])
403 body = self.networks_client.update_network(body['id'],
404 description='d2')
405 self.assertEqual('d2', body['network']['description'])
406 body = self.networks_client.list_networks(id=net_id)['networks'][0]
407 self.assertEqual('d2', body['description'])
408
raiesmh086b055e22013-09-16 12:59:57 +0530409
Tong Liu7012c862016-04-11 22:32:05 +0000410class BulkNetworkOpsTest(base.BaseNetworkTest):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000411 """Tests the following operations in the Neutron API:
raiesmh086b055e22013-09-16 12:59:57 +0530412
413 bulk network creation
414 bulk subnet creation
Eugene Nikanorove9d255a2013-12-18 16:31:42 +0400415 bulk port creation
Sean Dagueed6e5862016-04-04 10:49:13 -0400416 list project's networks
raiesmh086b055e22013-09-16 12:59:57 +0530417
418 v2.0 of the Neutron API is assumed. It is also assumed that the following
419 options are defined in the [network] section of etc/tempest.conf:
420
Sean Dagueed6e5862016-04-04 10:49:13 -0400421 project_network_cidr with a block of cidr's from which smaller blocks
422 can be allocated for project networks
raiesmh086b055e22013-09-16 12:59:57 +0530423
Sean Dagueed6e5862016-04-04 10:49:13 -0400424 project_network_mask_bits with the mask bits to be used to partition
425 the block defined by project-network_cidr
raiesmh086b055e22013-09-16 12:59:57 +0530426 """
427
raiesmh086b055e22013-09-16 12:59:57 +0530428 def _delete_networks(self, created_networks):
429 for n in created_networks:
John Warren94d8faf2015-09-15 12:22:24 -0400430 self.networks_client.delete_network(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530431 # Asserting that the networks are not found in the list after deletion
John Warren94d8faf2015-09-15 12:22:24 -0400432 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800433 networks_list = [network['id'] for network in body['networks']]
raiesmh086b055e22013-09-16 12:59:57 +0530434 for n in created_networks:
435 self.assertNotIn(n['id'], networks_list)
436
437 def _delete_subnets(self, created_subnets):
438 for n in created_subnets:
John Warren3961acd2015-10-02 14:38:53 -0400439 self.subnets_client.delete_subnet(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530440 # Asserting that the subnets are not found in the list after deletion
John Warren3961acd2015-10-02 14:38:53 -0400441 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800442 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh086b055e22013-09-16 12:59:57 +0530443 for n in created_subnets:
444 self.assertNotIn(n['id'], subnets_list)
445
446 def _delete_ports(self, created_ports):
447 for n in created_ports:
John Warren49c0fe52015-10-22 12:35:54 -0400448 self.ports_client.delete_port(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530449 # Asserting that the ports are not found in the list after deletion
John Warren49c0fe52015-10-22 12:35:54 -0400450 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800451 ports_list = [port['id'] for port in body['ports']]
raiesmh086b055e22013-09-16 12:59:57 +0530452 for n in created_ports:
453 self.assertNotIn(n['id'], ports_list)
454
Jordan Pittier3b46d272017-04-12 16:17:28 +0200455 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800456 @decorators.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
Nayna Patelb03eab42013-08-08 08:58:48 +0000457 def test_bulk_create_delete_network(self):
458 # Creates 2 networks in one request
piyush1107867584aa72015-12-15 18:46:38 +0530459 network_list = [{'name': data_utils.rand_name('network-')},
460 {'name': data_utils.rand_name('network-')}]
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800461 body = self.networks_client.create_bulk_networks(networks=network_list)
Nayna Patelb03eab42013-08-08 08:58:48 +0000462 created_networks = body['networks']
Nayna Patelb03eab42013-08-08 08:58:48 +0000463 self.addCleanup(self._delete_networks, created_networks)
464 # Asserting that the networks are found in the list after creation
John Warren94d8faf2015-09-15 12:22:24 -0400465 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800466 networks_list = [network['id'] for network in body['networks']]
Nayna Patelb03eab42013-08-08 08:58:48 +0000467 for n in created_networks:
468 self.assertIsNotNone(n['id'])
469 self.assertIn(n['id'], networks_list)
raiesmh0867698322013-08-20 13:09:01 +0530470
Jordan Pittier3b46d272017-04-12 16:17:28 +0200471 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800472 @decorators.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
raiesmh082d5c6512013-09-06 15:35:05 +0530473 def test_bulk_create_delete_subnet(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300474 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530475 # Creates 2 subnets in one request
Rohan Kanade0efb0232015-02-19 13:33:31 +0530476 if self._ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -0400477 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
478 mask_bits = CONF.network.project_network_mask_bits
Rohan Kanade0efb0232015-02-19 13:33:31 +0530479 else:
Sean Dagueed6e5862016-04-04 10:49:13 -0400480 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
481 mask_bits = CONF.network.project_network_v6_mask_bits
Rohan Kanade0efb0232015-02-19 13:33:31 +0530482
Mark Maglana5885eb32014-02-28 10:57:34 -0800483 cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
Rohan Kanade0efb0232015-02-19 13:33:31 +0530484
Mark Maglana5885eb32014-02-28 10:57:34 -0800485 names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
486 subnets_list = []
raiesmh082d5c6512013-09-06 15:35:05 +0530487 for i in range(len(names)):
488 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300489 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530490 'cidr': str(cidrs[(i)]),
491 'name': names[i],
Rohan Kanade0efb0232015-02-19 13:33:31 +0530492 'ip_version': self._ip_version
raiesmh082d5c6512013-09-06 15:35:05 +0530493 }
Mark Maglana5885eb32014-02-28 10:57:34 -0800494 subnets_list.append(p1)
495 del subnets_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800496 body = self.subnets_client.create_bulk_subnets(subnets=subnets_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530497 created_subnets = body['subnets']
498 self.addCleanup(self._delete_subnets, created_subnets)
raiesmh082d5c6512013-09-06 15:35:05 +0530499 # Asserting that the subnets are found in the list after creation
John Warren3961acd2015-10-02 14:38:53 -0400500 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800501 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh082d5c6512013-09-06 15:35:05 +0530502 for n in created_subnets:
503 self.assertIsNotNone(n['id'])
504 self.assertIn(n['id'], subnets_list)
505
Jordan Pittier3b46d272017-04-12 16:17:28 +0200506 @decorators.attr(type='smoke')
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800507 @decorators.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
raiesmh082d5c6512013-09-06 15:35:05 +0530508 def test_bulk_create_delete_port(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300509 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530510 # Creates 2 ports in one request
Mark Maglana5885eb32014-02-28 10:57:34 -0800511 names = [data_utils.rand_name('port-') for i in range(len(networks))]
raiesmh082d5c6512013-09-06 15:35:05 +0530512 port_list = []
513 state = [True, False]
514 for i in range(len(names)):
515 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300516 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530517 'name': names[i],
518 'admin_state_up': state[i],
519 }
520 port_list.append(p1)
521 del port_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800522 body = self.ports_client.create_bulk_ports(ports=port_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530523 created_ports = body['ports']
524 self.addCleanup(self._delete_ports, created_ports)
raiesmh082d5c6512013-09-06 15:35:05 +0530525 # Asserting that the ports are found in the list after creation
John Warren49c0fe52015-10-22 12:35:54 -0400526 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800527 ports_list = [port['id'] for port in body['ports']]
raiesmh082d5c6512013-09-06 15:35:05 +0530528 for n in created_ports:
529 self.assertIsNotNone(n['id'])
530 self.assertIn(n['id'], ports_list)
531
raiesmh0867698322013-08-20 13:09:01 +0530532
Tong Liu7012c862016-04-11 22:32:05 +0000533class BulkNetworkOpsIpV6Test(BulkNetworkOpsTest):
Rohan Kanade0efb0232015-02-19 13:33:31 +0530534 _ip_version = 6
535
536
Tong Liu7012c862016-04-11 22:32:05 +0000537class NetworksIpV6Test(NetworksTest):
Henry Gessauffda37a2014-01-16 11:17:55 -0500538 _ip_version = 6
Henry Gessauffda37a2014-01-16 11:17:55 -0500539
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800540 @decorators.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800541 def test_create_delete_subnet_with_gw(self):
Sean Dagueed6e5862016-04-04 10:49:13 -0400542 net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
sridhargaddamea73d532014-05-13 14:48:30 +0530543 gateway = str(netaddr.IPAddress(net.first + 2))
zhufld2c40ca2016-10-18 17:03:07 +0800544 network = self.create_network()
Edgar Magana6a9ac342014-01-16 13:52:49 -0800545 subnet = self.create_subnet(network, gateway)
546 # Verifies Subnet GW in IPv6
547 self.assertEqual(subnet['gateway_ip'], gateway)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800548
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800549 @decorators.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400550 def test_create_delete_subnet_with_default_gw(self):
Sean Dagueed6e5862016-04-04 10:49:13 -0400551 net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
sridhargaddamea73d532014-05-13 14:48:30 +0530552 gateway_ip = str(netaddr.IPAddress(net.first + 1))
zhufld2c40ca2016-10-18 17:03:07 +0800553 network = self.create_network()
Edgar Magana6a9ac342014-01-16 13:52:49 -0800554 subnet = self.create_subnet(network)
555 # Verifies Subnet GW in IPv6
sridhargaddamea73d532014-05-13 14:48:30 +0530556 self.assertEqual(subnet['gateway_ip'], gateway_ip)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800557
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800558 @decorators.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400559 def test_create_list_subnet_with_no_gw64_one_network(self):
zhufld2c40ca2016-10-18 17:03:07 +0800560 network = self.create_network()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400561 ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
562 subnet1 = self.create_subnet(network,
563 ip_version=6,
564 gateway=ipv6_gateway)
565 self.assertEqual(netaddr.IPNetwork(subnet1['cidr']).version, 6,
566 'The created subnet is not IPv6')
567 subnet2 = self.create_subnet(network,
568 gateway=None,
569 ip_version=4)
570 self.assertEqual(netaddr.IPNetwork(subnet2['cidr']).version, 4,
571 'The created subnet is not IPv4')
572 # Verifies Subnet GW is set in IPv6
573 self.assertEqual(subnet1['gateway_ip'], ipv6_gateway)
574 # Verifies Subnet GW is None in IPv4
guo yunxian0306a4a2016-07-29 16:32:28 +0800575 self.assertIsNone(subnet2['gateway_ip'])
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400576 # Verifies all 2 subnets in the same network
John Warren3961acd2015-10-02 14:38:53 -0400577 body = self.subnets_client.list_subnets()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400578 subnets = [sub['id'] for sub in body['subnets']
579 if sub['network_id'] == network['id']]
580 test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
ghanshyam2dee5e32016-06-24 14:42:56 +0900581 six.assertCountEqual(self, subnets,
582 test_subnet_ids,
583 'Subnet are not in the same network')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400584
Sergey She757c332014-11-25 01:16:32 +0300585
Jonte Watford871547c2016-10-10 20:11:04 +0000586class NetworksIpV6TestAttrs(BaseNetworkTestResources):
587
588 _ip_version = 6
Sergey She757c332014-11-25 01:16:32 +0300589
590 @classmethod
Rohan Kanadea565e452015-01-27 14:00:13 +0530591 def skip_checks(cls):
592 super(NetworksIpV6TestAttrs, cls).skip_checks()
Sergey She757c332014-11-25 01:16:32 +0300593 if not CONF.network_feature_enabled.ipv6_subnet_attributes:
594 raise cls.skipException("IPv6 extended attributes for "
595 "subnets not available")
Sergey She757c332014-11-25 01:16:32 +0300596
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800597 @decorators.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400598 def test_create_delete_subnet_with_v6_attributes_stateful(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200599 self._create_verify_delete_subnet(
600 gateway=self._subnet_data[self._ip_version]['gateway'],
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400601 ipv6_ra_mode='dhcpv6-stateful',
602 ipv6_address_mode='dhcpv6-stateful')
603
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800604 @decorators.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400605 def test_create_delete_subnet_with_v6_attributes_slaac(self):
606 self._create_verify_delete_subnet(
Rohan Kanade35589aa2014-08-19 14:56:12 +0200607 ipv6_ra_mode='slaac',
608 ipv6_address_mode='slaac')
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400609
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800610 @decorators.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400611 def test_create_delete_subnet_with_v6_attributes_stateless(self):
612 self._create_verify_delete_subnet(
613 ipv6_ra_mode='dhcpv6-stateless',
614 ipv6_address_mode='dhcpv6-stateless')
Sergey She757c332014-11-25 01:16:32 +0300615
616 def _test_delete_subnet_with_ports(self, mode):
617 """Create subnet and delete it with existing ports"""
618 slaac_network = self.create_network()
619 subnet_slaac = self.create_subnet(slaac_network,
620 **{'ipv6_ra_mode': mode,
621 'ipv6_address_mode': mode})
622 port = self.create_port(slaac_network)
623 self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
John Warren3961acd2015-10-02 14:38:53 -0400624 self.subnets_client.delete_subnet(subnet_slaac['id'])
Sergey She757c332014-11-25 01:16:32 +0300625 self.subnets.pop()
John Warren3961acd2015-10-02 14:38:53 -0400626 subnets = self.subnets_client.list_subnets()
Sergey She757c332014-11-25 01:16:32 +0300627 subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
628 self.assertNotIn(subnet_slaac['id'], subnet_ids,
629 "Subnet wasn't deleted")
reedip6fb7e1a2016-03-10 13:32:01 +0900630 self.assertRaisesRegex(
Masayuki Igawad9388762015-01-20 14:56:42 +0900631 lib_exc.Conflict,
Sergey She757c332014-11-25 01:16:32 +0300632 "There are one or more ports still in use on the network",
John Warren94d8faf2015-09-15 12:22:24 -0400633 self.networks_client.delete_network,
Sergey She757c332014-11-25 01:16:32 +0300634 slaac_network['id'])
635
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800636 @decorators.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
Sergey She757c332014-11-25 01:16:32 +0300637 def test_create_delete_slaac_subnet_with_ports(self):
638 """Test deleting subnet with SLAAC ports
639
640 Create subnet with SLAAC, create ports in network
641 and then you shall be able to delete subnet without port
642 deletion. But you still can not delete the network.
643 """
644 self._test_delete_subnet_with_ports("slaac")
645
Ken'ichi Ohmichi53b9a632017-01-27 18:04:39 -0800646 @decorators.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
Sergey She757c332014-11-25 01:16:32 +0300647 def test_create_delete_stateless_subnet_with_ports(self):
648 """Test deleting subnet with DHCPv6 stateless ports
649
650 Create subnet with DHCPv6 stateless, create ports in network
651 and then you shall be able to delete subnet without port
652 deletion. But you still can not delete the network.
653 """
654 self._test_delete_subnet_with_ports("dhcpv6-stateless")