blob: 7a96f3431f9b77c1b65beafcd2c0b162dd38b080 [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
Matthew Treinish01472ff2015-02-20 17:26:52 -050019from tempest_lib.common.utils import data_utils
Masayuki Igawad9388762015-01-20 14:56:42 +090020from tempest_lib import exceptions as lib_exc
Jay Pipesf4dad392012-06-05 16:03:58 -040021
Sean Dague1937d092013-05-17 16:36:38 -040022from tempest.api.network import base
Rohan Kanade35589aa2014-08-19 14:56:12 +020023from tempest.common import custom_matchers
Matthew Treinish03b48df2014-01-29 16:59:49 +000024from tempest import config
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):
Miguel Lavallecc939612013-02-22 17:27:20 -060031 """
Mark McClainf2982e82013-07-06 17:48:03 -040032 Tests the following operations in the Neutron API using the REST client for
33 Neutron:
Miguel Lavallecc939612013-02-22 17:27:20 -060034
35 create a network for a tenant
36 list tenant's networks
37 show a tenant network details
38 create a subnet for a tenant
39 list tenant's subnets
40 show a tenant subnet details
raiesmh08e1aad982013-08-05 14:19:36 +053041 network update
42 subnet update
sukhdevc704a702014-01-15 11:50:56 -080043 delete a network also deletes its subnets
Yair Friedbfdfc752014-09-28 13:56:45 +030044 list external networks
Miguel Lavallecc939612013-02-22 17:27:20 -060045
Henry Gessauffda37a2014-01-16 11:17:55 -050046 All subnet tests are run once with ipv4 and once with ipv6.
47
Mark McClainf2982e82013-07-06 17:48:03 -040048 v2.0 of the Neutron API is assumed. It is also assumed that the following
Miguel Lavallecc939612013-02-22 17:27:20 -060049 options are defined in the [network] section of etc/tempest.conf:
50
51 tenant_network_cidr with a block of cidr's from which smaller blocks
Henry Gessauffda37a2014-01-16 11:17:55 -050052 can be allocated for tenant ipv4 subnets
53
54 tenant_network_v6_cidr is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060055
56 tenant_network_mask_bits with the mask bits to be used to partition the
Henry Gessauffda37a2014-01-16 11:17:55 -050057 block defined by tenant_network_cidr
58
59 tenant_network_v6_mask_bits is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060060 """
61
Unmesh Gurjar44986832012-05-08 19:57:10 +053062 @classmethod
Andrea Frittolida4a2452014-09-15 13:12:08 +010063 def resource_setup(cls):
64 super(NetworksTestJSON, cls).resource_setup()
Jay Pipesf4dad392012-06-05 16:03:58 -040065 cls.network = cls.create_network()
66 cls.name = cls.network['name']
venakata anil1a2a64a2014-12-02 07:25:59 +000067 cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
68 cls._ip_version)
Miguel Lavallecc939612013-02-22 17:27:20 -060069 cls.cidr = cls.subnet['cidr']
Rohan Kanade35589aa2014-08-19 14:56:12 +020070 cls._subnet_data = {6: {'gateway':
71 str(cls._get_gateway_from_tempest_conf(6)),
72 'allocation_pools':
73 cls._get_allocation_pools_from_gateway(6),
74 'dns_nameservers': ['2001:4860:4860::8844',
75 '2001:4860:4860::8888'],
76 'host_routes': [{'destination': '2001::/64',
77 'nexthop': '2003::1'}],
78 'new_host_routes': [{'destination':
79 '2001::/64',
80 'nexthop': '2005::1'}],
81 'new_dns_nameservers':
82 ['2001:4860:4860::7744',
83 '2001:4860:4860::7888']},
84 4: {'gateway':
85 str(cls._get_gateway_from_tempest_conf(4)),
86 'allocation_pools':
87 cls._get_allocation_pools_from_gateway(4),
88 'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
89 'host_routes': [{'destination': '10.20.0.0/32',
90 'nexthop': '10.100.1.1'}],
91 'new_host_routes': [{'destination':
92 '10.20.0.0/32',
93 'nexthop':
94 '10.100.1.2'}],
95 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
96
97 @classmethod
venakata anil1a2a64a2014-12-02 07:25:59 +000098 def _create_subnet_with_last_subnet_block(cls, network, ip_version):
99 """Derive last subnet CIDR block from tenant CIDR and
100 create the subnet with that derived CIDR
101 """
102 if ip_version == 4:
103 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
104 mask_bits = CONF.network.tenant_network_mask_bits
105 elif ip_version == 6:
106 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
107 mask_bits = CONF.network.tenant_network_v6_mask_bits
108
109 subnet_cidr = list(cidr.subnet(mask_bits))[-1]
110 gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
111 return cls.create_subnet(network, gateway=gateway_ip,
112 cidr=subnet_cidr, mask_bits=mask_bits)
113
114 @classmethod
Rohan Kanade35589aa2014-08-19 14:56:12 +0200115 def _get_gateway_from_tempest_conf(cls, ip_version):
116 """Return first subnet gateway for configured CIDR """
117 if ip_version == 4:
118 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
119 mask_bits = CONF.network.tenant_network_mask_bits
120 elif ip_version == 6:
121 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
122 mask_bits = CONF.network.tenant_network_v6_mask_bits
123
124 if mask_bits >= cidr.prefixlen:
125 return netaddr.IPAddress(cidr) + 1
126 else:
127 for subnet in cidr.subnet(mask_bits):
128 return netaddr.IPAddress(subnet) + 1
129
130 @classmethod
131 def _get_allocation_pools_from_gateway(cls, ip_version):
132 """Return allocation range for subnet of given gateway"""
133 gateway = cls._get_gateway_from_tempest_conf(ip_version)
134 return [{'start': str(gateway + 2), 'end': str(gateway + 3)}]
135
136 def subnet_dict(self, include_keys):
137 """Return a subnet dict which has include_keys and their corresponding
138 value from self._subnet_data
139 """
140 return dict((key, self._subnet_data[self._ip_version][key])
141 for key in include_keys)
142
143 def _compare_resource_attrs(self, actual, expected):
144 exclude_keys = set(actual).symmetric_difference(expected)
145 self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
146 expected, exclude_keys))
147
venakata anil1a2a64a2014-12-02 07:25:59 +0000148 def _delete_network(self, network):
149 # Deleting network also deletes its subnets if exists
150 self.client.delete_network(network['id'])
151 if network in self.networks:
152 self.networks.remove(network)
153 for subnet in self.subnets:
154 if subnet['network_id'] == network['id']:
155 self.subnets.remove(subnet)
156
Rohan Kanade35589aa2014-08-19 14:56:12 +0200157 def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
158 **kwargs):
159 network = self.create_network()
160 net_id = network['id']
161 gateway = kwargs.pop('gateway', None)
162 subnet = self.create_subnet(network, gateway, cidr, mask_bits,
163 **kwargs)
164 compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
165 mask_bits=mask_bits, **kwargs)
Matthew Treinish71426682015-04-23 11:19:38 -0400166 compare_args = dict((k, v) for k, v in six.iteritems(compare_args_full)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200167 if v is not None)
168
169 if 'dns_nameservers' in set(subnet).intersection(compare_args):
170 self.assertEqual(sorted(compare_args['dns_nameservers']),
171 sorted(subnet['dns_nameservers']))
172 del subnet['dns_nameservers'], compare_args['dns_nameservers']
173
174 self._compare_resource_attrs(subnet, compare_args)
175 self.client.delete_network(net_id)
176 self.networks.pop()
177 self.subnets.pop()
Unmesh Gurjar44986832012-05-08 19:57:10 +0530178
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900179 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800180 @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
raiesmh08e1aad982013-08-05 14:19:36 +0530181 def test_create_update_delete_network_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800182 # Create a network
Masayuki Igawa259c1132013-10-31 17:48:44 +0900183 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200184 network = self.create_network(network_name=name)
venakata anil1a2a64a2014-12-02 07:25:59 +0000185 self.addCleanup(self._delete_network, network)
raiesmh08e1aad982013-08-05 14:19:36 +0530186 net_id = network['id']
Santosh Kumar42c94802014-08-08 04:31:42 -0700187 self.assertEqual('ACTIVE', network['status'])
Mark Maglana5885eb32014-02-28 10:57:34 -0800188 # Verify network update
raiesmh08e1aad982013-08-05 14:19:36 +0530189 new_name = "New_network"
David Kranz34e88122014-12-11 15:24:05 -0500190 body = self.client.update_network(net_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530191 updated_net = body['network']
192 self.assertEqual(updated_net['name'], new_name)
Miguel Lavallecc939612013-02-22 17:27:20 -0600193 # Find a cidr that is not in use yet and create a subnet with it
Matthew Treinish6b8cd2a2014-03-03 20:45:56 +0000194 subnet = self.create_subnet(network)
raiesmh08e1aad982013-08-05 14:19:36 +0530195 subnet_id = subnet['id']
Mark Maglana5885eb32014-02-28 10:57:34 -0800196 # Verify subnet update
197 new_name = "New_subnet"
David Kranz34e88122014-12-11 15:24:05 -0500198 body = self.client.update_subnet(subnet_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530199 updated_subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800200 self.assertEqual(updated_subnet['name'], new_name)
Unmesh Gurjar44986832012-05-08 19:57:10 +0530201
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900202 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800203 @test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
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
Chris Hoge7579c1a2015-02-26 14:12:15 -0800211 @test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
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')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800223 @test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530224 def test_list_networks(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500225 # Verify the network exists in the list of all networks
David Kranz34e88122014-12-11 15:24:05 -0500226 body = self.client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800227 networks = [network['id'] for network in body['networks']
228 if network['id'] == self.network['id']]
229 self.assertNotEmpty(networks, "Created network not found in the list")
Unmesh Gurjar44986832012-05-08 19:57:10 +0530230
Chris Hoge7579c1a2015-02-26 14:12:15 -0800231 @test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
jun xie0b4735d2014-01-07 15:42:58 +0800232 def test_list_networks_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800233 # Verify specific fields of the networks
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500234 fields = ['id', 'name']
David Kranz34e88122014-12-11 15:24:05 -0500235 body = self.client.list_networks(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800236 networks = body['networks']
Mark Maglana5885eb32014-02-28 10:57:34 -0800237 self.assertNotEmpty(networks, "Network list returned is empty")
238 for network in networks:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500239 self.assertEqual(sorted(network.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800240
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900241 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800242 @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
Miguel Lavallecc939612013-02-22 17:27:20 -0600243 def test_show_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800244 # Verify the details of a subnet
David Kranz34e88122014-12-11 15:24:05 -0500245 body = self.client.show_subnet(self.subnet['id'])
Miguel Lavallecc939612013-02-22 17:27:20 -0600246 subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800247 self.assertNotEmpty(subnet, "Subnet returned has no fields")
248 for key in ['id', 'cidr']:
249 self.assertIn(key, subnet)
250 self.assertEqual(subnet[key], self.subnet[key])
Miguel Lavallecc939612013-02-22 17:27:20 -0600251
Chris Hoge7579c1a2015-02-26 14:12:15 -0800252 @test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
jun xied557d9b2014-01-09 14:00:36 +0800253 def test_show_subnet_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800254 # Verify specific fields of a subnet
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500255 fields = ['id', 'network_id']
David Kranz34e88122014-12-11 15:24:05 -0500256 body = self.client.show_subnet(self.subnet['id'],
257 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800258 subnet = body['subnet']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500259 self.assertEqual(sorted(subnet.keys()), sorted(fields))
260 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800261 self.assertEqual(subnet[field_name], self.subnet[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800262
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900263 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800264 @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
Miguel Lavallecc939612013-02-22 17:27:20 -0600265 def test_list_subnets(self):
266 # Verify the subnet exists in the list of all subnets
David Kranz34e88122014-12-11 15:24:05 -0500267 body = self.client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800268 subnets = [subnet['id'] for subnet in body['subnets']
269 if subnet['id'] == self.subnet['id']]
270 self.assertNotEmpty(subnets, "Created subnet not found in the list")
raiesmh08e1aad982013-08-05 14:19:36 +0530271
Chris Hoge7579c1a2015-02-26 14:12:15 -0800272 @test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
jun xie0b4735d2014-01-07 15:42:58 +0800273 def test_list_subnets_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800274 # Verify specific fields of subnets
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500275 fields = ['id', 'network_id']
David Kranz34e88122014-12-11 15:24:05 -0500276 body = self.client.list_subnets(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800277 subnets = body['subnets']
Mark Maglana5885eb32014-02-28 10:57:34 -0800278 self.assertNotEmpty(subnets, "Subnet list returned is empty")
279 for subnet in subnets:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500280 self.assertEqual(sorted(subnet.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800281
sukhdevc704a702014-01-15 11:50:56 -0800282 def _try_delete_network(self, net_id):
283 # delete network, if it exists
284 try:
285 self.client.delete_network(net_id)
286 # if network is not found, this means it was deleted in the test
Masayuki Igawabfa07602015-01-20 18:47:17 +0900287 except lib_exc.NotFound:
sukhdevc704a702014-01-15 11:50:56 -0800288 pass
289
Chris Hoge7579c1a2015-02-26 14:12:15 -0800290 @test.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
sukhdevc704a702014-01-15 11:50:56 -0800291 def test_delete_network_with_subnet(self):
292 # Creates a network
293 name = data_utils.rand_name('network-')
David Kranz34e88122014-12-11 15:24:05 -0500294 body = self.client.create_network(name=name)
sukhdevc704a702014-01-15 11:50:56 -0800295 network = body['network']
296 net_id = network['id']
297 self.addCleanup(self._try_delete_network, net_id)
298
299 # Find a cidr that is not in use yet and create a subnet with it
300 subnet = self.create_subnet(network)
301 subnet_id = subnet['id']
302
303 # Delete network while the subnet still exists
David Kranz34e88122014-12-11 15:24:05 -0500304 body = self.client.delete_network(net_id)
sukhdevc704a702014-01-15 11:50:56 -0800305
306 # Verify that the subnet got automatically deleted.
Masayuki Igawabfa07602015-01-20 18:47:17 +0900307 self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
sukhdevc704a702014-01-15 11:50:56 -0800308 subnet_id)
309
310 # Since create_subnet adds the subnet to the delete list, and it is
311 # is actually deleted here - this will create and issue, hence remove
312 # it from the list.
313 self.subnets.pop()
314
Chris Hoge7579c1a2015-02-26 14:12:15 -0800315 @test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400316 def test_create_delete_subnet_without_gateway(self):
317 self._create_verify_delete_subnet()
318
Chris Hoge7579c1a2015-02-26 14:12:15 -0800319 @test.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800320 def test_create_delete_subnet_with_gw(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200321 self._create_verify_delete_subnet(
322 **self.subnet_dict(['gateway']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800323
Chris Hoge7579c1a2015-02-26 14:12:15 -0800324 @test.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200325 def test_create_delete_subnet_with_allocation_pools(self):
326 self._create_verify_delete_subnet(
327 **self.subnet_dict(['allocation_pools']))
328
Chris Hoge7579c1a2015-02-26 14:12:15 -0800329 @test.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200330 def test_create_delete_subnet_with_gw_and_allocation_pools(self):
331 self._create_verify_delete_subnet(**self.subnet_dict(
332 ['gateway', 'allocation_pools']))
333
Chris Hoge7579c1a2015-02-26 14:12:15 -0800334 @test.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200335 def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
336 self._create_verify_delete_subnet(
337 **self.subnet_dict(['host_routes', 'dns_nameservers']))
338
Chris Hoge7579c1a2015-02-26 14:12:15 -0800339 @test.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200340 def test_create_delete_subnet_with_dhcp_enabled(self):
341 self._create_verify_delete_subnet(enable_dhcp=True)
342
Chris Hoge7579c1a2015-02-26 14:12:15 -0800343 @test.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200344 def test_update_subnet_gw_dns_host_routes_dhcp(self):
345 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000346 self.addCleanup(self._delete_network, network)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200347
348 subnet = self.create_subnet(
349 network, **self.subnet_dict(['gateway', 'host_routes',
350 'dns_nameservers',
351 'allocation_pools']))
352 subnet_id = subnet['id']
353 new_gateway = str(netaddr.IPAddress(
354 self._subnet_data[self._ip_version]['gateway']) + 1)
355 # Verify subnet update
356 new_host_routes = self._subnet_data[self._ip_version][
357 'new_host_routes']
358
359 new_dns_nameservers = self._subnet_data[self._ip_version][
360 'new_dns_nameservers']
361 kwargs = {'host_routes': new_host_routes,
362 'dns_nameservers': new_dns_nameservers,
363 'gateway_ip': new_gateway, 'enable_dhcp': True}
364
365 new_name = "New_subnet"
David Kranz34e88122014-12-11 15:24:05 -0500366 body = self.client.update_subnet(subnet_id, name=new_name,
367 **kwargs)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200368 updated_subnet = body['subnet']
369 kwargs['name'] = new_name
370 self.assertEqual(sorted(updated_subnet['dns_nameservers']),
371 sorted(kwargs['dns_nameservers']))
372 del subnet['dns_nameservers'], kwargs['dns_nameservers']
373
374 self._compare_resource_attrs(updated_subnet, kwargs)
375
Chris Hoge7579c1a2015-02-26 14:12:15 -0800376 @test.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200377 def test_create_delete_subnet_all_attributes(self):
378 self._create_verify_delete_subnet(
379 enable_dhcp=True,
380 **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800381
Yair Friedbfdfc752014-09-28 13:56:45 +0300382 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800383 @test.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
Yair Friedbfdfc752014-09-28 13:56:45 +0300384 def test_external_network_visibility(self):
385 """Verifies user can see external networks but not subnets."""
David Kranz34e88122014-12-11 15:24:05 -0500386 body = self.client.list_networks(**{'router:external': True})
Yair Friedbfdfc752014-09-28 13:56:45 +0300387 networks = [network['id'] for network in body['networks']]
388 self.assertNotEmpty(networks, "No external networks found")
389
390 nonexternal = [net for net in body['networks'] if
391 not net['router:external']]
392 self.assertEmpty(nonexternal, "Found non-external networks"
393 " in filtered list (%s)." % nonexternal)
394 self.assertIn(CONF.network.public_network_id, networks)
395
Xavier León3aa65342015-05-12 15:24:28 +0000396 subnets_iter = (network['subnets']
397 for network in body['networks']
398 if not network['shared'])
Yair Friedbfdfc752014-09-28 13:56:45 +0300399 # subnets_iter is a list (iterator) of lists. This flattens it to a
400 # list of UUIDs
401 public_subnets_iter = itertools.chain(*subnets_iter)
David Kranz34e88122014-12-11 15:24:05 -0500402 body = self.client.list_subnets()
Yair Friedbfdfc752014-09-28 13:56:45 +0300403 subnets = [sub['id'] for sub in body['subnets']
404 if sub['id'] in public_subnets_iter]
405 self.assertEmpty(subnets, "Public subnets visible")
406
raiesmh086b055e22013-09-16 12:59:57 +0530407
Ken'ichi Ohmichi91c675d2014-02-06 02:15:21 +0900408class BulkNetworkOpsTestJSON(base.BaseNetworkTest):
raiesmh086b055e22013-09-16 12:59:57 +0530409 """
410 Tests the following operations in the Neutron API using the REST client for
411 Neutron:
412
413 bulk network creation
414 bulk subnet creation
Eugene Nikanorove9d255a2013-12-18 16:31:42 +0400415 bulk port creation
raiesmh086b055e22013-09-16 12:59:57 +0530416 list tenant's networks
417
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
421 tenant_network_cidr with a block of cidr's from which smaller blocks
422 can be allocated for tenant networks
423
424 tenant_network_mask_bits with the mask bits to be used to partition the
425 block defined by tenant-network_cidr
426 """
427
raiesmh086b055e22013-09-16 12:59:57 +0530428 def _delete_networks(self, created_networks):
429 for n in created_networks:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200430 self.client.delete_network(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530431 # Asserting that the networks are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500432 body = self.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:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200439 self.client.delete_subnet(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530440 # Asserting that the subnets are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500441 body = self.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:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200448 self.client.delete_port(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530449 # Asserting that the ports are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500450 body = self.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
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900455 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800456 @test.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
Masayuki Igawa259c1132013-10-31 17:48:44 +0900459 network_names = [data_utils.rand_name('network-'),
460 data_utils.rand_name('network-')]
David Kranz34e88122014-12-11 15:24:05 -0500461 body = self.client.create_bulk_network(network_names)
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
David Kranz34e88122014-12-11 15:24:05 -0500465 body = self.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
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900471 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800472 @test.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:
477 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
478 mask_bits = CONF.network.tenant_network_mask_bits
479 else:
480 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
481 mask_bits = CONF.network.tenant_network_v6_mask_bits
482
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']
David Kranz34e88122014-12-11 15:24:05 -0500496 body = self.client.create_bulk_subnet(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
David Kranz34e88122014-12-11 15:24:05 -0500500 body = self.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
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900506 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800507 @test.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']
David Kranz34e88122014-12-11 15:24:05 -0500522 body = self.client.create_bulk_port(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
David Kranz34e88122014-12-11 15:24:05 -0500526 body = self.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
Rohan Kanade0efb0232015-02-19 13:33:31 +0530533class BulkNetworkOpsIpV6TestJSON(BulkNetworkOpsTestJSON):
534 _ip_version = 6
535
536
Henry Gessauffda37a2014-01-16 11:17:55 -0500537class NetworksIpV6TestJSON(NetworksTestJSON):
538 _ip_version = 6
Henry Gessauffda37a2014-01-16 11:17:55 -0500539
Chris Hoge7579c1a2015-02-26 14:12:15 -0800540 @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800541 def test_create_delete_subnet_with_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530542 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
543 gateway = str(netaddr.IPAddress(net.first + 2))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800544 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200545 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800546 subnet = self.create_subnet(network, gateway)
547 # Verifies Subnet GW in IPv6
548 self.assertEqual(subnet['gateway_ip'], gateway)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800549
Chris Hoge7579c1a2015-02-26 14:12:15 -0800550 @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400551 def test_create_delete_subnet_with_default_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530552 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
553 gateway_ip = str(netaddr.IPAddress(net.first + 1))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800554 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200555 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800556 subnet = self.create_subnet(network)
557 # Verifies Subnet GW in IPv6
sridhargaddamea73d532014-05-13 14:48:30 +0530558 self.assertEqual(subnet['gateway_ip'], gateway_ip)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800559
Chris Hoge7579c1a2015-02-26 14:12:15 -0800560 @test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400561 def test_create_list_subnet_with_no_gw64_one_network(self):
562 name = data_utils.rand_name('network-')
563 network = self.create_network(name)
564 ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
565 subnet1 = self.create_subnet(network,
566 ip_version=6,
567 gateway=ipv6_gateway)
568 self.assertEqual(netaddr.IPNetwork(subnet1['cidr']).version, 6,
569 'The created subnet is not IPv6')
570 subnet2 = self.create_subnet(network,
571 gateway=None,
572 ip_version=4)
573 self.assertEqual(netaddr.IPNetwork(subnet2['cidr']).version, 4,
574 'The created subnet is not IPv4')
575 # Verifies Subnet GW is set in IPv6
576 self.assertEqual(subnet1['gateway_ip'], ipv6_gateway)
577 # Verifies Subnet GW is None in IPv4
578 self.assertEqual(subnet2['gateway_ip'], None)
579 # Verifies all 2 subnets in the same network
David Kranz34e88122014-12-11 15:24:05 -0500580 body = self.client.list_subnets()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400581 subnets = [sub['id'] for sub in body['subnets']
582 if sub['network_id'] == network['id']]
583 test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
584 self.assertItemsEqual(subnets,
585 test_subnet_ids,
586 'Subnet are not in the same network')
587
Sergey She757c332014-11-25 01:16:32 +0300588
589class NetworksIpV6TestAttrs(NetworksIpV6TestJSON):
590
591 @classmethod
Rohan Kanadea565e452015-01-27 14:00:13 +0530592 def skip_checks(cls):
593 super(NetworksIpV6TestAttrs, cls).skip_checks()
Sergey She757c332014-11-25 01:16:32 +0300594 if not CONF.network_feature_enabled.ipv6_subnet_attributes:
595 raise cls.skipException("IPv6 extended attributes for "
596 "subnets not available")
Sergey She757c332014-11-25 01:16:32 +0300597
Chris Hoge7579c1a2015-02-26 14:12:15 -0800598 @test.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400599 def test_create_delete_subnet_with_v6_attributes_stateful(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200600 self._create_verify_delete_subnet(
601 gateway=self._subnet_data[self._ip_version]['gateway'],
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400602 ipv6_ra_mode='dhcpv6-stateful',
603 ipv6_address_mode='dhcpv6-stateful')
604
Chris Hoge7579c1a2015-02-26 14:12:15 -0800605 @test.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400606 def test_create_delete_subnet_with_v6_attributes_slaac(self):
607 self._create_verify_delete_subnet(
Rohan Kanade35589aa2014-08-19 14:56:12 +0200608 ipv6_ra_mode='slaac',
609 ipv6_address_mode='slaac')
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400610
Chris Hoge7579c1a2015-02-26 14:12:15 -0800611 @test.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400612 def test_create_delete_subnet_with_v6_attributes_stateless(self):
613 self._create_verify_delete_subnet(
614 ipv6_ra_mode='dhcpv6-stateless',
615 ipv6_address_mode='dhcpv6-stateless')
Sergey She757c332014-11-25 01:16:32 +0300616
617 def _test_delete_subnet_with_ports(self, mode):
618 """Create subnet and delete it with existing ports"""
619 slaac_network = self.create_network()
620 subnet_slaac = self.create_subnet(slaac_network,
621 **{'ipv6_ra_mode': mode,
622 'ipv6_address_mode': mode})
623 port = self.create_port(slaac_network)
624 self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
625 self.client.delete_subnet(subnet_slaac['id'])
626 self.subnets.pop()
627 subnets = self.client.list_subnets()
628 subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
629 self.assertNotIn(subnet_slaac['id'], subnet_ids,
630 "Subnet wasn't deleted")
631 self.assertRaisesRegexp(
Masayuki Igawad9388762015-01-20 14:56:42 +0900632 lib_exc.Conflict,
Sergey She757c332014-11-25 01:16:32 +0300633 "There are one or more ports still in use on the network",
634 self.client.delete_network,
635 slaac_network['id'])
636
Chris Hoge7579c1a2015-02-26 14:12:15 -0800637 @test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
Sergey She757c332014-11-25 01:16:32 +0300638 def test_create_delete_slaac_subnet_with_ports(self):
639 """Test deleting subnet with SLAAC ports
640
641 Create subnet with SLAAC, create ports in network
642 and then you shall be able to delete subnet without port
643 deletion. But you still can not delete the network.
644 """
645 self._test_delete_subnet_with_ports("slaac")
646
Chris Hoge7579c1a2015-02-26 14:12:15 -0800647 @test.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
Sergey She757c332014-11-25 01:16:32 +0300648 def test_create_delete_stateless_subnet_with_ports(self):
649 """Test deleting subnet with DHCPv6 stateless ports
650
651 Create subnet with DHCPv6 stateless, create ports in network
652 and then you shall be able to delete subnet without port
653 deletion. But you still can not delete the network.
654 """
655 self._test_delete_subnet_with_ports("dhcpv6-stateless")