Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 1 | # Copyright 2013 IBM Corp. |
| 2 | # 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. |
| 15 | |
Rohan Kanade | 9ce97df | 2013-12-10 18:59:35 +0530 | [diff] [blame] | 16 | import time |
| 17 | |
| 18 | from tempest_lib import exceptions as lib_exc |
| 19 | |
Sean Dague | 1937d09 | 2013-05-17 16:36:38 -0400 | [diff] [blame] | 20 | from tempest.api.compute import base |
Matthew Treinish | b0a78fc | 2014-01-29 16:49:12 +0000 | [diff] [blame] | 21 | from tempest import config |
Oleg Bondarev | ee50bb1 | 2014-01-16 00:01:34 +0400 | [diff] [blame] | 22 | from tempest import exceptions |
Yuiko Takada | e9999d6 | 2014-03-06 09:22:54 +0000 | [diff] [blame] | 23 | from tempest import test |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 24 | |
Matthew Treinish | b0a78fc | 2014-01-29 16:49:12 +0000 | [diff] [blame] | 25 | CONF = config.CONF |
| 26 | |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 27 | |
ivan-zhu | f2b0050 | 2013-10-18 10:06:52 +0800 | [diff] [blame] | 28 | class AttachInterfacesTestJSON(base.BaseV2ComputeTest): |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 29 | |
| 30 | @classmethod |
Emily Hugenbruch | e7991d9 | 2014-12-12 16:53:36 +0000 | [diff] [blame] | 31 | def skip_checks(cls): |
| 32 | super(AttachInterfacesTestJSON, cls).skip_checks() |
Matthew Treinish | b0a78fc | 2014-01-29 16:49:12 +0000 | [diff] [blame] | 33 | if not CONF.service_available.neutron: |
Mark McClain | f2982e8 | 2013-07-06 17:48:03 -0400 | [diff] [blame] | 34 | raise cls.skipException("Neutron is required") |
Adam Gandelman | 7186f7a | 2014-07-23 09:28:56 -0400 | [diff] [blame] | 35 | if not CONF.compute_feature_enabled.interface_attach: |
| 36 | raise cls.skipException("Interface attachment is not available.") |
Emily Hugenbruch | e7991d9 | 2014-12-12 16:53:36 +0000 | [diff] [blame] | 37 | |
| 38 | @classmethod |
| 39 | def setup_credentials(cls): |
Salvatore Orlando | 5a33724 | 2014-01-15 22:49:22 +0000 | [diff] [blame] | 40 | # This test class requires network and subnet |
| 41 | cls.set_network_resources(network=True, subnet=True) |
Emily Hugenbruch | e7991d9 | 2014-12-12 16:53:36 +0000 | [diff] [blame] | 42 | super(AttachInterfacesTestJSON, cls).setup_credentials() |
| 43 | |
| 44 | @classmethod |
| 45 | def setup_clients(cls): |
| 46 | super(AttachInterfacesTestJSON, cls).setup_clients() |
David Kranz | b9017e7 | 2013-05-07 11:16:29 -0400 | [diff] [blame] | 47 | cls.client = cls.os.interfaces_client |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 48 | |
Ken'ichi Ohmichi | 84e9968 | 2015-07-08 05:28:57 +0000 | [diff] [blame] | 49 | def wait_for_interface_status(self, server, port_id, status): |
| 50 | """Waits for a interface to reach a given status.""" |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 51 | body = (self.client.show_interface(server, port_id) |
| 52 | ['interfaceAttachment']) |
Ken'ichi Ohmichi | 84e9968 | 2015-07-08 05:28:57 +0000 | [diff] [blame] | 53 | interface_status = body['port_state'] |
| 54 | start = int(time.time()) |
| 55 | |
| 56 | while(interface_status != status): |
| 57 | time.sleep(self.build_interval) |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 58 | body = (self.client.show_interface(server, port_id) |
| 59 | ['interfaceAttachment']) |
Ken'ichi Ohmichi | 84e9968 | 2015-07-08 05:28:57 +0000 | [diff] [blame] | 60 | interface_status = body['port_state'] |
| 61 | |
| 62 | timed_out = int(time.time()) - start >= self.build_timeout |
| 63 | |
| 64 | if interface_status != status and timed_out: |
| 65 | message = ('Interface %s failed to reach %s status ' |
| 66 | '(current %s) within the required time (%s s).' % |
| 67 | (port_id, status, interface_status, |
| 68 | self.build_timeout)) |
| 69 | raise exceptions.TimeoutException(message) |
| 70 | |
| 71 | return body |
| 72 | |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 73 | def _check_interface(self, iface, port_id=None, network_id=None, |
venkata anil | 4537530 | 2014-12-30 10:41:43 +0000 | [diff] [blame] | 74 | fixed_ip=None, mac_addr=None): |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 75 | self.assertIn('port_state', iface) |
| 76 | if port_id: |
| 77 | self.assertEqual(iface['port_id'], port_id) |
| 78 | if network_id: |
| 79 | self.assertEqual(iface['net_id'], network_id) |
| 80 | if fixed_ip: |
| 81 | self.assertEqual(iface['fixed_ips'][0]['ip_address'], fixed_ip) |
venkata anil | 4537530 | 2014-12-30 10:41:43 +0000 | [diff] [blame] | 82 | if mac_addr: |
| 83 | self.assertEqual(iface['mac_addr'], mac_addr) |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 84 | |
| 85 | def _create_server_get_interfaces(self): |
David Kranz | 0fb1429 | 2015-02-11 15:55:20 -0500 | [diff] [blame] | 86 | server = self.create_test_server(wait_until='ACTIVE') |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 87 | ifs = (self.client.list_interfaces(server['id']) |
| 88 | ['interfaceAttachments']) |
Ken'ichi Ohmichi | 84e9968 | 2015-07-08 05:28:57 +0000 | [diff] [blame] | 89 | body = self.wait_for_interface_status( |
Leo Toyoda | ba9e909 | 2013-04-08 09:02:11 +0900 | [diff] [blame] | 90 | server['id'], ifs[0]['port_id'], 'ACTIVE') |
| 91 | ifs[0]['port_state'] = body['port_state'] |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 92 | return server, ifs |
| 93 | |
| 94 | def _test_create_interface(self, server): |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 95 | iface = (self.client.create_interface(server['id']) |
| 96 | ['interfaceAttachment']) |
Ken'ichi Ohmichi | 84e9968 | 2015-07-08 05:28:57 +0000 | [diff] [blame] | 97 | iface = self.wait_for_interface_status( |
Leo Toyoda | ba9e909 | 2013-04-08 09:02:11 +0900 | [diff] [blame] | 98 | server['id'], iface['port_id'], 'ACTIVE') |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 99 | self._check_interface(iface) |
| 100 | return iface |
| 101 | |
| 102 | def _test_create_interface_by_network_id(self, server, ifs): |
| 103 | network_id = ifs[0]['net_id'] |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 104 | iface = self.client.create_interface( |
| 105 | server['id'], net_id=network_id)['interfaceAttachment'] |
Ken'ichi Ohmichi | 84e9968 | 2015-07-08 05:28:57 +0000 | [diff] [blame] | 106 | iface = self.wait_for_interface_status( |
Leo Toyoda | ba9e909 | 2013-04-08 09:02:11 +0900 | [diff] [blame] | 107 | server['id'], iface['port_id'], 'ACTIVE') |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 108 | self._check_interface(iface, network_id=network_id) |
| 109 | return iface |
| 110 | |
| 111 | def _test_show_interface(self, server, ifs): |
| 112 | iface = ifs[0] |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 113 | _iface = self.client.show_interface( |
| 114 | server['id'], iface['port_id'])['interfaceAttachment'] |
venkata anil | 4537530 | 2014-12-30 10:41:43 +0000 | [diff] [blame] | 115 | self._check_interface(iface, port_id=_iface['port_id'], |
| 116 | network_id=_iface['net_id'], |
| 117 | fixed_ip=_iface['fixed_ips'][0]['ip_address'], |
| 118 | mac_addr=_iface['mac_addr']) |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 119 | |
| 120 | def _test_delete_interface(self, server, ifs): |
| 121 | # NOTE(danms): delete not the first or last, but one in the middle |
| 122 | iface = ifs[1] |
David Kranz | b2b0c18 | 2015-02-18 13:28:19 -0500 | [diff] [blame] | 123 | self.client.delete_interface(server['id'], iface['port_id']) |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 124 | _ifs = (self.client.list_interfaces(server['id']) |
| 125 | ['interfaceAttachments']) |
Oleg Bondarev | ee50bb1 | 2014-01-16 00:01:34 +0400 | [diff] [blame] | 126 | start = int(time.time()) |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 127 | |
Oleg Bondarev | ee50bb1 | 2014-01-16 00:01:34 +0400 | [diff] [blame] | 128 | while len(ifs) == len(_ifs): |
| 129 | time.sleep(self.build_interval) |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 130 | _ifs = (self.client.list_interfaces(server['id']) |
| 131 | ['interfaceAttachments']) |
Oleg Bondarev | ee50bb1 | 2014-01-16 00:01:34 +0400 | [diff] [blame] | 132 | timed_out = int(time.time()) - start >= self.build_timeout |
| 133 | if len(ifs) == len(_ifs) and timed_out: |
| 134 | message = ('Failed to delete interface within ' |
| 135 | 'the required time: %s sec.' % self.build_timeout) |
| 136 | raise exceptions.TimeoutException(message) |
| 137 | |
| 138 | self.assertNotIn(iface['port_id'], [i['port_id'] for i in _ifs]) |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 139 | return _ifs |
| 140 | |
| 141 | def _compare_iface_list(self, list1, list2): |
| 142 | # NOTE(danms): port_state will likely have changed, so just |
| 143 | # confirm the port_ids are the same at least |
| 144 | list1 = [x['port_id'] for x in list1] |
| 145 | list2 = [x['port_id'] for x in list2] |
| 146 | |
| 147 | self.assertEqual(sorted(list1), sorted(list2)) |
| 148 | |
Chris Hoge | 7579c1a | 2015-02-26 14:12:15 -0800 | [diff] [blame] | 149 | @test.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051') |
Matthew Treinish | 2df9748 | 2014-06-13 15:02:26 -0400 | [diff] [blame] | 150 | @test.services('network') |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 151 | def test_create_list_show_delete_interfaces(self): |
| 152 | server, ifs = self._create_server_get_interfaces() |
| 153 | interface_count = len(ifs) |
| 154 | self.assertTrue(interface_count > 0) |
| 155 | self._check_interface(ifs[0]) |
| 156 | |
Rohan Kanade | 9ce97df | 2013-12-10 18:59:35 +0530 | [diff] [blame] | 157 | try: |
| 158 | iface = self._test_create_interface(server) |
| 159 | except lib_exc.BadRequest as e: |
| 160 | msg = ('Multiple possible networks found, use a Network ID to be ' |
| 161 | 'more specific.') |
| 162 | if not CONF.compute.fixed_network_name and e.message == msg: |
| 163 | raise |
| 164 | else: |
| 165 | ifs.append(iface) |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 166 | |
| 167 | iface = self._test_create_interface_by_network_id(server, ifs) |
| 168 | ifs.append(iface) |
| 169 | |
ghanshyam | a2364f1 | 2015-08-24 15:45:37 +0900 | [diff] [blame] | 170 | _ifs = (self.client.list_interfaces(server['id']) |
| 171 | ['interfaceAttachments']) |
Dan Smith | 8ad1c47 | 2013-02-26 13:03:16 -0500 | [diff] [blame] | 172 | self._compare_iface_list(ifs, _ifs) |
| 173 | |
| 174 | self._test_show_interface(server, ifs) |
| 175 | |
| 176 | _ifs = self._test_delete_interface(server, ifs) |
| 177 | self.assertEqual(len(ifs) - 1, len(_ifs)) |
| 178 | |
Masayuki Igawa | 750aa92 | 2014-03-20 09:46:37 +0900 | [diff] [blame] | 179 | @test.attr(type='smoke') |
Chris Hoge | 7579c1a | 2015-02-26 14:12:15 -0800 | [diff] [blame] | 180 | @test.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9') |
Matthew Treinish | 2df9748 | 2014-06-13 15:02:26 -0400 | [diff] [blame] | 181 | @test.services('network') |
Ghanshyam Mann | 6e855d1 | 2014-02-26 13:31:56 +0900 | [diff] [blame] | 182 | def test_add_remove_fixed_ip(self): |
| 183 | # Add and Remove the fixed IP to server. |
| 184 | server, ifs = self._create_server_get_interfaces() |
| 185 | interface_count = len(ifs) |
| 186 | self.assertTrue(interface_count > 0) |
| 187 | self._check_interface(ifs[0]) |
| 188 | network_id = ifs[0]['net_id'] |
ghanshyam | 4c7d2a0 | 2015-09-14 16:05:13 +0900 | [diff] [blame] | 189 | self.servers_client.add_fixed_ip(server['id'], networkId=network_id) |
Ghanshyam Mann | 6e855d1 | 2014-02-26 13:31:56 +0900 | [diff] [blame] | 190 | # Remove the fixed IP from server. |
Ken'ichi Ohmichi | 7680024 | 2015-07-03 05:12:31 +0000 | [diff] [blame] | 191 | server_detail = self.os.servers_client.show_server( |
ghanshyam | 0f82525 | 2015-08-25 16:02:50 +0900 | [diff] [blame] | 192 | server['id'])['server'] |
Ghanshyam Mann | 6e855d1 | 2014-02-26 13:31:56 +0900 | [diff] [blame] | 193 | # Get the Fixed IP from server. |
| 194 | fixed_ip = None |
| 195 | for ip_set in server_detail['addresses']: |
| 196 | for ip in server_detail['addresses'][ip_set]: |
| 197 | if ip['OS-EXT-IPS:type'] == 'fixed': |
| 198 | fixed_ip = ip['addr'] |
| 199 | break |
| 200 | if fixed_ip is not None: |
| 201 | break |
ghanshyam | 4c7d2a0 | 2015-09-14 16:05:13 +0900 | [diff] [blame] | 202 | self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip) |