Jay Pipes | f4dad39 | 2012-06-05 16:03:58 -0400 | [diff] [blame] | 1 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 |
| 2 | |
ZhiQiang Fan | 39f9722 | 2013-09-20 04:49:44 +0800 | [diff] [blame] | 3 | # Copyright 2012 OpenStack Foundation |
Jay Pipes | f4dad39 | 2012-06-05 16:03:58 -0400 | [diff] [blame] | 4 | # All Rights Reserved. |
| 5 | # |
| 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 7 | # not use this file except in compliance with the License. You may obtain |
| 8 | # a copy of the License at |
| 9 | # |
| 10 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | # |
| 12 | # Unless required by applicable law or agreed to in writing, software |
| 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 15 | # License for the specific language governing permissions and limitations |
| 16 | # under the License. |
| 17 | |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 18 | import netaddr |
Jay Pipes | f4dad39 | 2012-06-05 16:03:58 -0400 | [diff] [blame] | 19 | |
Sean Dague | 1937d09 | 2013-05-17 16:36:38 -0400 | [diff] [blame] | 20 | from tempest.api.network import base |
Masayuki Igawa | 259c113 | 2013-10-31 17:48:44 +0900 | [diff] [blame] | 21 | from tempest.common.utils import data_utils |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 22 | from tempest import exceptions |
| 23 | from tempest.test import attr |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 24 | |
| 25 | |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 26 | class NetworksTestJSON(base.BaseNetworkTest): |
| 27 | _interface = 'json' |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 28 | |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 29 | """ |
Mark McClain | f2982e8 | 2013-07-06 17:48:03 -0400 | [diff] [blame] | 30 | Tests the following operations in the Neutron API using the REST client for |
| 31 | Neutron: |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 32 | |
| 33 | create a network for a tenant |
| 34 | list tenant's networks |
| 35 | show a tenant network details |
| 36 | create a subnet for a tenant |
| 37 | list tenant's subnets |
| 38 | show a tenant subnet details |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 39 | port create |
| 40 | port delete |
| 41 | port list |
| 42 | port show |
| 43 | port update |
| 44 | network update |
| 45 | subnet update |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 46 | |
Mark McClain | f2982e8 | 2013-07-06 17:48:03 -0400 | [diff] [blame] | 47 | v2.0 of the Neutron API is assumed. It is also assumed that the following |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 48 | options are defined in the [network] section of etc/tempest.conf: |
| 49 | |
| 50 | tenant_network_cidr with a block of cidr's from which smaller blocks |
| 51 | can be allocated for tenant networks |
| 52 | |
| 53 | tenant_network_mask_bits with the mask bits to be used to partition the |
| 54 | block defined by tenant-network_cidr |
| 55 | """ |
| 56 | |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 57 | @classmethod |
| 58 | def setUpClass(cls): |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 59 | super(NetworksTestJSON, cls).setUpClass() |
Jay Pipes | f4dad39 | 2012-06-05 16:03:58 -0400 | [diff] [blame] | 60 | cls.network = cls.create_network() |
| 61 | cls.name = cls.network['name'] |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 62 | cls.subnet = cls.create_subnet(cls.network) |
| 63 | cls.cidr = cls.subnet['cidr'] |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 64 | cls.port = cls.create_port(cls.network) |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 65 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 66 | @attr(type='smoke') |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 67 | def test_create_update_delete_network_subnet(self): |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 68 | # Creates a network |
Masayuki Igawa | 259c113 | 2013-10-31 17:48:44 +0900 | [diff] [blame] | 69 | name = data_utils.rand_name('network-') |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 70 | resp, body = self.client.create_network(name) |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 71 | self.assertEqual('201', resp['status']) |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 72 | network = body['network'] |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 73 | net_id = network['id'] |
| 74 | # Verification of network update |
| 75 | new_name = "New_network" |
| 76 | resp, body = self.client.update_network(net_id, new_name) |
| 77 | self.assertEqual('200', resp['status']) |
| 78 | updated_net = body['network'] |
| 79 | self.assertEqual(updated_net['name'], new_name) |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 80 | # Find a cidr that is not in use yet and create a subnet with it |
| 81 | cidr = netaddr.IPNetwork(self.network_cfg.tenant_network_cidr) |
| 82 | mask_bits = self.network_cfg.tenant_network_mask_bits |
| 83 | for subnet_cidr in cidr.subnet(mask_bits): |
| 84 | try: |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 85 | resp, body = self.client.create_subnet(net_id, |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 86 | str(subnet_cidr)) |
| 87 | break |
| 88 | except exceptions.BadRequest as e: |
| 89 | is_overlapping_cidr = 'overlaps with another subnet' in str(e) |
| 90 | if not is_overlapping_cidr: |
| 91 | raise |
| 92 | self.assertEqual('201', resp['status']) |
| 93 | subnet = body['subnet'] |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 94 | subnet_id = subnet['id'] |
| 95 | # Verification of subnet update |
| 96 | new_subnet = "New_subnet" |
| 97 | resp, body = self.client.update_subnet(subnet_id, new_subnet) |
| 98 | self.assertEqual('200', resp['status']) |
| 99 | updated_subnet = body['subnet'] |
| 100 | self.assertEqual(updated_subnet['name'], new_subnet) |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 101 | # Delete subnet and network |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 102 | resp, body = self.client.delete_subnet(subnet_id) |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 103 | self.assertEqual('204', resp['status']) |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 104 | resp, body = self.client.delete_network(net_id) |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 105 | self.assertEqual('204', resp['status']) |
| 106 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 107 | @attr(type='smoke') |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 108 | def test_show_network(self): |
Sean Dague | 46c4a2b | 2013-01-03 17:54:17 -0500 | [diff] [blame] | 109 | # Verifies the details of a network |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 110 | resp, body = self.client.show_network(self.network['id']) |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 111 | self.assertEqual('200', resp['status']) |
| 112 | network = body['network'] |
| 113 | self.assertEqual(self.network['id'], network['id']) |
| 114 | self.assertEqual(self.name, network['name']) |
| 115 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 116 | @attr(type='smoke') |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 117 | def test_list_networks(self): |
Sean Dague | 46c4a2b | 2013-01-03 17:54:17 -0500 | [diff] [blame] | 118 | # Verify the network exists in the list of all networks |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 119 | resp, body = self.client.list_networks() |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 120 | self.assertEqual('200', resp['status']) |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 121 | networks = body['networks'] |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 122 | found = None |
| 123 | for n in networks: |
| 124 | if (n['id'] == self.network['id']): |
| 125 | found = n['id'] |
| 126 | msg = "Network list doesn't contain created network" |
| 127 | self.assertIsNotNone(found, msg) |
Unmesh Gurjar | 4498683 | 2012-05-08 19:57:10 +0530 | [diff] [blame] | 128 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 129 | @attr(type='smoke') |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 130 | def test_show_subnet(self): |
| 131 | # Verifies the details of a subnet |
| 132 | resp, body = self.client.show_subnet(self.subnet['id']) |
| 133 | self.assertEqual('200', resp['status']) |
| 134 | subnet = body['subnet'] |
| 135 | self.assertEqual(self.subnet['id'], subnet['id']) |
| 136 | self.assertEqual(self.cidr, subnet['cidr']) |
| 137 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 138 | @attr(type='smoke') |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 139 | def test_list_subnets(self): |
| 140 | # Verify the subnet exists in the list of all subnets |
| 141 | resp, body = self.client.list_subnets() |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 142 | self.assertEqual('200', resp['status']) |
Miguel Lavalle | cc93961 | 2013-02-22 17:27:20 -0600 | [diff] [blame] | 143 | subnets = body['subnets'] |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 144 | found = None |
| 145 | for n in subnets: |
| 146 | if (n['id'] == self.subnet['id']): |
| 147 | found = n['id'] |
| 148 | msg = "Subnet list doesn't contain created subnet" |
| 149 | self.assertIsNotNone(found, msg) |
| 150 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 151 | @attr(type='smoke') |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 152 | def test_create_update_delete_port(self): |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 153 | # Verify that successful port creation, update & deletion |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 154 | resp, body = self.client.create_port(self.network['id']) |
| 155 | self.assertEqual('201', resp['status']) |
| 156 | port = body['port'] |
| 157 | # Verification of port update |
| 158 | new_port = "New_Port" |
| 159 | resp, body = self.client.update_port(port['id'], new_port) |
| 160 | self.assertEqual('200', resp['status']) |
| 161 | updated_port = body['port'] |
| 162 | self.assertEqual(updated_port['name'], new_port) |
| 163 | # Verification of port delete |
| 164 | resp, body = self.client.delete_port(port['id']) |
| 165 | self.assertEqual('204', resp['status']) |
| 166 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 167 | @attr(type='smoke') |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 168 | def test_show_port(self): |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 169 | # Verify the details of port |
| 170 | resp, body = self.client.show_port(self.port['id']) |
| 171 | self.assertEqual('200', resp['status']) |
| 172 | port = body['port'] |
| 173 | self.assertEqual(self.port['id'], port['id']) |
| 174 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 175 | @attr(type='smoke') |
raiesmh08 | e1aad98 | 2013-08-05 14:19:36 +0530 | [diff] [blame] | 176 | def test_list_ports(self): |
| 177 | # Verify the port exists in the list of all ports |
| 178 | resp, body = self.client.list_ports() |
| 179 | self.assertEqual('200', resp['status']) |
| 180 | ports_list = body['ports'] |
| 181 | found = None |
| 182 | for n in ports_list: |
| 183 | if (n['id'] == self.port['id']): |
| 184 | found = n['id'] |
| 185 | self.assertIsNotNone(found, "Port list doesn't contain created port") |
Anju Tiwari | 6656f58 | 2013-08-03 05:43:42 +0530 | [diff] [blame] | 186 | |
raiesmh08 | 6b055e2 | 2013-09-16 12:59:57 +0530 | [diff] [blame] | 187 | |
| 188 | class NetworksTestXML(NetworksTestJSON): |
| 189 | _interface = 'xml' |
| 190 | |
| 191 | |
| 192 | class BulkNetworkOpsJSON(base.BaseNetworkTest): |
| 193 | _interface = 'json' |
| 194 | |
| 195 | """ |
| 196 | Tests the following operations in the Neutron API using the REST client for |
| 197 | Neutron: |
| 198 | |
| 199 | bulk network creation |
| 200 | bulk subnet creation |
| 201 | bulk subnet creation |
| 202 | list tenant's networks |
| 203 | |
| 204 | v2.0 of the Neutron API is assumed. It is also assumed that the following |
| 205 | options are defined in the [network] section of etc/tempest.conf: |
| 206 | |
| 207 | tenant_network_cidr with a block of cidr's from which smaller blocks |
| 208 | can be allocated for tenant networks |
| 209 | |
| 210 | tenant_network_mask_bits with the mask bits to be used to partition the |
| 211 | block defined by tenant-network_cidr |
| 212 | """ |
| 213 | |
| 214 | @classmethod |
| 215 | def setUpClass(cls): |
| 216 | super(BulkNetworkOpsJSON, cls).setUpClass() |
| 217 | cls.network1 = cls.create_network() |
| 218 | cls.network2 = cls.create_network() |
| 219 | |
| 220 | def _delete_networks(self, created_networks): |
| 221 | for n in created_networks: |
| 222 | resp, body = self.client.delete_network(n['id']) |
| 223 | self.assertEqual(204, resp.status) |
| 224 | # Asserting that the networks are not found in the list after deletion |
| 225 | resp, body = self.client.list_networks() |
| 226 | networks_list = list() |
| 227 | for network in body['networks']: |
| 228 | networks_list.append(network['id']) |
| 229 | for n in created_networks: |
| 230 | self.assertNotIn(n['id'], networks_list) |
| 231 | |
| 232 | def _delete_subnets(self, created_subnets): |
| 233 | for n in created_subnets: |
| 234 | resp, body = self.client.delete_subnet(n['id']) |
| 235 | self.assertEqual(204, resp.status) |
| 236 | # Asserting that the subnets are not found in the list after deletion |
| 237 | resp, body = self.client.list_subnets() |
| 238 | subnets_list = list() |
| 239 | for subnet in body['subnets']: |
| 240 | subnets_list.append(subnet['id']) |
| 241 | for n in created_subnets: |
| 242 | self.assertNotIn(n['id'], subnets_list) |
| 243 | |
| 244 | def _delete_ports(self, created_ports): |
| 245 | for n in created_ports: |
| 246 | resp, body = self.client.delete_port(n['id']) |
| 247 | self.assertEqual(204, resp.status) |
| 248 | # Asserting that the ports are not found in the list after deletion |
| 249 | resp, body = self.client.list_ports() |
| 250 | ports_list = list() |
| 251 | for port in body['ports']: |
| 252 | ports_list.append(port['id']) |
| 253 | for n in created_ports: |
| 254 | self.assertNotIn(n['id'], ports_list) |
| 255 | |
Attila Fazekas | 71834a2 | 2013-08-18 06:56:21 +0200 | [diff] [blame] | 256 | @attr(type='smoke') |
Nayna Patel | b03eab4 | 2013-08-08 08:58:48 +0000 | [diff] [blame] | 257 | def test_bulk_create_delete_network(self): |
| 258 | # Creates 2 networks in one request |
Masayuki Igawa | 259c113 | 2013-10-31 17:48:44 +0900 | [diff] [blame] | 259 | network_names = [data_utils.rand_name('network-'), |
| 260 | data_utils.rand_name('network-')] |
Nayna Patel | b03eab4 | 2013-08-08 08:58:48 +0000 | [diff] [blame] | 261 | resp, body = self.client.create_bulk_network(2, network_names) |
| 262 | created_networks = body['networks'] |
| 263 | self.assertEqual('201', resp['status']) |
| 264 | self.addCleanup(self._delete_networks, created_networks) |
| 265 | # Asserting that the networks are found in the list after creation |
| 266 | resp, body = self.client.list_networks() |
| 267 | networks_list = list() |
| 268 | for network in body['networks']: |
| 269 | networks_list.append(network['id']) |
| 270 | for n in created_networks: |
| 271 | self.assertIsNotNone(n['id']) |
| 272 | self.assertIn(n['id'], networks_list) |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 273 | |
raiesmh08 | 2d5c651 | 2013-09-06 15:35:05 +0530 | [diff] [blame] | 274 | @attr(type='smoke') |
| 275 | def test_bulk_create_delete_subnet(self): |
| 276 | # Creates 2 subnets in one request |
| 277 | cidr = netaddr.IPNetwork(self.network_cfg.tenant_network_cidr) |
| 278 | mask_bits = self.network_cfg.tenant_network_mask_bits |
| 279 | cidrs = [] |
| 280 | for subnet_cidr in cidr.subnet(mask_bits): |
| 281 | cidrs.append(subnet_cidr) |
| 282 | names = [] |
| 283 | networks = [self.network1['id'], self.network2['id']] |
| 284 | for i in range(len(networks)): |
Masayuki Igawa | 259c113 | 2013-10-31 17:48:44 +0900 | [diff] [blame] | 285 | names.append(data_utils.rand_name('subnet-')) |
raiesmh08 | 2d5c651 | 2013-09-06 15:35:05 +0530 | [diff] [blame] | 286 | subnet_list = [] |
| 287 | # TODO(raies): "for IPv6, version list [4, 6] will be used. |
| 288 | # and cidr for IPv6 will be of IPv6" |
| 289 | ip_version = [4, 4] |
| 290 | for i in range(len(names)): |
| 291 | p1 = { |
| 292 | 'network_id': networks[i], |
| 293 | 'cidr': str(cidrs[(i)]), |
| 294 | 'name': names[i], |
| 295 | 'ip_version': ip_version[i] |
| 296 | } |
| 297 | subnet_list.append(p1) |
| 298 | del subnet_list[1]['name'] |
| 299 | resp, body = self.client.create_bulk_subnet(subnet_list) |
| 300 | created_subnets = body['subnets'] |
| 301 | self.addCleanup(self._delete_subnets, created_subnets) |
| 302 | self.assertEqual('201', resp['status']) |
| 303 | # Asserting that the subnets are found in the list after creation |
| 304 | resp, body = self.client.list_subnets() |
| 305 | subnets_list = list() |
| 306 | for subnet in body['subnets']: |
| 307 | subnets_list.append(subnet['id']) |
| 308 | for n in created_subnets: |
| 309 | self.assertIsNotNone(n['id']) |
| 310 | self.assertIn(n['id'], subnets_list) |
| 311 | |
| 312 | @attr(type='smoke') |
| 313 | def test_bulk_create_delete_port(self): |
| 314 | # Creates 2 ports in one request |
| 315 | names = [] |
| 316 | networks = [self.network1['id'], self.network2['id']] |
| 317 | for i in range(len(networks)): |
Masayuki Igawa | 259c113 | 2013-10-31 17:48:44 +0900 | [diff] [blame] | 318 | names.append(data_utils.rand_name('port-')) |
raiesmh08 | 2d5c651 | 2013-09-06 15:35:05 +0530 | [diff] [blame] | 319 | port_list = [] |
| 320 | state = [True, False] |
| 321 | for i in range(len(names)): |
| 322 | p1 = { |
| 323 | 'network_id': networks[i], |
| 324 | 'name': names[i], |
| 325 | 'admin_state_up': state[i], |
| 326 | } |
| 327 | port_list.append(p1) |
| 328 | del port_list[1]['name'] |
| 329 | resp, body = self.client.create_bulk_port(port_list) |
| 330 | created_ports = body['ports'] |
| 331 | self.addCleanup(self._delete_ports, created_ports) |
| 332 | self.assertEqual('201', resp['status']) |
| 333 | # Asserting that the ports are found in the list after creation |
| 334 | resp, body = self.client.list_ports() |
| 335 | ports_list = list() |
| 336 | for port in body['ports']: |
| 337 | ports_list.append(port['id']) |
| 338 | for n in created_ports: |
| 339 | self.assertIsNotNone(n['id']) |
| 340 | self.assertIn(n['id'], ports_list) |
| 341 | |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 342 | |
raiesmh08 | 6b055e2 | 2013-09-16 12:59:57 +0530 | [diff] [blame] | 343 | class BulkNetworkOpsXML(BulkNetworkOpsJSON): |
raiesmh08 | 6769832 | 2013-08-20 13:09:01 +0530 | [diff] [blame] | 344 | _interface = 'xml' |