blob: 11165737546d4ea68856f3fd13070837980a8f40 [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
Masayuki Igawad9388762015-01-20 14:56:42 +090019from tempest_lib import exceptions as lib_exc
Jay Pipesf4dad392012-06-05 16:03:58 -040020
Sean Dague1937d092013-05-17 16:36:38 -040021from tempest.api.network import base
Rohan Kanade35589aa2014-08-19 14:56:12 +020022from tempest.common import custom_matchers
Fei Long Wangd39431f2015-05-14 11:30:48 +120023from tempest.common.utils import data_utils
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
Matthew Treinishe4184ea2015-09-03 21:13:09 -040030class NetworksTest(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):
Matthew Treinishe4184ea2015-09-03 21:13:09 -040064 super(NetworksTest, 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)
Rohan Kanade35589aa2014-08-19 14:56:12 +020069 cls._subnet_data = {6: {'gateway':
70 str(cls._get_gateway_from_tempest_conf(6)),
71 'allocation_pools':
72 cls._get_allocation_pools_from_gateway(6),
73 'dns_nameservers': ['2001:4860:4860::8844',
74 '2001:4860:4860::8888'],
75 'host_routes': [{'destination': '2001::/64',
76 'nexthop': '2003::1'}],
77 'new_host_routes': [{'destination':
78 '2001::/64',
79 'nexthop': '2005::1'}],
80 'new_dns_nameservers':
81 ['2001:4860:4860::7744',
82 '2001:4860:4860::7888']},
83 4: {'gateway':
84 str(cls._get_gateway_from_tempest_conf(4)),
85 'allocation_pools':
86 cls._get_allocation_pools_from_gateway(4),
87 'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
88 'host_routes': [{'destination': '10.20.0.0/32',
89 'nexthop': '10.100.1.1'}],
90 'new_host_routes': [{'destination':
91 '10.20.0.0/32',
92 'nexthop':
93 '10.100.1.2'}],
94 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
95
96 @classmethod
venakata anil1a2a64a2014-12-02 07:25:59 +000097 def _create_subnet_with_last_subnet_block(cls, network, ip_version):
98 """Derive last subnet CIDR block from tenant CIDR and
99 create the subnet with that derived CIDR
100 """
101 if ip_version == 4:
102 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
103 mask_bits = CONF.network.tenant_network_mask_bits
104 elif ip_version == 6:
105 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
106 mask_bits = CONF.network.tenant_network_v6_mask_bits
107
108 subnet_cidr = list(cidr.subnet(mask_bits))[-1]
109 gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
110 return cls.create_subnet(network, gateway=gateway_ip,
111 cidr=subnet_cidr, mask_bits=mask_bits)
112
113 @classmethod
Rohan Kanade35589aa2014-08-19 14:56:12 +0200114 def _get_gateway_from_tempest_conf(cls, ip_version):
115 """Return first subnet gateway for configured CIDR """
116 if ip_version == 4:
117 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
118 mask_bits = CONF.network.tenant_network_mask_bits
119 elif ip_version == 6:
120 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
121 mask_bits = CONF.network.tenant_network_v6_mask_bits
122
123 if mask_bits >= cidr.prefixlen:
124 return netaddr.IPAddress(cidr) + 1
125 else:
126 for subnet in cidr.subnet(mask_bits):
127 return netaddr.IPAddress(subnet) + 1
128
129 @classmethod
130 def _get_allocation_pools_from_gateway(cls, ip_version):
131 """Return allocation range for subnet of given gateway"""
132 gateway = cls._get_gateway_from_tempest_conf(ip_version)
133 return [{'start': str(gateway + 2), 'end': str(gateway + 3)}]
134
135 def subnet_dict(self, include_keys):
136 """Return a subnet dict which has include_keys and their corresponding
137 value from self._subnet_data
138 """
139 return dict((key, self._subnet_data[self._ip_version][key])
140 for key in include_keys)
141
142 def _compare_resource_attrs(self, actual, expected):
143 exclude_keys = set(actual).symmetric_difference(expected)
144 self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
145 expected, exclude_keys))
146
venakata anil1a2a64a2014-12-02 07:25:59 +0000147 def _delete_network(self, network):
148 # Deleting network also deletes its subnets if exists
149 self.client.delete_network(network['id'])
150 if network in self.networks:
151 self.networks.remove(network)
152 for subnet in self.subnets:
153 if subnet['network_id'] == network['id']:
154 self.subnets.remove(subnet)
155
Rohan Kanade35589aa2014-08-19 14:56:12 +0200156 def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
157 **kwargs):
158 network = self.create_network()
159 net_id = network['id']
160 gateway = kwargs.pop('gateway', None)
161 subnet = self.create_subnet(network, gateway, cidr, mask_bits,
162 **kwargs)
163 compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
164 mask_bits=mask_bits, **kwargs)
Matthew Treinish71426682015-04-23 11:19:38 -0400165 compare_args = dict((k, v) for k, v in six.iteritems(compare_args_full)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200166 if v is not None)
167
168 if 'dns_nameservers' in set(subnet).intersection(compare_args):
169 self.assertEqual(sorted(compare_args['dns_nameservers']),
170 sorted(subnet['dns_nameservers']))
171 del subnet['dns_nameservers'], compare_args['dns_nameservers']
172
173 self._compare_resource_attrs(subnet, compare_args)
174 self.client.delete_network(net_id)
175 self.networks.pop()
176 self.subnets.pop()
Unmesh Gurjar44986832012-05-08 19:57:10 +0530177
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900178 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800179 @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
raiesmh08e1aad982013-08-05 14:19:36 +0530180 def test_create_update_delete_network_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800181 # Create a network
Masayuki Igawa259c1132013-10-31 17:48:44 +0900182 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200183 network = self.create_network(network_name=name)
venakata anil1a2a64a2014-12-02 07:25:59 +0000184 self.addCleanup(self._delete_network, network)
raiesmh08e1aad982013-08-05 14:19:36 +0530185 net_id = network['id']
Santosh Kumar42c94802014-08-08 04:31:42 -0700186 self.assertEqual('ACTIVE', network['status'])
Mark Maglana5885eb32014-02-28 10:57:34 -0800187 # Verify network update
raiesmh08e1aad982013-08-05 14:19:36 +0530188 new_name = "New_network"
David Kranz34e88122014-12-11 15:24:05 -0500189 body = self.client.update_network(net_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530190 updated_net = body['network']
191 self.assertEqual(updated_net['name'], new_name)
Miguel Lavallecc939612013-02-22 17:27:20 -0600192 # Find a cidr that is not in use yet and create a subnet with it
Matthew Treinish6b8cd2a2014-03-03 20:45:56 +0000193 subnet = self.create_subnet(network)
raiesmh08e1aad982013-08-05 14:19:36 +0530194 subnet_id = subnet['id']
Mark Maglana5885eb32014-02-28 10:57:34 -0800195 # Verify subnet update
196 new_name = "New_subnet"
David Kranz34e88122014-12-11 15:24:05 -0500197 body = self.client.update_subnet(subnet_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530198 updated_subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800199 self.assertEqual(updated_subnet['name'], new_name)
Unmesh Gurjar44986832012-05-08 19:57:10 +0530200
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900201 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800202 @test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530203 def test_show_network(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800204 # Verify the details of a network
David Kranz34e88122014-12-11 15:24:05 -0500205 body = self.client.show_network(self.network['id'])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530206 network = body['network']
Mark Maglana5885eb32014-02-28 10:57:34 -0800207 for key in ['id', 'name']:
208 self.assertEqual(network[key], self.network[key])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530209
Chris Hoge7579c1a2015-02-26 14:12:15 -0800210 @test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
jun xied557d9b2014-01-09 14:00:36 +0800211 def test_show_network_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800212 # Verify specific fields of a network
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500213 fields = ['id', 'name']
David Kranz34e88122014-12-11 15:24:05 -0500214 body = self.client.show_network(self.network['id'],
215 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800216 network = body['network']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500217 self.assertEqual(sorted(network.keys()), sorted(fields))
218 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800219 self.assertEqual(network[field_name], self.network[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800220
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900221 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800222 @test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
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
Chris Hoge7579c1a2015-02-26 14:12:15 -0800230 @test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
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')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800241 @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
Miguel Lavallecc939612013-02-22 17:27:20 -0600242 def test_show_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800243 # Verify the details of a subnet
David Kranz34e88122014-12-11 15:24:05 -0500244 body = self.client.show_subnet(self.subnet['id'])
Miguel Lavallecc939612013-02-22 17:27:20 -0600245 subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800246 self.assertNotEmpty(subnet, "Subnet returned has no fields")
247 for key in ['id', 'cidr']:
248 self.assertIn(key, subnet)
249 self.assertEqual(subnet[key], self.subnet[key])
Miguel Lavallecc939612013-02-22 17:27:20 -0600250
Chris Hoge7579c1a2015-02-26 14:12:15 -0800251 @test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
jun xied557d9b2014-01-09 14:00:36 +0800252 def test_show_subnet_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800253 # Verify specific fields of a subnet
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500254 fields = ['id', 'network_id']
David Kranz34e88122014-12-11 15:24:05 -0500255 body = self.client.show_subnet(self.subnet['id'],
256 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800257 subnet = body['subnet']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500258 self.assertEqual(sorted(subnet.keys()), sorted(fields))
259 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800260 self.assertEqual(subnet[field_name], self.subnet[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800261
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900262 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800263 @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
Miguel Lavallecc939612013-02-22 17:27:20 -0600264 def test_list_subnets(self):
265 # Verify the subnet exists in the list of all subnets
David Kranz34e88122014-12-11 15:24:05 -0500266 body = self.client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800267 subnets = [subnet['id'] for subnet in body['subnets']
268 if subnet['id'] == self.subnet['id']]
269 self.assertNotEmpty(subnets, "Created subnet not found in the list")
raiesmh08e1aad982013-08-05 14:19:36 +0530270
Chris Hoge7579c1a2015-02-26 14:12:15 -0800271 @test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
jun xie0b4735d2014-01-07 15:42:58 +0800272 def test_list_subnets_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800273 # Verify specific fields of subnets
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500274 fields = ['id', 'network_id']
David Kranz34e88122014-12-11 15:24:05 -0500275 body = self.client.list_subnets(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800276 subnets = body['subnets']
Mark Maglana5885eb32014-02-28 10:57:34 -0800277 self.assertNotEmpty(subnets, "Subnet list returned is empty")
278 for subnet in subnets:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500279 self.assertEqual(sorted(subnet.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800280
sukhdevc704a702014-01-15 11:50:56 -0800281 def _try_delete_network(self, net_id):
282 # delete network, if it exists
283 try:
284 self.client.delete_network(net_id)
285 # if network is not found, this means it was deleted in the test
Masayuki Igawabfa07602015-01-20 18:47:17 +0900286 except lib_exc.NotFound:
sukhdevc704a702014-01-15 11:50:56 -0800287 pass
288
Chris Hoge7579c1a2015-02-26 14:12:15 -0800289 @test.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
sukhdevc704a702014-01-15 11:50:56 -0800290 def test_delete_network_with_subnet(self):
291 # Creates a network
292 name = data_utils.rand_name('network-')
David Kranz34e88122014-12-11 15:24:05 -0500293 body = self.client.create_network(name=name)
sukhdevc704a702014-01-15 11:50:56 -0800294 network = body['network']
295 net_id = network['id']
296 self.addCleanup(self._try_delete_network, net_id)
297
298 # Find a cidr that is not in use yet and create a subnet with it
299 subnet = self.create_subnet(network)
300 subnet_id = subnet['id']
301
302 # Delete network while the subnet still exists
David Kranz34e88122014-12-11 15:24:05 -0500303 body = self.client.delete_network(net_id)
sukhdevc704a702014-01-15 11:50:56 -0800304
305 # Verify that the subnet got automatically deleted.
Masayuki Igawabfa07602015-01-20 18:47:17 +0900306 self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
sukhdevc704a702014-01-15 11:50:56 -0800307 subnet_id)
308
309 # Since create_subnet adds the subnet to the delete list, and it is
310 # is actually deleted here - this will create and issue, hence remove
311 # it from the list.
312 self.subnets.pop()
313
Chris Hoge7579c1a2015-02-26 14:12:15 -0800314 @test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400315 def test_create_delete_subnet_without_gateway(self):
316 self._create_verify_delete_subnet()
317
Chris Hoge7579c1a2015-02-26 14:12:15 -0800318 @test.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800319 def test_create_delete_subnet_with_gw(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200320 self._create_verify_delete_subnet(
321 **self.subnet_dict(['gateway']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800322
Chris Hoge7579c1a2015-02-26 14:12:15 -0800323 @test.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200324 def test_create_delete_subnet_with_allocation_pools(self):
325 self._create_verify_delete_subnet(
326 **self.subnet_dict(['allocation_pools']))
327
Chris Hoge7579c1a2015-02-26 14:12:15 -0800328 @test.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200329 def test_create_delete_subnet_with_gw_and_allocation_pools(self):
330 self._create_verify_delete_subnet(**self.subnet_dict(
331 ['gateway', 'allocation_pools']))
332
Chris Hoge7579c1a2015-02-26 14:12:15 -0800333 @test.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200334 def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
335 self._create_verify_delete_subnet(
336 **self.subnet_dict(['host_routes', 'dns_nameservers']))
337
Chris Hoge7579c1a2015-02-26 14:12:15 -0800338 @test.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200339 def test_create_delete_subnet_with_dhcp_enabled(self):
340 self._create_verify_delete_subnet(enable_dhcp=True)
341
Chris Hoge7579c1a2015-02-26 14:12:15 -0800342 @test.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200343 def test_update_subnet_gw_dns_host_routes_dhcp(self):
344 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000345 self.addCleanup(self._delete_network, network)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200346
347 subnet = self.create_subnet(
348 network, **self.subnet_dict(['gateway', 'host_routes',
349 'dns_nameservers',
350 'allocation_pools']))
351 subnet_id = subnet['id']
352 new_gateway = str(netaddr.IPAddress(
353 self._subnet_data[self._ip_version]['gateway']) + 1)
354 # Verify subnet update
355 new_host_routes = self._subnet_data[self._ip_version][
356 'new_host_routes']
357
358 new_dns_nameservers = self._subnet_data[self._ip_version][
359 'new_dns_nameservers']
360 kwargs = {'host_routes': new_host_routes,
361 'dns_nameservers': new_dns_nameservers,
362 'gateway_ip': new_gateway, 'enable_dhcp': True}
363
364 new_name = "New_subnet"
David Kranz34e88122014-12-11 15:24:05 -0500365 body = self.client.update_subnet(subnet_id, name=new_name,
366 **kwargs)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200367 updated_subnet = body['subnet']
368 kwargs['name'] = new_name
369 self.assertEqual(sorted(updated_subnet['dns_nameservers']),
370 sorted(kwargs['dns_nameservers']))
371 del subnet['dns_nameservers'], kwargs['dns_nameservers']
372
373 self._compare_resource_attrs(updated_subnet, kwargs)
374
Chris Hoge7579c1a2015-02-26 14:12:15 -0800375 @test.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200376 def test_create_delete_subnet_all_attributes(self):
377 self._create_verify_delete_subnet(
378 enable_dhcp=True,
379 **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800380
Yair Friedbfdfc752014-09-28 13:56:45 +0300381 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800382 @test.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
Yair Friedbfdfc752014-09-28 13:56:45 +0300383 def test_external_network_visibility(self):
384 """Verifies user can see external networks but not subnets."""
David Kranz34e88122014-12-11 15:24:05 -0500385 body = self.client.list_networks(**{'router:external': True})
Yair Friedbfdfc752014-09-28 13:56:45 +0300386 networks = [network['id'] for network in body['networks']]
387 self.assertNotEmpty(networks, "No external networks found")
388
389 nonexternal = [net for net in body['networks'] if
390 not net['router:external']]
391 self.assertEmpty(nonexternal, "Found non-external networks"
392 " in filtered list (%s)." % nonexternal)
393 self.assertIn(CONF.network.public_network_id, networks)
394
Xavier León3aa65342015-05-12 15:24:28 +0000395 subnets_iter = (network['subnets']
396 for network in body['networks']
397 if not network['shared'])
Yair Friedbfdfc752014-09-28 13:56:45 +0300398 # subnets_iter is a list (iterator) of lists. This flattens it to a
399 # list of UUIDs
400 public_subnets_iter = itertools.chain(*subnets_iter)
David Kranz34e88122014-12-11 15:24:05 -0500401 body = self.client.list_subnets()
Yair Friedbfdfc752014-09-28 13:56:45 +0300402 subnets = [sub['id'] for sub in body['subnets']
403 if sub['id'] in public_subnets_iter]
404 self.assertEmpty(subnets, "Public subnets visible")
405
raiesmh086b055e22013-09-16 12:59:57 +0530406
Ken'ichi Ohmichi91c675d2014-02-06 02:15:21 +0900407class BulkNetworkOpsTestJSON(base.BaseNetworkTest):
raiesmh086b055e22013-09-16 12:59:57 +0530408 """
409 Tests the following operations in the Neutron API using the REST client for
410 Neutron:
411
412 bulk network creation
413 bulk subnet creation
Eugene Nikanorove9d255a2013-12-18 16:31:42 +0400414 bulk port creation
raiesmh086b055e22013-09-16 12:59:57 +0530415 list tenant's networks
416
417 v2.0 of the Neutron API is assumed. It is also assumed that the following
418 options are defined in the [network] section of etc/tempest.conf:
419
420 tenant_network_cidr with a block of cidr's from which smaller blocks
421 can be allocated for tenant networks
422
423 tenant_network_mask_bits with the mask bits to be used to partition the
424 block defined by tenant-network_cidr
425 """
426
raiesmh086b055e22013-09-16 12:59:57 +0530427 def _delete_networks(self, created_networks):
428 for n in created_networks:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200429 self.client.delete_network(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530430 # Asserting that the networks are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500431 body = self.client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800432 networks_list = [network['id'] for network in body['networks']]
raiesmh086b055e22013-09-16 12:59:57 +0530433 for n in created_networks:
434 self.assertNotIn(n['id'], networks_list)
435
436 def _delete_subnets(self, created_subnets):
437 for n in created_subnets:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200438 self.client.delete_subnet(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530439 # Asserting that the subnets are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500440 body = self.client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800441 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh086b055e22013-09-16 12:59:57 +0530442 for n in created_subnets:
443 self.assertNotIn(n['id'], subnets_list)
444
445 def _delete_ports(self, created_ports):
446 for n in created_ports:
Rohan Kanadeeeb21642014-08-14 12:00:26 +0200447 self.client.delete_port(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530448 # Asserting that the ports are not found in the list after deletion
David Kranz34e88122014-12-11 15:24:05 -0500449 body = self.client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800450 ports_list = [port['id'] for port in body['ports']]
raiesmh086b055e22013-09-16 12:59:57 +0530451 for n in created_ports:
452 self.assertNotIn(n['id'], ports_list)
453
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900454 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800455 @test.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
Nayna Patelb03eab42013-08-08 08:58:48 +0000456 def test_bulk_create_delete_network(self):
457 # Creates 2 networks in one request
Masayuki Igawa259c1132013-10-31 17:48:44 +0900458 network_names = [data_utils.rand_name('network-'),
459 data_utils.rand_name('network-')]
David Kranz34e88122014-12-11 15:24:05 -0500460 body = self.client.create_bulk_network(network_names)
Nayna Patelb03eab42013-08-08 08:58:48 +0000461 created_networks = body['networks']
Nayna Patelb03eab42013-08-08 08:58:48 +0000462 self.addCleanup(self._delete_networks, created_networks)
463 # Asserting that the networks are found in the list after creation
David Kranz34e88122014-12-11 15:24:05 -0500464 body = self.client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800465 networks_list = [network['id'] for network in body['networks']]
Nayna Patelb03eab42013-08-08 08:58:48 +0000466 for n in created_networks:
467 self.assertIsNotNone(n['id'])
468 self.assertIn(n['id'], networks_list)
raiesmh0867698322013-08-20 13:09:01 +0530469
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900470 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800471 @test.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
raiesmh082d5c6512013-09-06 15:35:05 +0530472 def test_bulk_create_delete_subnet(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300473 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530474 # Creates 2 subnets in one request
Rohan Kanade0efb0232015-02-19 13:33:31 +0530475 if self._ip_version == 4:
476 cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
477 mask_bits = CONF.network.tenant_network_mask_bits
478 else:
479 cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
480 mask_bits = CONF.network.tenant_network_v6_mask_bits
481
Mark Maglana5885eb32014-02-28 10:57:34 -0800482 cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
Rohan Kanade0efb0232015-02-19 13:33:31 +0530483
Mark Maglana5885eb32014-02-28 10:57:34 -0800484 names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
485 subnets_list = []
raiesmh082d5c6512013-09-06 15:35:05 +0530486 for i in range(len(names)):
487 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300488 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530489 'cidr': str(cidrs[(i)]),
490 'name': names[i],
Rohan Kanade0efb0232015-02-19 13:33:31 +0530491 'ip_version': self._ip_version
raiesmh082d5c6512013-09-06 15:35:05 +0530492 }
Mark Maglana5885eb32014-02-28 10:57:34 -0800493 subnets_list.append(p1)
494 del subnets_list[1]['name']
David Kranz34e88122014-12-11 15:24:05 -0500495 body = self.client.create_bulk_subnet(subnets_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530496 created_subnets = body['subnets']
497 self.addCleanup(self._delete_subnets, created_subnets)
raiesmh082d5c6512013-09-06 15:35:05 +0530498 # Asserting that the subnets are found in the list after creation
David Kranz34e88122014-12-11 15:24:05 -0500499 body = self.client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800500 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh082d5c6512013-09-06 15:35:05 +0530501 for n in created_subnets:
502 self.assertIsNotNone(n['id'])
503 self.assertIn(n['id'], subnets_list)
504
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900505 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800506 @test.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
raiesmh082d5c6512013-09-06 15:35:05 +0530507 def test_bulk_create_delete_port(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300508 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530509 # Creates 2 ports in one request
Mark Maglana5885eb32014-02-28 10:57:34 -0800510 names = [data_utils.rand_name('port-') for i in range(len(networks))]
raiesmh082d5c6512013-09-06 15:35:05 +0530511 port_list = []
512 state = [True, False]
513 for i in range(len(names)):
514 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300515 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530516 'name': names[i],
517 'admin_state_up': state[i],
518 }
519 port_list.append(p1)
520 del port_list[1]['name']
David Kranz34e88122014-12-11 15:24:05 -0500521 body = self.client.create_bulk_port(port_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530522 created_ports = body['ports']
523 self.addCleanup(self._delete_ports, created_ports)
raiesmh082d5c6512013-09-06 15:35:05 +0530524 # Asserting that the ports are found in the list after creation
David Kranz34e88122014-12-11 15:24:05 -0500525 body = self.client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800526 ports_list = [port['id'] for port in body['ports']]
raiesmh082d5c6512013-09-06 15:35:05 +0530527 for n in created_ports:
528 self.assertIsNotNone(n['id'])
529 self.assertIn(n['id'], ports_list)
530
raiesmh0867698322013-08-20 13:09:01 +0530531
Rohan Kanade0efb0232015-02-19 13:33:31 +0530532class BulkNetworkOpsIpV6TestJSON(BulkNetworkOpsTestJSON):
533 _ip_version = 6
534
535
Matthew Treinishe4184ea2015-09-03 21:13:09 -0400536class NetworksIpV6TestJSON(NetworksTest):
Henry Gessauffda37a2014-01-16 11:17:55 -0500537 _ip_version = 6
Henry Gessauffda37a2014-01-16 11:17:55 -0500538
Chris Hoge7579c1a2015-02-26 14:12:15 -0800539 @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800540 def test_create_delete_subnet_with_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530541 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
542 gateway = str(netaddr.IPAddress(net.first + 2))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800543 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200544 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800545 subnet = self.create_subnet(network, gateway)
546 # Verifies Subnet GW in IPv6
547 self.assertEqual(subnet['gateway_ip'], gateway)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800548
Chris Hoge7579c1a2015-02-26 14:12:15 -0800549 @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400550 def test_create_delete_subnet_with_default_gw(self):
sridhargaddamea73d532014-05-13 14:48:30 +0530551 net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
552 gateway_ip = str(netaddr.IPAddress(net.first + 1))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800553 name = data_utils.rand_name('network-')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200554 network = self.create_network(network_name=name)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800555 subnet = self.create_subnet(network)
556 # Verifies Subnet GW in IPv6
sridhargaddamea73d532014-05-13 14:48:30 +0530557 self.assertEqual(subnet['gateway_ip'], gateway_ip)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800558
Chris Hoge7579c1a2015-02-26 14:12:15 -0800559 @test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400560 def test_create_list_subnet_with_no_gw64_one_network(self):
561 name = data_utils.rand_name('network-')
562 network = self.create_network(name)
563 ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
564 subnet1 = self.create_subnet(network,
565 ip_version=6,
566 gateway=ipv6_gateway)
567 self.assertEqual(netaddr.IPNetwork(subnet1['cidr']).version, 6,
568 'The created subnet is not IPv6')
569 subnet2 = self.create_subnet(network,
570 gateway=None,
571 ip_version=4)
572 self.assertEqual(netaddr.IPNetwork(subnet2['cidr']).version, 4,
573 'The created subnet is not IPv4')
574 # Verifies Subnet GW is set in IPv6
575 self.assertEqual(subnet1['gateway_ip'], ipv6_gateway)
576 # Verifies Subnet GW is None in IPv4
577 self.assertEqual(subnet2['gateway_ip'], None)
578 # Verifies all 2 subnets in the same network
David Kranz34e88122014-12-11 15:24:05 -0500579 body = self.client.list_subnets()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400580 subnets = [sub['id'] for sub in body['subnets']
581 if sub['network_id'] == network['id']]
582 test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
583 self.assertItemsEqual(subnets,
584 test_subnet_ids,
585 'Subnet are not in the same network')
586
Sergey She757c332014-11-25 01:16:32 +0300587
588class NetworksIpV6TestAttrs(NetworksIpV6TestJSON):
589
590 @classmethod
Rohan Kanadea565e452015-01-27 14:00:13 +0530591 def skip_checks(cls):
592 super(NetworksIpV6TestAttrs, cls).skip_checks()
Sergey She757c332014-11-25 01:16:32 +0300593 if not CONF.network_feature_enabled.ipv6_subnet_attributes:
594 raise cls.skipException("IPv6 extended attributes for "
595 "subnets not available")
Sergey She757c332014-11-25 01:16:32 +0300596
Chris Hoge7579c1a2015-02-26 14:12:15 -0800597 @test.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400598 def test_create_delete_subnet_with_v6_attributes_stateful(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200599 self._create_verify_delete_subnet(
600 gateway=self._subnet_data[self._ip_version]['gateway'],
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400601 ipv6_ra_mode='dhcpv6-stateful',
602 ipv6_address_mode='dhcpv6-stateful')
603
Chris Hoge7579c1a2015-02-26 14:12:15 -0800604 @test.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400605 def test_create_delete_subnet_with_v6_attributes_slaac(self):
606 self._create_verify_delete_subnet(
Rohan Kanade35589aa2014-08-19 14:56:12 +0200607 ipv6_ra_mode='slaac',
608 ipv6_address_mode='slaac')
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400609
Chris Hoge7579c1a2015-02-26 14:12:15 -0800610 @test.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400611 def test_create_delete_subnet_with_v6_attributes_stateless(self):
612 self._create_verify_delete_subnet(
613 ipv6_ra_mode='dhcpv6-stateless',
614 ipv6_address_mode='dhcpv6-stateless')
Sergey She757c332014-11-25 01:16:32 +0300615
616 def _test_delete_subnet_with_ports(self, mode):
617 """Create subnet and delete it with existing ports"""
618 slaac_network = self.create_network()
619 subnet_slaac = self.create_subnet(slaac_network,
620 **{'ipv6_ra_mode': mode,
621 'ipv6_address_mode': mode})
622 port = self.create_port(slaac_network)
623 self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
624 self.client.delete_subnet(subnet_slaac['id'])
625 self.subnets.pop()
626 subnets = self.client.list_subnets()
627 subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
628 self.assertNotIn(subnet_slaac['id'], subnet_ids,
629 "Subnet wasn't deleted")
630 self.assertRaisesRegexp(
Masayuki Igawad9388762015-01-20 14:56:42 +0900631 lib_exc.Conflict,
Sergey She757c332014-11-25 01:16:32 +0300632 "There are one or more ports still in use on the network",
633 self.client.delete_network,
634 slaac_network['id'])
635
Chris Hoge7579c1a2015-02-26 14:12:15 -0800636 @test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
Sergey She757c332014-11-25 01:16:32 +0300637 def test_create_delete_slaac_subnet_with_ports(self):
638 """Test deleting subnet with SLAAC ports
639
640 Create subnet with SLAAC, create ports in network
641 and then you shall be able to delete subnet without port
642 deletion. But you still can not delete the network.
643 """
644 self._test_delete_subnet_with_ports("slaac")
645
Chris Hoge7579c1a2015-02-26 14:12:15 -0800646 @test.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
Sergey She757c332014-11-25 01:16:32 +0300647 def test_create_delete_stateless_subnet_with_ports(self):
648 """Test deleting subnet with DHCPv6 stateless ports
649
650 Create subnet with DHCPv6 stateless, create ports in network
651 and then you shall be able to delete subnet without port
652 deletion. But you still can not delete the network.
653 """
654 self._test_delete_subnet_with_ports("dhcpv6-stateless")