blob: e70519e1e1a26929019ea7f2b312ca812f6af3fe [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
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -040018import testtools
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
Masayuki Igawa259c1132013-10-31 17:48:44 +090022from tempest.common.utils import data_utils
Matthew Treinish03b48df2014-01-29 16:59:49 +000023from tempest import config
sukhdevc704a702014-01-15 11:50:56 -080024from tempest import exceptions
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
raiesmh0867698322013-08-20 13:09:01 +053030class NetworksTestJSON(base.BaseNetworkTest):
31 _interface = 'json'
Unmesh Gurjar44986832012-05-08 19:57:10 +053032
Miguel Lavallecc939612013-02-22 17:27:20 -060033 """
Mark McClainf2982e82013-07-06 17:48:03 -040034 Tests the following operations in the Neutron API using the REST client for
35 Neutron:
Miguel Lavallecc939612013-02-22 17:27:20 -060036
37 create a network for a tenant
38 list tenant's networks
39 show a tenant network details
40 create a subnet for a tenant
41 list tenant's subnets
42 show a tenant subnet details
raiesmh08e1aad982013-08-05 14:19:36 +053043 network update
44 subnet update
sukhdevc704a702014-01-15 11:50:56 -080045 delete a network also deletes its subnets
Yair Friedbfdfc752014-09-28 13:56:45 +030046 list external networks
Miguel Lavallecc939612013-02-22 17:27:20 -060047
Henry Gessauffda37a2014-01-16 11:17:55 -050048 All subnet tests are run once with ipv4 and once with ipv6.
49
Mark McClainf2982e82013-07-06 17:48:03 -040050 v2.0 of the Neutron API is assumed. It is also assumed that the following
Miguel Lavallecc939612013-02-22 17:27:20 -060051 options are defined in the [network] section of etc/tempest.conf:
52
53 tenant_network_cidr with a block of cidr's from which smaller blocks
Henry Gessauffda37a2014-01-16 11:17:55 -050054 can be allocated for tenant ipv4 subnets
55
56 tenant_network_v6_cidr is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060057
58 tenant_network_mask_bits with the mask bits to be used to partition the
Henry Gessauffda37a2014-01-16 11:17:55 -050059 block defined by tenant_network_cidr
60
61 tenant_network_v6_mask_bits is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060062 """
63
Unmesh Gurjar44986832012-05-08 19:57:10 +053064 @classmethod
Andrea Frittolida4a2452014-09-15 13:12:08 +010065 def resource_setup(cls):
66 super(NetworksTestJSON, cls).resource_setup()
Jay Pipesf4dad392012-06-05 16:03:58 -040067 cls.network = cls.create_network()
68 cls.name = cls.network['name']
venakata anil1a2a64a2014-12-02 07:25:59 +000069 cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
70 cls._ip_version)
Miguel Lavallecc939612013-02-22 17:27:20 -060071 cls.cidr = cls.subnet['cidr']
Rohan Kanade35589aa2014-08-19 14:56:12 +020072 cls._subnet_data = {6: {'gateway':
73 str(cls._get_gateway_from_tempest_conf(6)),
74 'allocation_pools':
75 cls._get_allocation_pools_from_gateway(6),
76 'dns_nameservers': ['2001:4860:4860::8844',
77 '2001:4860:4860::8888'],
78 'host_routes': [{'destination': '2001::/64',
79 'nexthop': '2003::1'}],
80 'new_host_routes': [{'destination':
81 '2001::/64',
82 'nexthop': '2005::1'}],
83 'new_dns_nameservers':
84 ['2001:4860:4860::7744',
85 '2001:4860:4860::7888']},
86 4: {'gateway':
87 str(cls._get_gateway_from_tempest_conf(4)),
88 'allocation_pools':
89 cls._get_allocation_pools_from_gateway(4),
90 'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
91 'host_routes': [{'destination': '10.20.0.0/32',
92 'nexthop': '10.100.1.1'}],
93 'new_host_routes': [{'destination':
94 '10.20.0.0/32',
95 'nexthop':
96 '10.100.1.2'}],
97 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
98
99 @classmethod
venakata anil1a2a64a2014-12-02 07:25:59 +0000100 def _create_subnet_with_last_subnet_block(cls, network, ip_version):
101 """Derive last subnet CIDR block from tenant CIDR and
102 create the subnet with that derived CIDR
103 """
104 if ip_version == 4:
105 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
106 mask_bits = CONF.network.tenant_network_mask_bits
107 elif ip_version == 6:
108 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
109 mask_bits = CONF.network.tenant_network_v6_mask_bits
110
111 subnet_cidr = list(cidr.subnet(mask_bits))[-1]
112 gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
113 return cls.create_subnet(network, gateway=gateway_ip,
114 cidr=subnet_cidr, mask_bits=mask_bits)
115
116 @classmethod
Rohan Kanade35589aa2014-08-19 14:56:12 +0200117 def _get_gateway_from_tempest_conf(cls, ip_version):
118 """Return first subnet gateway for configured CIDR """
119 if ip_version == 4:
120 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
121 mask_bits = CONF.network.tenant_network_mask_bits
122 elif ip_version == 6:
123 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
124 mask_bits = CONF.network.tenant_network_v6_mask_bits
125
126 if mask_bits >= cidr.prefixlen:
127 return netaddr.IPAddress(cidr) + 1
128 else:
129 for subnet in cidr.subnet(mask_bits):
130 return netaddr.IPAddress(subnet) + 1
131
132 @classmethod
133 def _get_allocation_pools_from_gateway(cls, ip_version):
134 """Return allocation range for subnet of given gateway"""
135 gateway = cls._get_gateway_from_tempest_conf(ip_version)
136 return [{'start': str(gateway + 2), 'end': str(gateway + 3)}]
137
138 def subnet_dict(self, include_keys):
139 """Return a subnet dict which has include_keys and their corresponding
140 value from self._subnet_data
141 """
142 return dict((key, self._subnet_data[self._ip_version][key])
143 for key in include_keys)
144
145 def _compare_resource_attrs(self, actual, expected):
146 exclude_keys = set(actual).symmetric_difference(expected)
147 self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
148 expected, exclude_keys))
149
venakata anil1a2a64a2014-12-02 07:25:59 +0000150 def _delete_network(self, network):
151 # Deleting network also deletes its subnets if exists
152 self.client.delete_network(network['id'])
153 if network in self.networks:
154 self.networks.remove(network)
155 for subnet in self.subnets:
156 if subnet['network_id'] == network['id']:
157 self.subnets.remove(subnet)
158
Rohan Kanade35589aa2014-08-19 14:56:12 +0200159 def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
160 **kwargs):
161 network = self.create_network()
162 net_id = network['id']
163 gateway = kwargs.pop('gateway', None)
164 subnet = self.create_subnet(network, gateway, cidr, mask_bits,
165 **kwargs)
166 compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
167 mask_bits=mask_bits, **kwargs)
168 compare_args = dict((k, v) for k, v in compare_args_full.iteritems()
169 if v is not None)
170
171 if 'dns_nameservers' in set(subnet).intersection(compare_args):
172 self.assertEqual(sorted(compare_args['dns_nameservers']),
173 sorted(subnet['dns_nameservers']))
174 del subnet['dns_nameservers'], compare_args['dns_nameservers']
175
176 self._compare_resource_attrs(subnet, compare_args)
177 self.client.delete_network(net_id)
178 self.networks.pop()
179 self.subnets.pop()
Unmesh Gurjar44986832012-05-08 19:57:10 +0530180
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900181 @test.attr(type='smoke')
raiesmh08e1aad982013-08-05 14:19:36 +0530182 def test_create_update_delete_network_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800183 # Create a network
Masayuki Igawa259c1132013-10-31 17:48:44 +0900184 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200185 network = self.create_network(network_name=name)
venakata anil1a2a64a2014-12-02 07:25:59 +0000186 self.addCleanup(self._delete_network, network)
raiesmh08e1aad982013-08-05 14:19:36 +0530187 net_id = network['id']
Santosh Kumar42c94802014-08-08 04:31:42 -0700188 self.assertEqual('ACTIVE', network['status'])
Mark Maglana5885eb32014-02-28 10:57:34 -0800189 # Verify network update
raiesmh08e1aad982013-08-05 14:19:36 +0530190 new_name = "New_network"
David Kranz34e88122014-12-11 15:24:05 -0500191 body = self.client.update_network(net_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530192 updated_net = body['network']
193 self.assertEqual(updated_net['name'], new_name)
Miguel Lavallecc939612013-02-22 17:27:20 -0600194 # Find a cidr that is not in use yet and create a subnet with it
Matthew Treinish6b8cd2a2014-03-03 20:45:56 +0000195 subnet = self.create_subnet(network)
raiesmh08e1aad982013-08-05 14:19:36 +0530196 subnet_id = subnet['id']
Mark Maglana5885eb32014-02-28 10:57:34 -0800197 # Verify subnet update
198 new_name = "New_subnet"
David Kranz34e88122014-12-11 15:24:05 -0500199 body = self.client.update_subnet(subnet_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530200 updated_subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800201 self.assertEqual(updated_subnet['name'], new_name)
Unmesh Gurjar44986832012-05-08 19:57:10 +0530202
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900203 @test.attr(type='smoke')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530204 def test_show_network(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800205 # Verify the details of a network
David Kranz34e88122014-12-11 15:24:05 -0500206 body = self.client.show_network(self.network['id'])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530207 network = body['network']
Mark Maglana5885eb32014-02-28 10:57:34 -0800208 for key in ['id', 'name']:
209 self.assertEqual(network[key], self.network[key])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530210
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900211 @test.attr(type='smoke')
jun xied557d9b2014-01-09 14:00:36 +0800212 def test_show_network_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800213 # Verify specific fields of a network
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500214 fields = ['id', 'name']
David Kranz34e88122014-12-11 15:24:05 -0500215 body = self.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])
jun xied557d9b2014-01-09 14:00:36 +0800221
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900222 @test.attr(type='smoke')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530223 def test_list_networks(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500224 # Verify the network exists in the list of all networks
David Kranz34e88122014-12-11 15:24:05 -0500225 body = self.client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800226 networks = [network['id'] for network in body['networks']
227 if network['id'] == self.network['id']]
228 self.assertNotEmpty(networks, "Created network not found in the list")
Unmesh Gurjar44986832012-05-08 19:57:10 +0530229
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900230 @test.attr(type='smoke')
jun xie0b4735d2014-01-07 15:42:58 +0800231 def test_list_networks_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800232 # Verify specific fields of the networks
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500233 fields = ['id', 'name']
David Kranz34e88122014-12-11 15:24:05 -0500234 body = self.client.list_networks(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800235 networks = body['networks']
Mark Maglana5885eb32014-02-28 10:57:34 -0800236 self.assertNotEmpty(networks, "Network list returned is empty")
237 for network in networks:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500238 self.assertEqual(sorted(network.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800239
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900240 @test.attr(type='smoke')
Miguel Lavallecc939612013-02-22 17:27:20 -0600241 def test_show_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800242 # Verify the details of a subnet
David Kranz34e88122014-12-11 15:24:05 -0500243 body = self.client.show_subnet(self.subnet['id'])
Miguel Lavallecc939612013-02-22 17:27:20 -0600244 subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800245 self.assertNotEmpty(subnet, "Subnet returned has no fields")
246 for key in ['id', 'cidr']:
247 self.assertIn(key, subnet)
248 self.assertEqual(subnet[key], self.subnet[key])
Miguel Lavallecc939612013-02-22 17:27:20 -0600249
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900250 @test.attr(type='smoke')
jun xied557d9b2014-01-09 14:00:36 +0800251 def test_show_subnet_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800252 # Verify specific fields of a subnet
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500253 fields = ['id', 'network_id']
David Kranz34e88122014-12-11 15:24:05 -0500254 body = self.client.show_subnet(self.subnet['id'],
255 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800256 subnet = body['subnet']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500257 self.assertEqual(sorted(subnet.keys()), sorted(fields))
258 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800259 self.assertEqual(subnet[field_name], self.subnet[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800260
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900261 @test.attr(type='smoke')
Miguel Lavallecc939612013-02-22 17:27:20 -0600262 def test_list_subnets(self):
263 # Verify the subnet exists in the list of all subnets
David Kranz34e88122014-12-11 15:24:05 -0500264 body = self.client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800265 subnets = [subnet['id'] for subnet in body['subnets']
266 if subnet['id'] == self.subnet['id']]
267 self.assertNotEmpty(subnets, "Created subnet not found in the list")
raiesmh08e1aad982013-08-05 14:19:36 +0530268
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900269 @test.attr(type='smoke')
jun xie0b4735d2014-01-07 15:42:58 +0800270 def test_list_subnets_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800271 # Verify specific fields of subnets
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500272 fields = ['id', 'network_id']
David Kranz34e88122014-12-11 15:24:05 -0500273 body = self.client.list_subnets(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800274 subnets = body['subnets']
Mark Maglana5885eb32014-02-28 10:57:34 -0800275 self.assertNotEmpty(subnets, "Subnet list returned is empty")
276 for subnet in subnets:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500277 self.assertEqual(sorted(subnet.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800278
sukhdevc704a702014-01-15 11:50:56 -0800279 def _try_delete_network(self, net_id):
280 # delete network, if it exists
281 try:
282 self.client.delete_network(net_id)
283 # if network is not found, this means it was deleted in the test
284 except exceptions.NotFound:
285 pass
286
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900287 @test.attr(type='smoke')
sukhdevc704a702014-01-15 11:50:56 -0800288 def test_delete_network_with_subnet(self):
289 # Creates a network
290 name = data_utils.rand_name('network-')
David Kranz34e88122014-12-11 15:24:05 -0500291 body = self.client.create_network(name=name)
sukhdevc704a702014-01-15 11:50:56 -0800292 network = body['network']
293 net_id = network['id']
294 self.addCleanup(self._try_delete_network, net_id)
295
296 # Find a cidr that is not in use yet and create a subnet with it
297 subnet = self.create_subnet(network)
298 subnet_id = subnet['id']
299
300 # Delete network while the subnet still exists
David Kranz34e88122014-12-11 15:24:05 -0500301 body = self.client.delete_network(net_id)
sukhdevc704a702014-01-15 11:50:56 -0800302
303 # Verify that the subnet got automatically deleted.
304 self.assertRaises(exceptions.NotFound, self.client.show_subnet,
305 subnet_id)
306
307 # Since create_subnet adds the subnet to the delete list, and it is
308 # is actually deleted here - this will create and issue, hence remove
309 # it from the list.
310 self.subnets.pop()
311
Edgar Magana6a9ac342014-01-16 13:52:49 -0800312 @test.attr(type='smoke')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400313 def test_create_delete_subnet_without_gateway(self):
314 self._create_verify_delete_subnet()
315
316 @test.attr(type='smoke')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800317 def test_create_delete_subnet_with_gw(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200318 self._create_verify_delete_subnet(
319 **self.subnet_dict(['gateway']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800320
321 @test.attr(type='smoke')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200322 def test_create_delete_subnet_with_allocation_pools(self):
323 self._create_verify_delete_subnet(
324 **self.subnet_dict(['allocation_pools']))
325
326 @test.attr(type='smoke')
327 def test_create_delete_subnet_with_gw_and_allocation_pools(self):
328 self._create_verify_delete_subnet(**self.subnet_dict(
329 ['gateway', 'allocation_pools']))
330
331 @test.attr(type='smoke')
332 def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
333 self._create_verify_delete_subnet(
334 **self.subnet_dict(['host_routes', 'dns_nameservers']))
335
336 @test.attr(type='smoke')
337 def test_create_delete_subnet_with_dhcp_enabled(self):
338 self._create_verify_delete_subnet(enable_dhcp=True)
339
340 @test.attr(type='smoke')
341 def test_update_subnet_gw_dns_host_routes_dhcp(self):
342 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000343 self.addCleanup(self._delete_network, network)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200344
345 subnet = self.create_subnet(
346 network, **self.subnet_dict(['gateway', 'host_routes',
347 'dns_nameservers',
348 'allocation_pools']))
349 subnet_id = subnet['id']
350 new_gateway = str(netaddr.IPAddress(
351 self._subnet_data[self._ip_version]['gateway']) + 1)
352 # Verify subnet update
353 new_host_routes = self._subnet_data[self._ip_version][
354 'new_host_routes']
355
356 new_dns_nameservers = self._subnet_data[self._ip_version][
357 'new_dns_nameservers']
358 kwargs = {'host_routes': new_host_routes,
359 'dns_nameservers': new_dns_nameservers,
360 'gateway_ip': new_gateway, 'enable_dhcp': True}
361
362 new_name = "New_subnet"
David Kranz34e88122014-12-11 15:24:05 -0500363 body = self.client.update_subnet(subnet_id, name=new_name,
364 **kwargs)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200365 updated_subnet = body['subnet']
366 kwargs['name'] = new_name
367 self.assertEqual(sorted(updated_subnet['dns_nameservers']),
368 sorted(kwargs['dns_nameservers']))
369 del subnet['dns_nameservers'], kwargs['dns_nameservers']
370
371 self._compare_resource_attrs(updated_subnet, kwargs)
372
373 @test.attr(type='smoke')
374 def test_create_delete_subnet_all_attributes(self):
375 self._create_verify_delete_subnet(
376 enable_dhcp=True,
377 **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800378
Yair Friedbfdfc752014-09-28 13:56:45 +0300379 @test.attr(type='smoke')
380 def test_external_network_visibility(self):
381 """Verifies user can see external networks but not subnets."""
David Kranz34e88122014-12-11 15:24:05 -0500382 body = self.client.list_networks(**{'router:external': True})
Yair Friedbfdfc752014-09-28 13:56:45 +0300383 networks = [network['id'] for network in body['networks']]
384 self.assertNotEmpty(networks, "No external networks found")
385
386 nonexternal = [net for net in body['networks'] if
387 not net['router:external']]
388 self.assertEmpty(nonexternal, "Found non-external networks"
389 " in filtered list (%s)." % nonexternal)
390 self.assertIn(CONF.network.public_network_id, networks)
391
392 subnets_iter = (network['subnets'] for network in body['networks'])
393 # subnets_iter is a list (iterator) of lists. This flattens it to a
394 # list of UUIDs
395 public_subnets_iter = itertools.chain(*subnets_iter)
David Kranz34e88122014-12-11 15:24:05 -0500396 body = self.client.list_subnets()
Yair Friedbfdfc752014-09-28 13:56:45 +0300397 subnets = [sub['id'] for sub in body['subnets']
398 if sub['id'] in public_subnets_iter]
399 self.assertEmpty(subnets, "Public subnets visible")
400
raiesmh086b055e22013-09-16 12:59:57 +0530401
Ken'ichi Ohmichi91c675d2014-02-06 02:15:21 +0900402class BulkNetworkOpsTestJSON(base.BaseNetworkTest):
raiesmh086b055e22013-09-16 12:59:57 +0530403 _interface = 'json'
404
405 """
406 Tests the following operations in the Neutron API using the REST client for
407 Neutron:
408
409 bulk network creation
410 bulk subnet creation
Eugene Nikanorove9d255a2013-12-18 16:31:42 +0400411 bulk port creation
raiesmh086b055e22013-09-16 12:59:57 +0530412 list tenant's networks
413
414 v2.0 of the Neutron API is assumed. It is also assumed that the following
415 options are defined in the [network] section of etc/tempest.conf:
416
417 tenant_network_cidr with a block of cidr's from which smaller blocks
418 can be allocated for tenant networks
419
420 tenant_network_mask_bits with the mask bits to be used to partition the
421 block defined by tenant-network_cidr
422 """
423
raiesmh086b055e22013-09-16 12:59:57 +0530424 def _delete_networks(self, created_networks):
425 for n in created_networks:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200426 self.client.delete_network(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530427 # Asserting that the networks are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500428 body = self.client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800429 networks_list = [network['id'] for network in body['networks']]
raiesmh086b055e22013-09-16 12:59:57 +0530430 for n in created_networks:
431 self.assertNotIn(n['id'], networks_list)
432
433 def _delete_subnets(self, created_subnets):
434 for n in created_subnets:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200435 self.client.delete_subnet(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530436 # Asserting that the subnets are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500437 body = self.client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800438 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh086b055e22013-09-16 12:59:57 +0530439 for n in created_subnets:
440 self.assertNotIn(n['id'], subnets_list)
441
442 def _delete_ports(self, created_ports):
443 for n in created_ports:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200444 self.client.delete_port(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530445 # Asserting that the ports are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500446 body = self.client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800447 ports_list = [port['id'] for port in body['ports']]
raiesmh086b055e22013-09-16 12:59:57 +0530448 for n in created_ports:
449 self.assertNotIn(n['id'], ports_list)
450
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900451 @test.attr(type='smoke')
Nayna Patelb03eab42013-08-08 08:58:48 +0000452 def test_bulk_create_delete_network(self):
453 # Creates 2 networks in one request
Masayuki Igawa259c1132013-10-31 17:48:44 +0900454 network_names = [data_utils.rand_name('network-'),
455 data_utils.rand_name('network-')]
David Kranz34e88122014-12-11 15:24:05 -0500456 body = self.client.create_bulk_network(network_names)
Nayna Patelb03eab42013-08-08 08:58:48 +0000457 created_networks = body['networks']
Nayna Patelb03eab42013-08-08 08:58:48 +0000458 self.addCleanup(self._delete_networks, created_networks)
459 # Asserting that the networks are found in the list after creation
David Kranz34e88122014-12-11 15:24:05 -0500460 body = self.client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800461 networks_list = [network['id'] for network in body['networks']]
Nayna Patelb03eab42013-08-08 08:58:48 +0000462 for n in created_networks:
463 self.assertIsNotNone(n['id'])
464 self.assertIn(n['id'], networks_list)
raiesmh0867698322013-08-20 13:09:01 +0530465
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900466 @test.attr(type='smoke')
raiesmh082d5c6512013-09-06 15:35:05 +0530467 def test_bulk_create_delete_subnet(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300468 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530469 # Creates 2 subnets in one request
Matthew Treinish03b48df2014-01-29 16:59:49 +0000470 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
471 mask_bits = CONF.network.tenant_network_mask_bits
Mark Maglana5885eb32014-02-28 10:57:34 -0800472 cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
Mark Maglana5885eb32014-02-28 10:57:34 -0800473 names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
474 subnets_list = []
raiesmh082d5c6512013-09-06 15:35:05 +0530475 # TODO(raies): "for IPv6, version list [4, 6] will be used.
476 # and cidr for IPv6 will be of IPv6"
477 ip_version = [4, 4]
478 for i in range(len(names)):
479 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300480 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530481 'cidr': str(cidrs[(i)]),
482 'name': names[i],
483 'ip_version': ip_version[i]
484 }
Mark Maglana5885eb32014-02-28 10:57:34 -0800485 subnets_list.append(p1)
486 del subnets_list[1]['name']
David Kranz34e88122014-12-11 15:24:05 -0500487 body = self.client.create_bulk_subnet(subnets_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530488 created_subnets = body['subnets']
489 self.addCleanup(self._delete_subnets, created_subnets)
raiesmh082d5c6512013-09-06 15:35:05 +0530490 # Asserting that the subnets are found in the list after creation
David Kranz34e88122014-12-11 15:24:05 -0500491 body = self.client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800492 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh082d5c6512013-09-06 15:35:05 +0530493 for n in created_subnets:
494 self.assertIsNotNone(n['id'])
495 self.assertIn(n['id'], subnets_list)
496
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900497 @test.attr(type='smoke')
raiesmh082d5c6512013-09-06 15:35:05 +0530498 def test_bulk_create_delete_port(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300499 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530500 # Creates 2 ports in one request
Mark Maglana5885eb32014-02-28 10:57:34 -0800501 names = [data_utils.rand_name('port-') for i in range(len(networks))]
raiesmh082d5c6512013-09-06 15:35:05 +0530502 port_list = []
503 state = [True, False]
504 for i in range(len(names)):
505 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300506 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530507 'name': names[i],
508 'admin_state_up': state[i],
509 }
510 port_list.append(p1)
511 del port_list[1]['name']
David Kranz34e88122014-12-11 15:24:05 -0500512 body = self.client.create_bulk_port(port_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530513 created_ports = body['ports']
514 self.addCleanup(self._delete_ports, created_ports)
raiesmh082d5c6512013-09-06 15:35:05 +0530515 # Asserting that the ports are found in the list after creation
David Kranz34e88122014-12-11 15:24:05 -0500516 body = self.client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800517 ports_list = [port['id'] for port in body['ports']]
raiesmh082d5c6512013-09-06 15:35:05 +0530518 for n in created_ports:
519 self.assertIsNotNone(n['id'])
520 self.assertIn(n['id'], ports_list)
521
raiesmh0867698322013-08-20 13:09:01 +0530522
Henry Gessauffda37a2014-01-16 11:17:55 -0500523class NetworksIpV6TestJSON(NetworksTestJSON):
524 _ip_version = 6
Henry Gessauffda37a2014-01-16 11:17:55 -0500525
Edgar Magana6a9ac342014-01-16 13:52:49 -0800526 @test.attr(type='smoke')
527 def test_create_delete_subnet_with_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530528 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
529 gateway = str(netaddr.IPAddress(net.first + 2))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800530 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200531 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800532 subnet = self.create_subnet(network, gateway)
533 # Verifies Subnet GW in IPv6
534 self.assertEqual(subnet['gateway_ip'], gateway)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800535
536 @test.attr(type='smoke')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400537 def test_create_delete_subnet_with_default_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530538 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
539 gateway_ip = str(netaddr.IPAddress(net.first + 1))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800540 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200541 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800542 subnet = self.create_subnet(network)
543 # Verifies Subnet GW in IPv6
sridhargaddamea73d532014-05-13 14:48:30 +0530544 self.assertEqual(subnet['gateway_ip'], gateway_ip)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800545
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400546 @test.attr(type='smoke')
547 def test_create_list_subnet_with_no_gw64_one_network(self):
548 name = data_utils.rand_name('network-')
549 network = self.create_network(name)
550 ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
551 subnet1 = self.create_subnet(network,
552 ip_version=6,
553 gateway=ipv6_gateway)
554 self.assertEqual(netaddr.IPNetwork(subnet1['cidr']).version, 6,
555 'The created subnet is not IPv6')
556 subnet2 = self.create_subnet(network,
557 gateway=None,
558 ip_version=4)
559 self.assertEqual(netaddr.IPNetwork(subnet2['cidr']).version, 4,
560 'The created subnet is not IPv4')
561 # Verifies Subnet GW is set in IPv6
562 self.assertEqual(subnet1['gateway_ip'], ipv6_gateway)
563 # Verifies Subnet GW is None in IPv4
564 self.assertEqual(subnet2['gateway_ip'], None)
565 # Verifies all 2 subnets in the same network
David Kranz34e88122014-12-11 15:24:05 -0500566 body = self.client.list_subnets()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400567 subnets = [sub['id'] for sub in body['subnets']
568 if sub['network_id'] == network['id']]
569 test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
570 self.assertItemsEqual(subnets,
571 test_subnet_ids,
572 'Subnet are not in the same network')
573
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400574 @testtools.skipUnless(CONF.network_feature_enabled.ipv6_subnet_attributes,
575 "IPv6 extended attributes for subnets not "
576 "available")
577 @test.attr(type='smoke')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400578 def test_create_delete_subnet_with_v6_attributes_stateful(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200579 self._create_verify_delete_subnet(
580 gateway=self._subnet_data[self._ip_version]['gateway'],
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400581 ipv6_ra_mode='dhcpv6-stateful',
582 ipv6_address_mode='dhcpv6-stateful')
583
584 @testtools.skipUnless(CONF.network_feature_enabled.ipv6_subnet_attributes,
585 "IPv6 extended attributes for subnets not "
586 "available")
587 @test.attr(type='smoke')
588 def test_create_delete_subnet_with_v6_attributes_slaac(self):
589 self._create_verify_delete_subnet(
Rohan Kanade35589aa2014-08-19 14:56:12 +0200590 ipv6_ra_mode='slaac',
591 ipv6_address_mode='slaac')
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400592
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400593 @testtools.skipUnless(CONF.network_feature_enabled.ipv6_subnet_attributes,
594 "IPv6 extended attributes for subnets not "
595 "available")
596 @test.attr(type='smoke')
597 def test_create_delete_subnet_with_v6_attributes_stateless(self):
598 self._create_verify_delete_subnet(
599 ipv6_ra_mode='dhcpv6-stateless',
600 ipv6_address_mode='dhcpv6-stateless')