blob: d916891c511b561834a261e8d66962e600deb629 [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.
Yair Friedbfdfc752014-09-28 13:56:45 +030015import itertools
Jay Pipesf4dad392012-06-05 16:03:58 -040016
Miguel Lavallecc939612013-02-22 17:27:20 -060017import netaddr
Matthew Treinish71426682015-04-23 11:19:38 -040018import six
Jay Pipesf4dad392012-06-05 16:03:58 -040019
Sean Dague1937d092013-05-17 16:36:38 -040020from tempest.api.network import base
Rohan Kanade35589aa2014-08-19 14:56:12 +020021from tempest.common import custom_matchers
Fei Long Wangd39431f2015-05-14 11:30:48 +120022from tempest.common.utils import data_utils
Matthew Treinish03b48df2014-01-29 16:59:49 +000023from tempest import config
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050024from tempest.lib import exceptions as lib_exc
Masayuki Igawa6d495d62014-03-19 16:38:57 +090025from tempest import test
Unmesh Gurjar44986832012-05-08 19:57:10 +053026
Matthew Treinish03b48df2014-01-29 16:59:49 +000027CONF = config.CONF
28
Unmesh Gurjar44986832012-05-08 19:57:10 +053029
Matthew Treinishe4184ea2015-09-03 21:13:09 -040030class NetworksTest(base.BaseNetworkTest):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +000031 """Tests the following operations in the Neutron API:
Miguel Lavallecc939612013-02-22 17:27:20 -060032
33 create a network for a tenant
34 list tenant's networks
35 show a tenant network details
36 create a subnet for a tenant
37 list tenant's subnets
38 show a tenant subnet details
raiesmh08e1aad982013-08-05 14:19:36 +053039 network update
40 subnet update
sukhdevc704a702014-01-15 11:50:56 -080041 delete a network also deletes its subnets
Yair Friedbfdfc752014-09-28 13:56:45 +030042 list external networks
Miguel Lavallecc939612013-02-22 17:27:20 -060043
Henry Gessauffda37a2014-01-16 11:17:55 -050044 All subnet tests are run once with ipv4 and once with ipv6.
45
Mark McClainf2982e82013-07-06 17:48:03 -040046 v2.0 of the Neutron API is assumed. It is also assumed that the following
Miguel Lavallecc939612013-02-22 17:27:20 -060047 options are defined in the [network] section of etc/tempest.conf:
48
49 tenant_network_cidr with a block of cidr's from which smaller blocks
Henry Gessauffda37a2014-01-16 11:17:55 -050050 can be allocated for tenant ipv4 subnets
51
52 tenant_network_v6_cidr is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060053
54 tenant_network_mask_bits with the mask bits to be used to partition the
Henry Gessauffda37a2014-01-16 11:17:55 -050055 block defined by tenant_network_cidr
56
57 tenant_network_v6_mask_bits is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060058 """
59
Unmesh Gurjar44986832012-05-08 19:57:10 +053060 @classmethod
Andrea Frittolida4a2452014-09-15 13:12:08 +010061 def resource_setup(cls):
Matthew Treinishe4184ea2015-09-03 21:13:09 -040062 super(NetworksTest, cls).resource_setup()
Jay Pipesf4dad392012-06-05 16:03:58 -040063 cls.network = cls.create_network()
64 cls.name = cls.network['name']
venakata anil1a2a64a2014-12-02 07:25:59 +000065 cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
66 cls._ip_version)
Rohan Kanade35589aa2014-08-19 14:56:12 +020067 cls._subnet_data = {6: {'gateway':
68 str(cls._get_gateway_from_tempest_conf(6)),
69 'allocation_pools':
70 cls._get_allocation_pools_from_gateway(6),
71 'dns_nameservers': ['2001:4860:4860::8844',
72 '2001:4860:4860::8888'],
73 'host_routes': [{'destination': '2001::/64',
74 'nexthop': '2003::1'}],
75 'new_host_routes': [{'destination':
76 '2001::/64',
77 'nexthop': '2005::1'}],
78 'new_dns_nameservers':
79 ['2001:4860:4860::7744',
80 '2001:4860:4860::7888']},
81 4: {'gateway':
82 str(cls._get_gateway_from_tempest_conf(4)),
83 'allocation_pools':
84 cls._get_allocation_pools_from_gateway(4),
85 'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
86 'host_routes': [{'destination': '10.20.0.0/32',
87 'nexthop': '10.100.1.1'}],
88 'new_host_routes': [{'destination':
89 '10.20.0.0/32',
90 'nexthop':
91 '10.100.1.2'}],
92 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
93
94 @classmethod
venakata anil1a2a64a2014-12-02 07:25:59 +000095 def _create_subnet_with_last_subnet_block(cls, network, ip_version):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +000096 # Derive last subnet CIDR block from tenant CIDR and
97 # create the subnet with that derived CIDR
venakata anil1a2a64a2014-12-02 07:25:59 +000098 if ip_version == 4:
99 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
100 mask_bits = CONF.network.tenant_network_mask_bits
101 elif ip_version == 6:
102 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
103 mask_bits = CONF.network.tenant_network_v6_mask_bits
104
105 subnet_cidr = list(cidr.subnet(mask_bits))[-1]
106 gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
107 return cls.create_subnet(network, gateway=gateway_ip,
108 cidr=subnet_cidr, mask_bits=mask_bits)
109
110 @classmethod
Rohan Kanade35589aa2014-08-19 14:56:12 +0200111 def _get_gateway_from_tempest_conf(cls, ip_version):
112 """Return first subnet gateway for configured CIDR """
113 if ip_version == 4:
114 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
115 mask_bits = CONF.network.tenant_network_mask_bits
116 elif ip_version == 6:
117 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
118 mask_bits = CONF.network.tenant_network_v6_mask_bits
119
120 if mask_bits >= cidr.prefixlen:
121 return netaddr.IPAddress(cidr) + 1
122 else:
123 for subnet in cidr.subnet(mask_bits):
124 return netaddr.IPAddress(subnet) + 1
125
126 @classmethod
127 def _get_allocation_pools_from_gateway(cls, ip_version):
128 """Return allocation range for subnet of given gateway"""
129 gateway = cls._get_gateway_from_tempest_conf(ip_version)
130 return [{'start': str(gateway + 2), 'end': str(gateway + 3)}]
131
132 def subnet_dict(self, include_keys):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000133 # Return a subnet dict which has include_keys and their corresponding
134 # value from self._subnet_data
Rohan Kanade35589aa2014-08-19 14:56:12 +0200135 return dict((key, self._subnet_data[self._ip_version][key])
136 for key in include_keys)
137
138 def _compare_resource_attrs(self, actual, expected):
139 exclude_keys = set(actual).symmetric_difference(expected)
140 self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
141 expected, exclude_keys))
142
venakata anil1a2a64a2014-12-02 07:25:59 +0000143 def _delete_network(self, network):
144 # Deleting network also deletes its subnets if exists
John Warren94d8faf2015-09-15 12:22:24 -0400145 self.networks_client.delete_network(network['id'])
venakata anil1a2a64a2014-12-02 07:25:59 +0000146 if network in self.networks:
147 self.networks.remove(network)
148 for subnet in self.subnets:
149 if subnet['network_id'] == network['id']:
150 self.subnets.remove(subnet)
151
Rohan Kanade35589aa2014-08-19 14:56:12 +0200152 def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
153 **kwargs):
154 network = self.create_network()
155 net_id = network['id']
156 gateway = kwargs.pop('gateway', None)
157 subnet = self.create_subnet(network, gateway, cidr, mask_bits,
158 **kwargs)
159 compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
160 mask_bits=mask_bits, **kwargs)
Matthew Treinish71426682015-04-23 11:19:38 -0400161 compare_args = dict((k, v) for k, v in six.iteritems(compare_args_full)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200162 if v is not None)
163
164 if 'dns_nameservers' in set(subnet).intersection(compare_args):
165 self.assertEqual(sorted(compare_args['dns_nameservers']),
166 sorted(subnet['dns_nameservers']))
167 del subnet['dns_nameservers'], compare_args['dns_nameservers']
168
169 self._compare_resource_attrs(subnet, compare_args)
John Warren94d8faf2015-09-15 12:22:24 -0400170 self.networks_client.delete_network(net_id)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200171 self.networks.pop()
172 self.subnets.pop()
Unmesh Gurjar44986832012-05-08 19:57:10 +0530173
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900174 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800175 @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
raiesmh08e1aad982013-08-05 14:19:36 +0530176 def test_create_update_delete_network_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800177 # Create a network
Masayuki Igawa259c1132013-10-31 17:48:44 +0900178 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200179 network = self.create_network(network_name=name)
venakata anil1a2a64a2014-12-02 07:25:59 +0000180 self.addCleanup(self._delete_network, network)
raiesmh08e1aad982013-08-05 14:19:36 +0530181 net_id = network['id']
Santosh Kumar42c94802014-08-08 04:31:42 -0700182 self.assertEqual('ACTIVE', network['status'])
Mark Maglana5885eb32014-02-28 10:57:34 -0800183 # Verify network update
raiesmh08e1aad982013-08-05 14:19:36 +0530184 new_name = "New_network"
John Warren94d8faf2015-09-15 12:22:24 -0400185 body = self.networks_client.update_network(net_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530186 updated_net = body['network']
187 self.assertEqual(updated_net['name'], new_name)
Miguel Lavallecc939612013-02-22 17:27:20 -0600188 # Find a cidr that is not in use yet and create a subnet with it
Matthew Treinish6b8cd2a2014-03-03 20:45:56 +0000189 subnet = self.create_subnet(network)
raiesmh08e1aad982013-08-05 14:19:36 +0530190 subnet_id = subnet['id']
Mark Maglana5885eb32014-02-28 10:57:34 -0800191 # Verify subnet update
192 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400193 body = self.subnets_client.update_subnet(subnet_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530194 updated_subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800195 self.assertEqual(updated_subnet['name'], new_name)
Unmesh Gurjar44986832012-05-08 19:57:10 +0530196
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900197 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800198 @test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530199 def test_show_network(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800200 # Verify the details of a network
John Warren94d8faf2015-09-15 12:22:24 -0400201 body = self.networks_client.show_network(self.network['id'])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530202 network = body['network']
Mark Maglana5885eb32014-02-28 10:57:34 -0800203 for key in ['id', 'name']:
204 self.assertEqual(network[key], self.network[key])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530205
Chris Hoge7579c1a2015-02-26 14:12:15 -0800206 @test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
jun xied557d9b2014-01-09 14:00:36 +0800207 def test_show_network_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800208 # Verify specific fields of a network
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500209 fields = ['id', 'name']
John Warren94d8faf2015-09-15 12:22:24 -0400210 body = self.networks_client.show_network(self.network['id'],
211 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800212 network = body['network']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500213 self.assertEqual(sorted(network.keys()), sorted(fields))
214 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800215 self.assertEqual(network[field_name], self.network[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800216
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900217 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800218 @test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530219 def test_list_networks(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500220 # Verify the network exists in the list of all networks
John Warren94d8faf2015-09-15 12:22:24 -0400221 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800222 networks = [network['id'] for network in body['networks']
223 if network['id'] == self.network['id']]
224 self.assertNotEmpty(networks, "Created network not found in the list")
Unmesh Gurjar44986832012-05-08 19:57:10 +0530225
Chris Hoge7579c1a2015-02-26 14:12:15 -0800226 @test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
jun xie0b4735d2014-01-07 15:42:58 +0800227 def test_list_networks_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800228 # Verify specific fields of the networks
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500229 fields = ['id', 'name']
John Warren94d8faf2015-09-15 12:22:24 -0400230 body = self.networks_client.list_networks(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800231 networks = body['networks']
Mark Maglana5885eb32014-02-28 10:57:34 -0800232 self.assertNotEmpty(networks, "Network list returned is empty")
233 for network in networks:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500234 self.assertEqual(sorted(network.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800235
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900236 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800237 @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
Miguel Lavallecc939612013-02-22 17:27:20 -0600238 def test_show_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800239 # Verify the details of a subnet
John Warren3961acd2015-10-02 14:38:53 -0400240 body = self.subnets_client.show_subnet(self.subnet['id'])
Miguel Lavallecc939612013-02-22 17:27:20 -0600241 subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800242 self.assertNotEmpty(subnet, "Subnet returned has no fields")
243 for key in ['id', 'cidr']:
244 self.assertIn(key, subnet)
245 self.assertEqual(subnet[key], self.subnet[key])
Miguel Lavallecc939612013-02-22 17:27:20 -0600246
Chris Hoge7579c1a2015-02-26 14:12:15 -0800247 @test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
jun xied557d9b2014-01-09 14:00:36 +0800248 def test_show_subnet_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800249 # Verify specific fields of a subnet
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500250 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400251 body = self.subnets_client.show_subnet(self.subnet['id'],
252 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800253 subnet = body['subnet']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500254 self.assertEqual(sorted(subnet.keys()), sorted(fields))
255 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800256 self.assertEqual(subnet[field_name], self.subnet[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800257
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900258 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800259 @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
Miguel Lavallecc939612013-02-22 17:27:20 -0600260 def test_list_subnets(self):
261 # Verify the subnet exists in the list of all subnets
John Warren3961acd2015-10-02 14:38:53 -0400262 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800263 subnets = [subnet['id'] for subnet in body['subnets']
264 if subnet['id'] == self.subnet['id']]
265 self.assertNotEmpty(subnets, "Created subnet not found in the list")
raiesmh08e1aad982013-08-05 14:19:36 +0530266
Chris Hoge7579c1a2015-02-26 14:12:15 -0800267 @test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
jun xie0b4735d2014-01-07 15:42:58 +0800268 def test_list_subnets_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800269 # Verify specific fields of subnets
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500270 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400271 body = self.subnets_client.list_subnets(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800272 subnets = body['subnets']
Mark Maglana5885eb32014-02-28 10:57:34 -0800273 self.assertNotEmpty(subnets, "Subnet list returned is empty")
274 for subnet in subnets:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500275 self.assertEqual(sorted(subnet.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800276
sukhdevc704a702014-01-15 11:50:56 -0800277 def _try_delete_network(self, net_id):
278 # delete network, if it exists
279 try:
John Warren94d8faf2015-09-15 12:22:24 -0400280 self.networks_client.delete_network(net_id)
sukhdevc704a702014-01-15 11:50:56 -0800281 # if network is not found, this means it was deleted in the test
Masayuki Igawabfa07602015-01-20 18:47:17 +0900282 except lib_exc.NotFound:
sukhdevc704a702014-01-15 11:50:56 -0800283 pass
284
Chris Hoge7579c1a2015-02-26 14:12:15 -0800285 @test.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
288 name = data_utils.rand_name('network-')
John Warren94d8faf2015-09-15 12:22:24 -0400289 body = self.networks_client.create_network(name=name)
sukhdevc704a702014-01-15 11:50:56 -0800290 network = body['network']
291 net_id = network['id']
292 self.addCleanup(self._try_delete_network, net_id)
293
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
John Warren94d8faf2015-09-15 12:22:24 -0400299 body = 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
305 # Since create_subnet adds the subnet to the delete list, and it is
306 # is actually deleted here - this will create and issue, hence remove
307 # it from the list.
308 self.subnets.pop()
309
Chris Hoge7579c1a2015-02-26 14:12:15 -0800310 @test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400311 def test_create_delete_subnet_without_gateway(self):
312 self._create_verify_delete_subnet()
313
Chris Hoge7579c1a2015-02-26 14:12:15 -0800314 @test.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800315 def test_create_delete_subnet_with_gw(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200316 self._create_verify_delete_subnet(
317 **self.subnet_dict(['gateway']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800318
Chris Hoge7579c1a2015-02-26 14:12:15 -0800319 @test.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200320 def test_create_delete_subnet_with_allocation_pools(self):
321 self._create_verify_delete_subnet(
322 **self.subnet_dict(['allocation_pools']))
323
Chris Hoge7579c1a2015-02-26 14:12:15 -0800324 @test.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200325 def test_create_delete_subnet_with_gw_and_allocation_pools(self):
326 self._create_verify_delete_subnet(**self.subnet_dict(
327 ['gateway', 'allocation_pools']))
328
Chris Hoge7579c1a2015-02-26 14:12:15 -0800329 @test.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200330 def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
331 self._create_verify_delete_subnet(
332 **self.subnet_dict(['host_routes', 'dns_nameservers']))
333
Chris Hoge7579c1a2015-02-26 14:12:15 -0800334 @test.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200335 def test_create_delete_subnet_with_dhcp_enabled(self):
336 self._create_verify_delete_subnet(enable_dhcp=True)
337
Chris Hoge7579c1a2015-02-26 14:12:15 -0800338 @test.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200339 def test_update_subnet_gw_dns_host_routes_dhcp(self):
340 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000341 self.addCleanup(self._delete_network, network)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200342
343 subnet = self.create_subnet(
344 network, **self.subnet_dict(['gateway', 'host_routes',
345 'dns_nameservers',
346 'allocation_pools']))
347 subnet_id = subnet['id']
348 new_gateway = str(netaddr.IPAddress(
349 self._subnet_data[self._ip_version]['gateway']) + 1)
350 # Verify subnet update
351 new_host_routes = self._subnet_data[self._ip_version][
352 'new_host_routes']
353
354 new_dns_nameservers = self._subnet_data[self._ip_version][
355 'new_dns_nameservers']
356 kwargs = {'host_routes': new_host_routes,
357 'dns_nameservers': new_dns_nameservers,
358 'gateway_ip': new_gateway, 'enable_dhcp': True}
359
360 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400361 body = self.subnets_client.update_subnet(subnet_id, name=new_name,
362 **kwargs)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200363 updated_subnet = body['subnet']
364 kwargs['name'] = new_name
365 self.assertEqual(sorted(updated_subnet['dns_nameservers']),
366 sorted(kwargs['dns_nameservers']))
367 del subnet['dns_nameservers'], kwargs['dns_nameservers']
368
369 self._compare_resource_attrs(updated_subnet, kwargs)
370
Chris Hoge7579c1a2015-02-26 14:12:15 -0800371 @test.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200372 def test_create_delete_subnet_all_attributes(self):
373 self._create_verify_delete_subnet(
374 enable_dhcp=True,
375 **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800376
Yair Friedbfdfc752014-09-28 13:56:45 +0300377 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800378 @test.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
Yair Friedbfdfc752014-09-28 13:56:45 +0300379 def test_external_network_visibility(self):
380 """Verifies user can see external networks but not subnets."""
John Warren94d8faf2015-09-15 12:22:24 -0400381 body = self.networks_client.list_networks(**{'router:external': True})
Yair Friedbfdfc752014-09-28 13:56:45 +0300382 networks = [network['id'] for network in body['networks']]
383 self.assertNotEmpty(networks, "No external networks found")
384
385 nonexternal = [net for net in body['networks'] if
386 not net['router:external']]
387 self.assertEmpty(nonexternal, "Found non-external networks"
388 " in filtered list (%s)." % nonexternal)
389 self.assertIn(CONF.network.public_network_id, networks)
390
Xavier León3aa65342015-05-12 15:24:28 +0000391 subnets_iter = (network['subnets']
392 for network in body['networks']
393 if not network['shared'])
Yair Friedbfdfc752014-09-28 13:56:45 +0300394 # subnets_iter is a list (iterator) of lists. This flattens it to a
395 # list of UUIDs
396 public_subnets_iter = itertools.chain(*subnets_iter)
John Warren3961acd2015-10-02 14:38:53 -0400397 body = self.subnets_client.list_subnets()
Yair Friedbfdfc752014-09-28 13:56:45 +0300398 subnets = [sub['id'] for sub in body['subnets']
399 if sub['id'] in public_subnets_iter]
400 self.assertEmpty(subnets, "Public subnets visible")
401
raiesmh086b055e22013-09-16 12:59:57 +0530402
Ken'ichi Ohmichi91c675d2014-02-06 02:15:21 +0900403class BulkNetworkOpsTestJSON(base.BaseNetworkTest):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000404 """Tests the following operations in the Neutron API:
raiesmh086b055e22013-09-16 12:59:57 +0530405
406 bulk network creation
407 bulk subnet creation
Eugene Nikanorove9d255a2013-12-18 16:31:42 +0400408 bulk port creation
raiesmh086b055e22013-09-16 12:59:57 +0530409 list tenant's networks
410
411 v2.0 of the Neutron API is assumed. It is also assumed that the following
412 options are defined in the [network] section of etc/tempest.conf:
413
414 tenant_network_cidr with a block of cidr's from which smaller blocks
415 can be allocated for tenant networks
416
417 tenant_network_mask_bits with the mask bits to be used to partition the
418 block defined by tenant-network_cidr
419 """
420
raiesmh086b055e22013-09-16 12:59:57 +0530421 def _delete_networks(self, created_networks):
422 for n in created_networks:
John Warren94d8faf2015-09-15 12:22:24 -0400423 self.networks_client.delete_network(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530424 # Asserting that the networks are not found in the list after deletion
John Warren94d8faf2015-09-15 12:22:24 -0400425 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800426 networks_list = [network['id'] for network in body['networks']]
raiesmh086b055e22013-09-16 12:59:57 +0530427 for n in created_networks:
428 self.assertNotIn(n['id'], networks_list)
429
430 def _delete_subnets(self, created_subnets):
431 for n in created_subnets:
John Warren3961acd2015-10-02 14:38:53 -0400432 self.subnets_client.delete_subnet(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530433 # Asserting that the subnets are not found in the list after deletion
John Warren3961acd2015-10-02 14:38:53 -0400434 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800435 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh086b055e22013-09-16 12:59:57 +0530436 for n in created_subnets:
437 self.assertNotIn(n['id'], subnets_list)
438
439 def _delete_ports(self, created_ports):
440 for n in created_ports:
John Warren49c0fe52015-10-22 12:35:54 -0400441 self.ports_client.delete_port(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530442 # Asserting that the ports are not found in the list after deletion
John Warren49c0fe52015-10-22 12:35:54 -0400443 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800444 ports_list = [port['id'] for port in body['ports']]
raiesmh086b055e22013-09-16 12:59:57 +0530445 for n in created_ports:
446 self.assertNotIn(n['id'], ports_list)
447
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900448 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800449 @test.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
Nayna Patelb03eab42013-08-08 08:58:48 +0000450 def test_bulk_create_delete_network(self):
451 # Creates 2 networks in one request
piyush1107867584aa72015-12-15 18:46:38 +0530452 network_list = [{'name': data_utils.rand_name('network-')},
453 {'name': data_utils.rand_name('network-')}]
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800454 body = self.networks_client.create_bulk_networks(networks=network_list)
Nayna Patelb03eab42013-08-08 08:58:48 +0000455 created_networks = body['networks']
Nayna Patelb03eab42013-08-08 08:58:48 +0000456 self.addCleanup(self._delete_networks, created_networks)
457 # Asserting that the networks are found in the list after creation
John Warren94d8faf2015-09-15 12:22:24 -0400458 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800459 networks_list = [network['id'] for network in body['networks']]
Nayna Patelb03eab42013-08-08 08:58:48 +0000460 for n in created_networks:
461 self.assertIsNotNone(n['id'])
462 self.assertIn(n['id'], networks_list)
raiesmh0867698322013-08-20 13:09:01 +0530463
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900464 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800465 @test.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
raiesmh082d5c6512013-09-06 15:35:05 +0530466 def test_bulk_create_delete_subnet(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300467 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530468 # Creates 2 subnets in one request
Rohan Kanade0efb0232015-02-19 13:33:31 +0530469 if self._ip_version == 4:
470 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
471 mask_bits = CONF.network.tenant_network_mask_bits
472 else:
473 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
474 mask_bits = CONF.network.tenant_network_v6_mask_bits
475
Mark Maglana5885eb32014-02-28 10:57:34 -0800476 cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
Rohan Kanade0efb0232015-02-19 13:33:31 +0530477
Mark Maglana5885eb32014-02-28 10:57:34 -0800478 names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
479 subnets_list = []
raiesmh082d5c6512013-09-06 15:35:05 +0530480 for i in range(len(names)):
481 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300482 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530483 'cidr': str(cidrs[(i)]),
484 'name': names[i],
Rohan Kanade0efb0232015-02-19 13:33:31 +0530485 'ip_version': self._ip_version
raiesmh082d5c6512013-09-06 15:35:05 +0530486 }
Mark Maglana5885eb32014-02-28 10:57:34 -0800487 subnets_list.append(p1)
488 del subnets_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800489 body = self.subnets_client.create_bulk_subnets(subnets=subnets_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530490 created_subnets = body['subnets']
491 self.addCleanup(self._delete_subnets, created_subnets)
raiesmh082d5c6512013-09-06 15:35:05 +0530492 # Asserting that the subnets are found in the list after creation
John Warren3961acd2015-10-02 14:38:53 -0400493 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800494 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh082d5c6512013-09-06 15:35:05 +0530495 for n in created_subnets:
496 self.assertIsNotNone(n['id'])
497 self.assertIn(n['id'], subnets_list)
498
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900499 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800500 @test.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
raiesmh082d5c6512013-09-06 15:35:05 +0530501 def test_bulk_create_delete_port(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300502 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530503 # Creates 2 ports in one request
Mark Maglana5885eb32014-02-28 10:57:34 -0800504 names = [data_utils.rand_name('port-') for i in range(len(networks))]
raiesmh082d5c6512013-09-06 15:35:05 +0530505 port_list = []
506 state = [True, False]
507 for i in range(len(names)):
508 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300509 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530510 'name': names[i],
511 'admin_state_up': state[i],
512 }
513 port_list.append(p1)
514 del port_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800515 body = self.ports_client.create_bulk_ports(ports=port_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530516 created_ports = body['ports']
517 self.addCleanup(self._delete_ports, created_ports)
raiesmh082d5c6512013-09-06 15:35:05 +0530518 # Asserting that the ports are found in the list after creation
John Warren49c0fe52015-10-22 12:35:54 -0400519 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800520 ports_list = [port['id'] for port in body['ports']]
raiesmh082d5c6512013-09-06 15:35:05 +0530521 for n in created_ports:
522 self.assertIsNotNone(n['id'])
523 self.assertIn(n['id'], ports_list)
524
raiesmh0867698322013-08-20 13:09:01 +0530525
Rohan Kanade0efb0232015-02-19 13:33:31 +0530526class BulkNetworkOpsIpV6TestJSON(BulkNetworkOpsTestJSON):
527 _ip_version = 6
528
529
Matthew Treinishe4184ea2015-09-03 21:13:09 -0400530class NetworksIpV6TestJSON(NetworksTest):
Henry Gessauffda37a2014-01-16 11:17:55 -0500531 _ip_version = 6
Henry Gessauffda37a2014-01-16 11:17:55 -0500532
Chris Hoge7579c1a2015-02-26 14:12:15 -0800533 @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800534 def test_create_delete_subnet_with_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530535 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
536 gateway = str(netaddr.IPAddress(net.first + 2))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800537 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200538 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800539 subnet = self.create_subnet(network, gateway)
540 # Verifies Subnet GW in IPv6
541 self.assertEqual(subnet['gateway_ip'], gateway)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800542
Chris Hoge7579c1a2015-02-26 14:12:15 -0800543 @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400544 def test_create_delete_subnet_with_default_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530545 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
546 gateway_ip = str(netaddr.IPAddress(net.first + 1))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800547 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200548 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800549 subnet = self.create_subnet(network)
550 # Verifies Subnet GW in IPv6
sridhargaddamea73d532014-05-13 14:48:30 +0530551 self.assertEqual(subnet['gateway_ip'], gateway_ip)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800552
Chris Hoge7579c1a2015-02-26 14:12:15 -0800553 @test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400554 def test_create_list_subnet_with_no_gw64_one_network(self):
555 name = data_utils.rand_name('network-')
556 network = self.create_network(name)
557 ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
558 subnet1 = self.create_subnet(network,
559 ip_version=6,
560 gateway=ipv6_gateway)
561 self.assertEqual(netaddr.IPNetwork(subnet1['cidr']).version, 6,
562 'The created subnet is not IPv6')
563 subnet2 = self.create_subnet(network,
564 gateway=None,
565 ip_version=4)
566 self.assertEqual(netaddr.IPNetwork(subnet2['cidr']).version, 4,
567 'The created subnet is not IPv4')
568 # Verifies Subnet GW is set in IPv6
569 self.assertEqual(subnet1['gateway_ip'], ipv6_gateway)
570 # Verifies Subnet GW is None in IPv4
571 self.assertEqual(subnet2['gateway_ip'], None)
572 # Verifies all 2 subnets in the same network
John Warren3961acd2015-10-02 14:38:53 -0400573 body = self.subnets_client.list_subnets()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400574 subnets = [sub['id'] for sub in body['subnets']
575 if sub['network_id'] == network['id']]
576 test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
577 self.assertItemsEqual(subnets,
578 test_subnet_ids,
579 'Subnet are not in the same network')
580
Sergey She757c332014-11-25 01:16:32 +0300581
582class NetworksIpV6TestAttrs(NetworksIpV6TestJSON):
583
584 @classmethod
Rohan Kanadea565e452015-01-27 14:00:13 +0530585 def skip_checks(cls):
586 super(NetworksIpV6TestAttrs, cls).skip_checks()
Sergey She757c332014-11-25 01:16:32 +0300587 if not CONF.network_feature_enabled.ipv6_subnet_attributes:
588 raise cls.skipException("IPv6 extended attributes for "
589 "subnets not available")
Sergey She757c332014-11-25 01:16:32 +0300590
Chris Hoge7579c1a2015-02-26 14:12:15 -0800591 @test.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400592 def test_create_delete_subnet_with_v6_attributes_stateful(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200593 self._create_verify_delete_subnet(
594 gateway=self._subnet_data[self._ip_version]['gateway'],
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400595 ipv6_ra_mode='dhcpv6-stateful',
596 ipv6_address_mode='dhcpv6-stateful')
597
Chris Hoge7579c1a2015-02-26 14:12:15 -0800598 @test.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400599 def test_create_delete_subnet_with_v6_attributes_slaac(self):
600 self._create_verify_delete_subnet(
Rohan Kanade35589aa2014-08-19 14:56:12 +0200601 ipv6_ra_mode='slaac',
602 ipv6_address_mode='slaac')
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400603
Chris Hoge7579c1a2015-02-26 14:12:15 -0800604 @test.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400605 def test_create_delete_subnet_with_v6_attributes_stateless(self):
606 self._create_verify_delete_subnet(
607 ipv6_ra_mode='dhcpv6-stateless',
608 ipv6_address_mode='dhcpv6-stateless')
Sergey She757c332014-11-25 01:16:32 +0300609
610 def _test_delete_subnet_with_ports(self, mode):
611 """Create subnet and delete it with existing ports"""
612 slaac_network = self.create_network()
613 subnet_slaac = self.create_subnet(slaac_network,
614 **{'ipv6_ra_mode': mode,
615 'ipv6_address_mode': mode})
616 port = self.create_port(slaac_network)
617 self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
John Warren3961acd2015-10-02 14:38:53 -0400618 self.subnets_client.delete_subnet(subnet_slaac['id'])
Sergey She757c332014-11-25 01:16:32 +0300619 self.subnets.pop()
John Warren3961acd2015-10-02 14:38:53 -0400620 subnets = self.subnets_client.list_subnets()
Sergey She757c332014-11-25 01:16:32 +0300621 subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
622 self.assertNotIn(subnet_slaac['id'], subnet_ids,
623 "Subnet wasn't deleted")
reedip6fb7e1a2016-03-10 13:32:01 +0900624 self.assertRaisesRegex(
Masayuki Igawad9388762015-01-20 14:56:42 +0900625 lib_exc.Conflict,
Sergey She757c332014-11-25 01:16:32 +0300626 "There are one or more ports still in use on the network",
John Warren94d8faf2015-09-15 12:22:24 -0400627 self.networks_client.delete_network,
Sergey She757c332014-11-25 01:16:32 +0300628 slaac_network['id'])
629
Chris Hoge7579c1a2015-02-26 14:12:15 -0800630 @test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
Sergey She757c332014-11-25 01:16:32 +0300631 def test_create_delete_slaac_subnet_with_ports(self):
632 """Test deleting subnet with SLAAC ports
633
634 Create subnet with SLAAC, create ports in network
635 and then you shall be able to delete subnet without port
636 deletion. But you still can not delete the network.
637 """
638 self._test_delete_subnet_with_ports("slaac")
639
Chris Hoge7579c1a2015-02-26 14:12:15 -0800640 @test.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
Sergey She757c332014-11-25 01:16:32 +0300641 def test_create_delete_stateless_subnet_with_ports(self):
642 """Test deleting subnet with DHCPv6 stateless ports
643
644 Create subnet with DHCPv6 stateless, create ports in network
645 and then you shall be able to delete subnet without port
646 deletion. But you still can not delete the network.
647 """
648 self._test_delete_subnet_with_ports("dhcpv6-stateless")