blob: 6b0c20fd6197cf7d5e66b9a680a544b360d649d2 [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Jay Pipesf4dad392012-06-05 16:03:58 -04002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
Miguel Lavallecc939612013-02-22 17:27:20 -060015import netaddr
Matthew Treinish71426682015-04-23 11:19:38 -040016import six
Kevin Benton6919da42016-03-05 18:00:03 -080017import testtools
Jay Pipesf4dad392012-06-05 16:03:58 -040018
Sean Dague1937d092013-05-17 16:36:38 -040019from tempest.api.network import base
Rohan Kanade35589aa2014-08-19 14:56:12 +020020from tempest.common import custom_matchers
Fei Long Wangd39431f2015-05-14 11:30:48 +120021from tempest.common.utils import data_utils
Matthew Treinish03b48df2014-01-29 16:59:49 +000022from tempest import config
Jordan Pittier9e227c52016-02-09 14:35:18 +010023from tempest.lib.common.utils import test_utils
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050024from tempest.lib import exceptions as lib_exc
Masayuki Igawa6d495d62014-03-19 16:38:57 +090025from tempest import test
Unmesh Gurjar44986832012-05-08 19:57:10 +053026
Matthew Treinish03b48df2014-01-29 16:59:49 +000027CONF = config.CONF
28
Unmesh Gurjar44986832012-05-08 19:57:10 +053029
Matthew Treinishe4184ea2015-09-03 21:13:09 -040030class NetworksTest(base.BaseNetworkTest):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +000031 """Tests the following operations in the Neutron API:
Miguel Lavallecc939612013-02-22 17:27:20 -060032
Sean Dagueed6e5862016-04-04 10:49:13 -040033 create a network for a project
34 list project's networks
35 show a project network details
36 create a subnet for a project
37 list project's subnets
38 show a project subnet details
raiesmh08e1aad982013-08-05 14:19:36 +053039 network update
40 subnet update
sukhdevc704a702014-01-15 11:50:56 -080041 delete a network also deletes its subnets
Yair Friedbfdfc752014-09-28 13:56:45 +030042 list external networks
Miguel Lavallecc939612013-02-22 17:27:20 -060043
Henry Gessauffda37a2014-01-16 11:17:55 -050044 All subnet tests are run once with ipv4 and once with ipv6.
45
Mark McClainf2982e82013-07-06 17:48:03 -040046 v2.0 of the Neutron API is assumed. It is also assumed that the following
Miguel Lavallecc939612013-02-22 17:27:20 -060047 options are defined in the [network] section of etc/tempest.conf:
48
Sean Dagueed6e5862016-04-04 10:49:13 -040049 project_network_cidr with a block of cidr's from which smaller blocks
50 can be allocated for project ipv4 subnets
Henry Gessauffda37a2014-01-16 11:17:55 -050051
Sean Dagueed6e5862016-04-04 10:49:13 -040052 project_network_v6_cidr is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060053
Sean Dagueed6e5862016-04-04 10:49:13 -040054 project_network_mask_bits with the mask bits to be used to partition
55 the block defined by project_network_cidr
Henry Gessauffda37a2014-01-16 11:17:55 -050056
Sean Dagueed6e5862016-04-04 10:49:13 -040057 project_network_v6_mask_bits is the equivalent for ipv6 subnets
Miguel Lavallecc939612013-02-22 17:27:20 -060058 """
59
Unmesh Gurjar44986832012-05-08 19:57:10 +053060 @classmethod
Andrea Frittolida4a2452014-09-15 13:12:08 +010061 def resource_setup(cls):
Matthew Treinishe4184ea2015-09-03 21:13:09 -040062 super(NetworksTest, cls).resource_setup()
Jay Pipesf4dad392012-06-05 16:03:58 -040063 cls.network = cls.create_network()
64 cls.name = cls.network['name']
venakata anil1a2a64a2014-12-02 07:25:59 +000065 cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
66 cls._ip_version)
Rohan Kanade35589aa2014-08-19 14:56:12 +020067 cls._subnet_data = {6: {'gateway':
68 str(cls._get_gateway_from_tempest_conf(6)),
69 'allocation_pools':
70 cls._get_allocation_pools_from_gateway(6),
71 'dns_nameservers': ['2001:4860:4860::8844',
72 '2001:4860:4860::8888'],
73 'host_routes': [{'destination': '2001::/64',
74 'nexthop': '2003::1'}],
75 'new_host_routes': [{'destination':
76 '2001::/64',
77 'nexthop': '2005::1'}],
78 'new_dns_nameservers':
79 ['2001:4860:4860::7744',
80 '2001:4860:4860::7888']},
81 4: {'gateway':
82 str(cls._get_gateway_from_tempest_conf(4)),
83 'allocation_pools':
84 cls._get_allocation_pools_from_gateway(4),
85 'dns_nameservers': ['8.8.4.4', '8.8.8.8'],
86 'host_routes': [{'destination': '10.20.0.0/32',
87 'nexthop': '10.100.1.1'}],
88 'new_host_routes': [{'destination':
89 '10.20.0.0/32',
90 'nexthop':
91 '10.100.1.2'}],
92 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
93
94 @classmethod
venakata anil1a2a64a2014-12-02 07:25:59 +000095 def _create_subnet_with_last_subnet_block(cls, network, ip_version):
Sean Dagueed6e5862016-04-04 10:49:13 -040096 # Derive last subnet CIDR block from project CIDR and
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +000097 # create the subnet with that derived CIDR
venakata anil1a2a64a2014-12-02 07:25:59 +000098 if ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -040099 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
100 mask_bits = CONF.network.project_network_mask_bits
venakata anil1a2a64a2014-12-02 07:25:59 +0000101 elif ip_version == 6:
Sean Dagueed6e5862016-04-04 10:49:13 -0400102 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
103 mask_bits = CONF.network.project_network_v6_mask_bits
venakata anil1a2a64a2014-12-02 07:25:59 +0000104
105 subnet_cidr = list(cidr.subnet(mask_bits))[-1]
106 gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
107 return cls.create_subnet(network, gateway=gateway_ip,
108 cidr=subnet_cidr, mask_bits=mask_bits)
109
110 @classmethod
Rohan Kanade35589aa2014-08-19 14:56:12 +0200111 def _get_gateway_from_tempest_conf(cls, ip_version):
112 """Return first subnet gateway for configured CIDR """
113 if ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -0400114 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
115 mask_bits = CONF.network.project_network_mask_bits
Rohan Kanade35589aa2014-08-19 14:56:12 +0200116 elif ip_version == 6:
Sean Dagueed6e5862016-04-04 10:49:13 -0400117 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
118 mask_bits = CONF.network.project_network_v6_mask_bits
Rohan Kanade35589aa2014-08-19 14:56:12 +0200119
120 if mask_bits >= cidr.prefixlen:
121 return netaddr.IPAddress(cidr) + 1
122 else:
123 for subnet in cidr.subnet(mask_bits):
124 return netaddr.IPAddress(subnet) + 1
125
126 @classmethod
127 def _get_allocation_pools_from_gateway(cls, ip_version):
128 """Return allocation range for subnet of given gateway"""
129 gateway = cls._get_gateway_from_tempest_conf(ip_version)
Hynek Mlnarikbe634fc2016-06-27 09:34:15 +0200130 return [{'start': str(gateway + 2), 'end': str(gateway + 6)}]
Rohan Kanade35589aa2014-08-19 14:56:12 +0200131
132 def subnet_dict(self, include_keys):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000133 # Return a subnet dict which has include_keys and their corresponding
134 # value from self._subnet_data
Rohan Kanade35589aa2014-08-19 14:56:12 +0200135 return dict((key, self._subnet_data[self._ip_version][key])
136 for key in include_keys)
137
138 def _compare_resource_attrs(self, actual, expected):
139 exclude_keys = set(actual).symmetric_difference(expected)
140 self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
141 expected, exclude_keys))
142
venakata anil1a2a64a2014-12-02 07:25:59 +0000143 def _delete_network(self, network):
144 # Deleting network also deletes its subnets if exists
John Warren94d8faf2015-09-15 12:22:24 -0400145 self.networks_client.delete_network(network['id'])
venakata anil1a2a64a2014-12-02 07:25:59 +0000146 if network in self.networks:
147 self.networks.remove(network)
148 for subnet in self.subnets:
149 if subnet['network_id'] == network['id']:
150 self.subnets.remove(subnet)
151
Rohan Kanade35589aa2014-08-19 14:56:12 +0200152 def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
153 **kwargs):
154 network = self.create_network()
155 net_id = network['id']
156 gateway = kwargs.pop('gateway', None)
157 subnet = self.create_subnet(network, gateway, cidr, mask_bits,
158 **kwargs)
159 compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
160 mask_bits=mask_bits, **kwargs)
Matthew Treinish71426682015-04-23 11:19:38 -0400161 compare_args = dict((k, v) for k, v in six.iteritems(compare_args_full)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200162 if v is not None)
163
164 if 'dns_nameservers' in set(subnet).intersection(compare_args):
165 self.assertEqual(sorted(compare_args['dns_nameservers']),
166 sorted(subnet['dns_nameservers']))
167 del subnet['dns_nameservers'], compare_args['dns_nameservers']
168
169 self._compare_resource_attrs(subnet, compare_args)
John Warren94d8faf2015-09-15 12:22:24 -0400170 self.networks_client.delete_network(net_id)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200171 self.networks.pop()
172 self.subnets.pop()
Unmesh Gurjar44986832012-05-08 19:57:10 +0530173
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900174 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800175 @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
raiesmh08e1aad982013-08-05 14:19:36 +0530176 def test_create_update_delete_network_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800177 # Create a network
zhufld2c40ca2016-10-18 17:03:07 +0800178 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000179 self.addCleanup(self._delete_network, network)
raiesmh08e1aad982013-08-05 14:19:36 +0530180 net_id = network['id']
Santosh Kumar42c94802014-08-08 04:31:42 -0700181 self.assertEqual('ACTIVE', network['status'])
Mark Maglana5885eb32014-02-28 10:57:34 -0800182 # Verify network update
raiesmh08e1aad982013-08-05 14:19:36 +0530183 new_name = "New_network"
John Warren94d8faf2015-09-15 12:22:24 -0400184 body = self.networks_client.update_network(net_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530185 updated_net = body['network']
186 self.assertEqual(updated_net['name'], new_name)
Miguel Lavallecc939612013-02-22 17:27:20 -0600187 # Find a cidr that is not in use yet and create a subnet with it
Matthew Treinish6b8cd2a2014-03-03 20:45:56 +0000188 subnet = self.create_subnet(network)
raiesmh08e1aad982013-08-05 14:19:36 +0530189 subnet_id = subnet['id']
Mark Maglana5885eb32014-02-28 10:57:34 -0800190 # Verify subnet update
191 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400192 body = self.subnets_client.update_subnet(subnet_id, name=new_name)
raiesmh08e1aad982013-08-05 14:19:36 +0530193 updated_subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800194 self.assertEqual(updated_subnet['name'], new_name)
Unmesh Gurjar44986832012-05-08 19:57:10 +0530195
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900196 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800197 @test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530198 def test_show_network(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800199 # Verify the details of a network
John Warren94d8faf2015-09-15 12:22:24 -0400200 body = self.networks_client.show_network(self.network['id'])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530201 network = body['network']
Mark Maglana5885eb32014-02-28 10:57:34 -0800202 for key in ['id', 'name']:
203 self.assertEqual(network[key], self.network[key])
Unmesh Gurjar44986832012-05-08 19:57:10 +0530204
Chris Hoge7579c1a2015-02-26 14:12:15 -0800205 @test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
jun xied557d9b2014-01-09 14:00:36 +0800206 def test_show_network_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800207 # Verify specific fields of a network
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500208 fields = ['id', 'name']
John Warren94d8faf2015-09-15 12:22:24 -0400209 body = self.networks_client.show_network(self.network['id'],
210 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800211 network = body['network']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500212 self.assertEqual(sorted(network.keys()), sorted(fields))
213 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800214 self.assertEqual(network[field_name], self.network[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800215
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900216 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800217 @test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
Unmesh Gurjar44986832012-05-08 19:57:10 +0530218 def test_list_networks(self):
Sean Dague46c4a2b2013-01-03 17:54:17 -0500219 # Verify the network exists in the list of all networks
John Warren94d8faf2015-09-15 12:22:24 -0400220 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800221 networks = [network['id'] for network in body['networks']
222 if network['id'] == self.network['id']]
223 self.assertNotEmpty(networks, "Created network not found in the list")
Unmesh Gurjar44986832012-05-08 19:57:10 +0530224
Chris Hoge7579c1a2015-02-26 14:12:15 -0800225 @test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
jun xie0b4735d2014-01-07 15:42:58 +0800226 def test_list_networks_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800227 # Verify specific fields of the networks
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500228 fields = ['id', 'name']
John Warren94d8faf2015-09-15 12:22:24 -0400229 body = self.networks_client.list_networks(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800230 networks = body['networks']
Mark Maglana5885eb32014-02-28 10:57:34 -0800231 self.assertNotEmpty(networks, "Network list returned is empty")
232 for network in networks:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500233 self.assertEqual(sorted(network.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800234
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900235 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800236 @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
Miguel Lavallecc939612013-02-22 17:27:20 -0600237 def test_show_subnet(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800238 # Verify the details of a subnet
John Warren3961acd2015-10-02 14:38:53 -0400239 body = self.subnets_client.show_subnet(self.subnet['id'])
Miguel Lavallecc939612013-02-22 17:27:20 -0600240 subnet = body['subnet']
Mark Maglana5885eb32014-02-28 10:57:34 -0800241 self.assertNotEmpty(subnet, "Subnet returned has no fields")
242 for key in ['id', 'cidr']:
243 self.assertIn(key, subnet)
244 self.assertEqual(subnet[key], self.subnet[key])
Miguel Lavallecc939612013-02-22 17:27:20 -0600245
Chris Hoge7579c1a2015-02-26 14:12:15 -0800246 @test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
jun xied557d9b2014-01-09 14:00:36 +0800247 def test_show_subnet_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800248 # Verify specific fields of a subnet
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500249 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400250 body = self.subnets_client.show_subnet(self.subnet['id'],
251 fields=fields)
jun xied557d9b2014-01-09 14:00:36 +0800252 subnet = body['subnet']
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500253 self.assertEqual(sorted(subnet.keys()), sorted(fields))
254 for field_name in fields:
Mark Maglana5885eb32014-02-28 10:57:34 -0800255 self.assertEqual(subnet[field_name], self.subnet[field_name])
jun xied557d9b2014-01-09 14:00:36 +0800256
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900257 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800258 @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
Miguel Lavallecc939612013-02-22 17:27:20 -0600259 def test_list_subnets(self):
260 # Verify the subnet exists in the list of all subnets
John Warren3961acd2015-10-02 14:38:53 -0400261 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800262 subnets = [subnet['id'] for subnet in body['subnets']
263 if subnet['id'] == self.subnet['id']]
264 self.assertNotEmpty(subnets, "Created subnet not found in the list")
raiesmh08e1aad982013-08-05 14:19:36 +0530265
Chris Hoge7579c1a2015-02-26 14:12:15 -0800266 @test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
jun xie0b4735d2014-01-07 15:42:58 +0800267 def test_list_subnets_fields(self):
Mark Maglana5885eb32014-02-28 10:57:34 -0800268 # Verify specific fields of subnets
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500269 fields = ['id', 'network_id']
John Warren3961acd2015-10-02 14:38:53 -0400270 body = self.subnets_client.list_subnets(fields=fields)
jun xie0b4735d2014-01-07 15:42:58 +0800271 subnets = body['subnets']
Mark Maglana5885eb32014-02-28 10:57:34 -0800272 self.assertNotEmpty(subnets, "Subnet list returned is empty")
273 for subnet in subnets:
Zhi Kun Liu903596c2014-04-11 08:55:53 -0500274 self.assertEqual(sorted(subnet.keys()), sorted(fields))
jun xie0b4735d2014-01-07 15:42:58 +0800275
Chris Hoge7579c1a2015-02-26 14:12:15 -0800276 @test.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
sukhdevc704a702014-01-15 11:50:56 -0800277 def test_delete_network_with_subnet(self):
278 # Creates a network
Tianbiao Qi309ac412016-10-31 19:42:37 +0800279 network = self.create_network()
sukhdevc704a702014-01-15 11:50:56 -0800280 net_id = network['id']
Jordan Pittier9e227c52016-02-09 14:35:18 +0100281 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
Tianbiao Qi309ac412016-10-31 19:42:37 +0800282 self._delete_network, network)
sukhdevc704a702014-01-15 11:50:56 -0800283
284 # Find a cidr that is not in use yet and create a subnet with it
285 subnet = self.create_subnet(network)
286 subnet_id = subnet['id']
287
288 # Delete network while the subnet still exists
Tianbiao Qi309ac412016-10-31 19:42:37 +0800289 self.networks_client.delete_network(net_id)
sukhdevc704a702014-01-15 11:50:56 -0800290
291 # Verify that the subnet got automatically deleted.
John Warren3961acd2015-10-02 14:38:53 -0400292 self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
sukhdevc704a702014-01-15 11:50:56 -0800293 subnet_id)
294
Chris Hoge7579c1a2015-02-26 14:12:15 -0800295 @test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400296 def test_create_delete_subnet_without_gateway(self):
297 self._create_verify_delete_subnet()
298
Chris Hoge7579c1a2015-02-26 14:12:15 -0800299 @test.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800300 def test_create_delete_subnet_with_gw(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200301 self._create_verify_delete_subnet(
302 **self.subnet_dict(['gateway']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800303
Chris Hoge7579c1a2015-02-26 14:12:15 -0800304 @test.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200305 def test_create_delete_subnet_with_allocation_pools(self):
306 self._create_verify_delete_subnet(
307 **self.subnet_dict(['allocation_pools']))
308
Chris Hoge7579c1a2015-02-26 14:12:15 -0800309 @test.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200310 def test_create_delete_subnet_with_gw_and_allocation_pools(self):
311 self._create_verify_delete_subnet(**self.subnet_dict(
312 ['gateway', 'allocation_pools']))
313
Chris Hoge7579c1a2015-02-26 14:12:15 -0800314 @test.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200315 def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
316 self._create_verify_delete_subnet(
317 **self.subnet_dict(['host_routes', 'dns_nameservers']))
318
Chris Hoge7579c1a2015-02-26 14:12:15 -0800319 @test.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200320 def test_create_delete_subnet_with_dhcp_enabled(self):
321 self._create_verify_delete_subnet(enable_dhcp=True)
322
Chris Hoge7579c1a2015-02-26 14:12:15 -0800323 @test.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200324 def test_update_subnet_gw_dns_host_routes_dhcp(self):
325 network = self.create_network()
venakata anil1a2a64a2014-12-02 07:25:59 +0000326 self.addCleanup(self._delete_network, network)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200327
328 subnet = self.create_subnet(
329 network, **self.subnet_dict(['gateway', 'host_routes',
330 'dns_nameservers',
331 'allocation_pools']))
332 subnet_id = subnet['id']
333 new_gateway = str(netaddr.IPAddress(
334 self._subnet_data[self._ip_version]['gateway']) + 1)
335 # Verify subnet update
336 new_host_routes = self._subnet_data[self._ip_version][
337 'new_host_routes']
338
339 new_dns_nameservers = self._subnet_data[self._ip_version][
340 'new_dns_nameservers']
341 kwargs = {'host_routes': new_host_routes,
342 'dns_nameservers': new_dns_nameservers,
343 'gateway_ip': new_gateway, 'enable_dhcp': True}
344
345 new_name = "New_subnet"
John Warren3961acd2015-10-02 14:38:53 -0400346 body = self.subnets_client.update_subnet(subnet_id, name=new_name,
347 **kwargs)
Rohan Kanade35589aa2014-08-19 14:56:12 +0200348 updated_subnet = body['subnet']
349 kwargs['name'] = new_name
350 self.assertEqual(sorted(updated_subnet['dns_nameservers']),
351 sorted(kwargs['dns_nameservers']))
352 del subnet['dns_nameservers'], kwargs['dns_nameservers']
353
354 self._compare_resource_attrs(updated_subnet, kwargs)
355
Chris Hoge7579c1a2015-02-26 14:12:15 -0800356 @test.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
Rohan Kanade35589aa2014-08-19 14:56:12 +0200357 def test_create_delete_subnet_all_attributes(self):
358 self._create_verify_delete_subnet(
359 enable_dhcp=True,
360 **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
Edgar Magana6a9ac342014-01-16 13:52:49 -0800361
Yair Friedbfdfc752014-09-28 13:56:45 +0300362 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800363 @test.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
Kevin Benton6919da42016-03-05 18:00:03 -0800364 @test.requires_ext(extension='external-net', service='network')
365 @testtools.skipUnless(CONF.network.public_network_id,
366 'The public_network_id option must be specified.')
Yair Friedbfdfc752014-09-28 13:56:45 +0300367 def test_external_network_visibility(self):
368 """Verifies user can see external networks but not subnets."""
John Warren94d8faf2015-09-15 12:22:24 -0400369 body = self.networks_client.list_networks(**{'router:external': True})
Yair Friedbfdfc752014-09-28 13:56:45 +0300370 networks = [network['id'] for network in body['networks']]
371 self.assertNotEmpty(networks, "No external networks found")
372
373 nonexternal = [net for net in body['networks'] if
374 not net['router:external']]
375 self.assertEmpty(nonexternal, "Found non-external networks"
376 " in filtered list (%s)." % nonexternal)
377 self.assertIn(CONF.network.public_network_id, networks)
Kevin Benton6919da42016-03-05 18:00:03 -0800378 # only check the public network ID because the other networks may
379 # belong to other tests and their state may have changed during this
380 # test
381 body = self.subnets_client.list_subnets(
382 network_id=CONF.network.public_network_id)
383 self.assertEmpty(body['subnets'], "Public subnets visible")
Yair Friedbfdfc752014-09-28 13:56:45 +0300384
raiesmh086b055e22013-09-16 12:59:57 +0530385
Tong Liu7012c862016-04-11 22:32:05 +0000386class BulkNetworkOpsTest(base.BaseNetworkTest):
Ken'ichi Ohmichie03bea92015-11-19 07:45:58 +0000387 """Tests the following operations in the Neutron API:
raiesmh086b055e22013-09-16 12:59:57 +0530388
389 bulk network creation
390 bulk subnet creation
Eugene Nikanorove9d255a2013-12-18 16:31:42 +0400391 bulk port creation
Sean Dagueed6e5862016-04-04 10:49:13 -0400392 list project's networks
raiesmh086b055e22013-09-16 12:59:57 +0530393
394 v2.0 of the Neutron API is assumed. It is also assumed that the following
395 options are defined in the [network] section of etc/tempest.conf:
396
Sean Dagueed6e5862016-04-04 10:49:13 -0400397 project_network_cidr with a block of cidr's from which smaller blocks
398 can be allocated for project networks
raiesmh086b055e22013-09-16 12:59:57 +0530399
Sean Dagueed6e5862016-04-04 10:49:13 -0400400 project_network_mask_bits with the mask bits to be used to partition
401 the block defined by project-network_cidr
raiesmh086b055e22013-09-16 12:59:57 +0530402 """
403
raiesmh086b055e22013-09-16 12:59:57 +0530404 def _delete_networks(self, created_networks):
405 for n in created_networks:
John Warren94d8faf2015-09-15 12:22:24 -0400406 self.networks_client.delete_network(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530407 # Asserting that the networks are not found in the list after deletion
John Warren94d8faf2015-09-15 12:22:24 -0400408 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800409 networks_list = [network['id'] for network in body['networks']]
raiesmh086b055e22013-09-16 12:59:57 +0530410 for n in created_networks:
411 self.assertNotIn(n['id'], networks_list)
412
413 def _delete_subnets(self, created_subnets):
414 for n in created_subnets:
John Warren3961acd2015-10-02 14:38:53 -0400415 self.subnets_client.delete_subnet(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530416 # Asserting that the subnets are not found in the list after deletion
John Warren3961acd2015-10-02 14:38:53 -0400417 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800418 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh086b055e22013-09-16 12:59:57 +0530419 for n in created_subnets:
420 self.assertNotIn(n['id'], subnets_list)
421
422 def _delete_ports(self, created_ports):
423 for n in created_ports:
John Warren49c0fe52015-10-22 12:35:54 -0400424 self.ports_client.delete_port(n['id'])
raiesmh086b055e22013-09-16 12:59:57 +0530425 # Asserting that the ports are not found in the list after deletion
John Warren49c0fe52015-10-22 12:35:54 -0400426 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800427 ports_list = [port['id'] for port in body['ports']]
raiesmh086b055e22013-09-16 12:59:57 +0530428 for n in created_ports:
429 self.assertNotIn(n['id'], ports_list)
430
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900431 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800432 @test.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
Nayna Patelb03eab42013-08-08 08:58:48 +0000433 def test_bulk_create_delete_network(self):
434 # Creates 2 networks in one request
piyush1107867584aa72015-12-15 18:46:38 +0530435 network_list = [{'name': data_utils.rand_name('network-')},
436 {'name': data_utils.rand_name('network-')}]
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800437 body = self.networks_client.create_bulk_networks(networks=network_list)
Nayna Patelb03eab42013-08-08 08:58:48 +0000438 created_networks = body['networks']
Nayna Patelb03eab42013-08-08 08:58:48 +0000439 self.addCleanup(self._delete_networks, created_networks)
440 # Asserting that the networks are found in the list after creation
John Warren94d8faf2015-09-15 12:22:24 -0400441 body = self.networks_client.list_networks()
Mark Maglana5885eb32014-02-28 10:57:34 -0800442 networks_list = [network['id'] for network in body['networks']]
Nayna Patelb03eab42013-08-08 08:58:48 +0000443 for n in created_networks:
444 self.assertIsNotNone(n['id'])
445 self.assertIn(n['id'], networks_list)
raiesmh0867698322013-08-20 13:09:01 +0530446
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900447 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800448 @test.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
raiesmh082d5c6512013-09-06 15:35:05 +0530449 def test_bulk_create_delete_subnet(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300450 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530451 # Creates 2 subnets in one request
Rohan Kanade0efb0232015-02-19 13:33:31 +0530452 if self._ip_version == 4:
Sean Dagueed6e5862016-04-04 10:49:13 -0400453 cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
454 mask_bits = CONF.network.project_network_mask_bits
Rohan Kanade0efb0232015-02-19 13:33:31 +0530455 else:
Sean Dagueed6e5862016-04-04 10:49:13 -0400456 cidr = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
457 mask_bits = CONF.network.project_network_v6_mask_bits
Rohan Kanade0efb0232015-02-19 13:33:31 +0530458
Mark Maglana5885eb32014-02-28 10:57:34 -0800459 cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
Rohan Kanade0efb0232015-02-19 13:33:31 +0530460
Mark Maglana5885eb32014-02-28 10:57:34 -0800461 names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
462 subnets_list = []
raiesmh082d5c6512013-09-06 15:35:05 +0530463 for i in range(len(names)):
464 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300465 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530466 'cidr': str(cidrs[(i)]),
467 'name': names[i],
Rohan Kanade0efb0232015-02-19 13:33:31 +0530468 'ip_version': self._ip_version
raiesmh082d5c6512013-09-06 15:35:05 +0530469 }
Mark Maglana5885eb32014-02-28 10:57:34 -0800470 subnets_list.append(p1)
471 del subnets_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800472 body = self.subnets_client.create_bulk_subnets(subnets=subnets_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530473 created_subnets = body['subnets']
474 self.addCleanup(self._delete_subnets, created_subnets)
raiesmh082d5c6512013-09-06 15:35:05 +0530475 # Asserting that the subnets are found in the list after creation
John Warren3961acd2015-10-02 14:38:53 -0400476 body = self.subnets_client.list_subnets()
Mark Maglana5885eb32014-02-28 10:57:34 -0800477 subnets_list = [subnet['id'] for subnet in body['subnets']]
raiesmh082d5c6512013-09-06 15:35:05 +0530478 for n in created_subnets:
479 self.assertIsNotNone(n['id'])
480 self.assertIn(n['id'], subnets_list)
481
Masayuki Igawa6d495d62014-03-19 16:38:57 +0900482 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800483 @test.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
raiesmh082d5c6512013-09-06 15:35:05 +0530484 def test_bulk_create_delete_port(self):
Assaf Mullere4f78992014-06-19 17:32:14 +0300485 networks = [self.create_network(), self.create_network()]
raiesmh082d5c6512013-09-06 15:35:05 +0530486 # Creates 2 ports in one request
Mark Maglana5885eb32014-02-28 10:57:34 -0800487 names = [data_utils.rand_name('port-') for i in range(len(networks))]
raiesmh082d5c6512013-09-06 15:35:05 +0530488 port_list = []
489 state = [True, False]
490 for i in range(len(names)):
491 p1 = {
Assaf Mullere4f78992014-06-19 17:32:14 +0300492 'network_id': networks[i]['id'],
raiesmh082d5c6512013-09-06 15:35:05 +0530493 'name': names[i],
494 'admin_state_up': state[i],
495 }
496 port_list.append(p1)
497 del port_list[1]['name']
Ken'ichi Ohmichi1f52fd92016-03-03 12:24:12 -0800498 body = self.ports_client.create_bulk_ports(ports=port_list)
raiesmh082d5c6512013-09-06 15:35:05 +0530499 created_ports = body['ports']
500 self.addCleanup(self._delete_ports, created_ports)
raiesmh082d5c6512013-09-06 15:35:05 +0530501 # Asserting that the ports are found in the list after creation
John Warren49c0fe52015-10-22 12:35:54 -0400502 body = self.ports_client.list_ports()
Mark Maglana5885eb32014-02-28 10:57:34 -0800503 ports_list = [port['id'] for port in body['ports']]
raiesmh082d5c6512013-09-06 15:35:05 +0530504 for n in created_ports:
505 self.assertIsNotNone(n['id'])
506 self.assertIn(n['id'], ports_list)
507
raiesmh0867698322013-08-20 13:09:01 +0530508
Tong Liu7012c862016-04-11 22:32:05 +0000509class BulkNetworkOpsIpV6Test(BulkNetworkOpsTest):
Rohan Kanade0efb0232015-02-19 13:33:31 +0530510 _ip_version = 6
511
512
Tong Liu7012c862016-04-11 22:32:05 +0000513class NetworksIpV6Test(NetworksTest):
Henry Gessauffda37a2014-01-16 11:17:55 -0500514 _ip_version = 6
Henry Gessauffda37a2014-01-16 11:17:55 -0500515
Chris Hoge7579c1a2015-02-26 14:12:15 -0800516 @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
Edgar Magana6a9ac342014-01-16 13:52:49 -0800517 def test_create_delete_subnet_with_gw(self):
Sean Dagueed6e5862016-04-04 10:49:13 -0400518 net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
sridhargaddamea73d532014-05-13 14:48:30 +0530519 gateway = str(netaddr.IPAddress(net.first + 2))
zhufld2c40ca2016-10-18 17:03:07 +0800520 network = self.create_network()
Edgar Magana6a9ac342014-01-16 13:52:49 -0800521 subnet = self.create_subnet(network, gateway)
522 # Verifies Subnet GW in IPv6
523 self.assertEqual(subnet['gateway_ip'], gateway)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800524
Chris Hoge7579c1a2015-02-26 14:12:15 -0800525 @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400526 def test_create_delete_subnet_with_default_gw(self):
Sean Dagueed6e5862016-04-04 10:49:13 -0400527 net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
sridhargaddamea73d532014-05-13 14:48:30 +0530528 gateway_ip = str(netaddr.IPAddress(net.first + 1))
zhufld2c40ca2016-10-18 17:03:07 +0800529 network = self.create_network()
Edgar Magana6a9ac342014-01-16 13:52:49 -0800530 subnet = self.create_subnet(network)
531 # Verifies Subnet GW in IPv6
sridhargaddamea73d532014-05-13 14:48:30 +0530532 self.assertEqual(subnet['gateway_ip'], gateway_ip)
Edgar Magana6a9ac342014-01-16 13:52:49 -0800533
Chris Hoge7579c1a2015-02-26 14:12:15 -0800534 @test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400535 def test_create_list_subnet_with_no_gw64_one_network(self):
zhufld2c40ca2016-10-18 17:03:07 +0800536 network = self.create_network()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400537 ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
538 subnet1 = self.create_subnet(network,
539 ip_version=6,
540 gateway=ipv6_gateway)
541 self.assertEqual(netaddr.IPNetwork(subnet1['cidr']).version, 6,
542 'The created subnet is not IPv6')
543 subnet2 = self.create_subnet(network,
544 gateway=None,
545 ip_version=4)
546 self.assertEqual(netaddr.IPNetwork(subnet2['cidr']).version, 4,
547 'The created subnet is not IPv4')
548 # Verifies Subnet GW is set in IPv6
549 self.assertEqual(subnet1['gateway_ip'], ipv6_gateway)
550 # Verifies Subnet GW is None in IPv4
guo yunxian0306a4a2016-07-29 16:32:28 +0800551 self.assertIsNone(subnet2['gateway_ip'])
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400552 # Verifies all 2 subnets in the same network
John Warren3961acd2015-10-02 14:38:53 -0400553 body = self.subnets_client.list_subnets()
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400554 subnets = [sub['id'] for sub in body['subnets']
555 if sub['network_id'] == network['id']]
556 test_subnet_ids = [sub['id'] for sub in (subnet1, subnet2)]
ghanshyam2dee5e32016-06-24 14:42:56 +0900557 six.assertCountEqual(self, subnets,
558 test_subnet_ids,
559 'Subnet are not in the same network')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400560
Sergey She757c332014-11-25 01:16:32 +0300561
Tong Liu7012c862016-04-11 22:32:05 +0000562class NetworksIpV6TestAttrs(NetworksIpV6Test):
Sergey She757c332014-11-25 01:16:32 +0300563
564 @classmethod
Rohan Kanadea565e452015-01-27 14:00:13 +0530565 def skip_checks(cls):
566 super(NetworksIpV6TestAttrs, cls).skip_checks()
Sergey She757c332014-11-25 01:16:32 +0300567 if not CONF.network_feature_enabled.ipv6_subnet_attributes:
568 raise cls.skipException("IPv6 extended attributes for "
569 "subnets not available")
Sergey She757c332014-11-25 01:16:32 +0300570
Chris Hoge7579c1a2015-02-26 14:12:15 -0800571 @test.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400572 def test_create_delete_subnet_with_v6_attributes_stateful(self):
Rohan Kanade35589aa2014-08-19 14:56:12 +0200573 self._create_verify_delete_subnet(
574 gateway=self._subnet_data[self._ip_version]['gateway'],
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400575 ipv6_ra_mode='dhcpv6-stateful',
576 ipv6_address_mode='dhcpv6-stateful')
577
Chris Hoge7579c1a2015-02-26 14:12:15 -0800578 @test.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400579 def test_create_delete_subnet_with_v6_attributes_slaac(self):
580 self._create_verify_delete_subnet(
Rohan Kanade35589aa2014-08-19 14:56:12 +0200581 ipv6_ra_mode='slaac',
582 ipv6_address_mode='slaac')
Sean M. Collinsdd27a4d2014-05-13 10:33:15 -0400583
Chris Hoge7579c1a2015-02-26 14:12:15 -0800584 @test.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
Sergey Shnaidman18cf5972014-09-02 22:05:00 +0400585 def test_create_delete_subnet_with_v6_attributes_stateless(self):
586 self._create_verify_delete_subnet(
587 ipv6_ra_mode='dhcpv6-stateless',
588 ipv6_address_mode='dhcpv6-stateless')
Sergey She757c332014-11-25 01:16:32 +0300589
590 def _test_delete_subnet_with_ports(self, mode):
591 """Create subnet and delete it with existing ports"""
592 slaac_network = self.create_network()
593 subnet_slaac = self.create_subnet(slaac_network,
594 **{'ipv6_ra_mode': mode,
595 'ipv6_address_mode': mode})
596 port = self.create_port(slaac_network)
597 self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
John Warren3961acd2015-10-02 14:38:53 -0400598 self.subnets_client.delete_subnet(subnet_slaac['id'])
Sergey She757c332014-11-25 01:16:32 +0300599 self.subnets.pop()
John Warren3961acd2015-10-02 14:38:53 -0400600 subnets = self.subnets_client.list_subnets()
Sergey She757c332014-11-25 01:16:32 +0300601 subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
602 self.assertNotIn(subnet_slaac['id'], subnet_ids,
603 "Subnet wasn't deleted")
reedip6fb7e1a2016-03-10 13:32:01 +0900604 self.assertRaisesRegex(
Masayuki Igawad9388762015-01-20 14:56:42 +0900605 lib_exc.Conflict,
Sergey She757c332014-11-25 01:16:32 +0300606 "There are one or more ports still in use on the network",
John Warren94d8faf2015-09-15 12:22:24 -0400607 self.networks_client.delete_network,
Sergey She757c332014-11-25 01:16:32 +0300608 slaac_network['id'])
609
Chris Hoge7579c1a2015-02-26 14:12:15 -0800610 @test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
Sergey She757c332014-11-25 01:16:32 +0300611 def test_create_delete_slaac_subnet_with_ports(self):
612 """Test deleting subnet with SLAAC ports
613
614 Create subnet with SLAAC, create ports in network
615 and then you shall be able to delete subnet without port
616 deletion. But you still can not delete the network.
617 """
618 self._test_delete_subnet_with_ports("slaac")
619
Chris Hoge7579c1a2015-02-26 14:12:15 -0800620 @test.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
Sergey She757c332014-11-25 01:16:32 +0300621 def test_create_delete_stateless_subnet_with_ports(self):
622 """Test deleting subnet with DHCPv6 stateless ports
623
624 Create subnet with DHCPv6 stateless, create ports in network
625 and then you shall be able to delete subnet without port
626 deletion. But you still can not delete the network.
627 """
628 self._test_delete_subnet_with_ports("dhcpv6-stateless")