blob: 9bba733b0085b78e2ffaa3d2aa6e84db2fe7d130 [file] [log] [blame]
Dan Smith8ad1c472013-02-26 13:03:16 -05001# 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 Kanade9ce97df2013-12-10 18:59:35 +053016import time
17
Sean Dague1937d092013-05-17 16:36:38 -040018from tempest.api.compute import base
Matt Riedemanna8c641a2016-07-12 17:07:33 -040019from tempest.common import compute
Ryan Tidwell1964a262016-05-04 15:13:23 -070020from tempest.common.utils import net_utils
Matt Riedemanna8c641a2016-07-12 17:07:33 -040021from tempest.common import waiters
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000022from tempest import config
Matt Riedemann3570c1e2016-07-29 12:15:38 -040023from tempest.lib import decorators
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050024from tempest.lib import exceptions as lib_exc
Yuiko Takadae9999d62014-03-06 09:22:54 +000025from tempest import test
Dan Smith8ad1c472013-02-26 13:03:16 -050026
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000027CONF = config.CONF
28
Dan Smith8ad1c472013-02-26 13:03:16 -050029
ivan-zhuf2b00502013-10-18 10:06:52 +080030class AttachInterfacesTestJSON(base.BaseV2ComputeTest):
Dan Smith8ad1c472013-02-26 13:03:16 -050031
32 @classmethod
Emily Hugenbruche7991d92014-12-12 16:53:36 +000033 def skip_checks(cls):
34 super(AttachInterfacesTestJSON, cls).skip_checks()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000035 if not CONF.service_available.neutron:
Mark McClainf2982e82013-07-06 17:48:03 -040036 raise cls.skipException("Neutron is required")
Adam Gandelman7186f7a2014-07-23 09:28:56 -040037 if not CONF.compute_feature_enabled.interface_attach:
38 raise cls.skipException("Interface attachment is not available.")
Emily Hugenbruche7991d92014-12-12 16:53:36 +000039
40 @classmethod
41 def setup_credentials(cls):
Salvatore Orlando5a337242014-01-15 22:49:22 +000042 # This test class requires network and subnet
43 cls.set_network_resources(network=True, subnet=True)
Emily Hugenbruche7991d92014-12-12 16:53:36 +000044 super(AttachInterfacesTestJSON, cls).setup_credentials()
45
46 @classmethod
47 def setup_clients(cls):
48 super(AttachInterfacesTestJSON, cls).setup_clients()
Maho Koshiya7b629582016-02-22 10:59:01 +090049 cls.subnets_client = cls.os.subnets_client
Maho Koshiya3fc12462015-12-14 19:03:12 +090050 cls.ports_client = cls.os.ports_client
Dan Smith8ad1c472013-02-26 13:03:16 -050051
Matt Riedemanna8c641a2016-07-12 17:07:33 -040052 # TODO(mriedem): move this into a common waiters utility module
53 def wait_for_port_detach(self, port_id):
54 """Waits for the port's device_id to be unset.
55
56 :param port_id: The id of the port being detached.
57 :returns: The final port dict from the show_port response.
58 """
59 port = self.ports_client.show_port(port_id)['port']
60 device_id = port['device_id']
61 start = int(time.time())
62
63 # NOTE(mriedem): Nova updates the port's device_id to '' rather than
64 # None, but it's not contractual so handle Falsey either way.
65 while device_id:
66 time.sleep(self.build_interval)
67 port = self.ports_client.show_port(port_id)['port']
68 device_id = port['device_id']
69
70 timed_out = int(time.time()) - start >= self.build_timeout
71
72 if device_id and timed_out:
73 message = ('Port %s failed to detach (device_id %s) within '
74 'the required time (%s s).' %
75 (port_id, device_id, self.build_timeout))
guo yunxianebb15f22016-11-01 21:03:35 +080076 raise lib_exc.TimeoutException(message)
Matt Riedemanna8c641a2016-07-12 17:07:33 -040077
78 return port
79
Dan Smith8ad1c472013-02-26 13:03:16 -050080 def _check_interface(self, iface, port_id=None, network_id=None,
venkata anil45375302014-12-30 10:41:43 +000081 fixed_ip=None, mac_addr=None):
Dan Smith8ad1c472013-02-26 13:03:16 -050082 self.assertIn('port_state', iface)
83 if port_id:
84 self.assertEqual(iface['port_id'], port_id)
85 if network_id:
86 self.assertEqual(iface['net_id'], network_id)
87 if fixed_ip:
88 self.assertEqual(iface['fixed_ips'][0]['ip_address'], fixed_ip)
venkata anil45375302014-12-30 10:41:43 +000089 if mac_addr:
90 self.assertEqual(iface['mac_addr'], mac_addr)
Dan Smith8ad1c472013-02-26 13:03:16 -050091
92 def _create_server_get_interfaces(self):
David Kranz0fb14292015-02-11 15:55:20 -050093 server = self.create_test_server(wait_until='ACTIVE')
lkuchlan87b5a2d2016-09-27 15:46:16 +030094 ifs = (self.interfaces_client.list_interfaces(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +090095 ['interfaceAttachments'])
zhufl7b638332016-11-14 10:23:30 +080096 body = waiters.wait_for_interface_status(
97 self.interfaces_client, server['id'], ifs[0]['port_id'], 'ACTIVE')
Leo Toyodaba9e9092013-04-08 09:02:11 +090098 ifs[0]['port_state'] = body['port_state']
Dan Smith8ad1c472013-02-26 13:03:16 -050099 return server, ifs
100
101 def _test_create_interface(self, server):
lkuchlan87b5a2d2016-09-27 15:46:16 +0300102 iface = (self.interfaces_client.create_interface(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900103 ['interfaceAttachment'])
zhufl7b638332016-11-14 10:23:30 +0800104 iface = waiters.wait_for_interface_status(
105 self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
Dan Smith8ad1c472013-02-26 13:03:16 -0500106 self._check_interface(iface)
107 return iface
108
109 def _test_create_interface_by_network_id(self, server, ifs):
110 network_id = ifs[0]['net_id']
lkuchlan87b5a2d2016-09-27 15:46:16 +0300111 iface = self.interfaces_client.create_interface(
ghanshyama2364f12015-08-24 15:45:37 +0900112 server['id'], net_id=network_id)['interfaceAttachment']
zhufl7b638332016-11-14 10:23:30 +0800113 iface = waiters.wait_for_interface_status(
114 self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
Dan Smith8ad1c472013-02-26 13:03:16 -0500115 self._check_interface(iface, network_id=network_id)
116 return iface
117
Maho Koshiya3fc12462015-12-14 19:03:12 +0900118 def _test_create_interface_by_port_id(self, server, ifs):
119 network_id = ifs[0]['net_id']
120 port = self.ports_client.create_port(network_id=network_id)
121 port_id = port['port']['id']
122 self.addCleanup(self.ports_client.delete_port, port_id)
lkuchlan87b5a2d2016-09-27 15:46:16 +0300123 iface = self.interfaces_client.create_interface(
Maho Koshiya3fc12462015-12-14 19:03:12 +0900124 server['id'], port_id=port_id)['interfaceAttachment']
zhufl7b638332016-11-14 10:23:30 +0800125 iface = waiters.wait_for_interface_status(
126 self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
Maho Koshiya3fc12462015-12-14 19:03:12 +0900127 self._check_interface(iface, port_id=port_id)
128 return iface
129
Maho Koshiya7b629582016-02-22 10:59:01 +0900130 def _test_create_interface_by_fixed_ips(self, server, ifs):
131 network_id = ifs[0]['net_id']
Ryan Tidwell1964a262016-05-04 15:13:23 -0700132 subnet_id = ifs[0]['fixed_ips'][0]['subnet_id']
133 ip_list = net_utils.get_unused_ip_addresses(self.ports_client,
134 self.subnets_client,
135 network_id,
136 subnet_id,
137 1)
Maho Koshiya7b629582016-02-22 10:59:01 +0900138
Ryan Tidwell1964a262016-05-04 15:13:23 -0700139 fixed_ips = [{'ip_address': ip_list[0]}]
lkuchlan87b5a2d2016-09-27 15:46:16 +0300140 iface = self.interfaces_client.create_interface(
Maho Koshiya7b629582016-02-22 10:59:01 +0900141 server['id'], net_id=network_id,
142 fixed_ips=fixed_ips)['interfaceAttachment']
143 self.addCleanup(self.ports_client.delete_port, iface['port_id'])
zhufl7b638332016-11-14 10:23:30 +0800144 iface = waiters.wait_for_interface_status(
145 self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
Ryan Tidwell1964a262016-05-04 15:13:23 -0700146 self._check_interface(iface, fixed_ip=ip_list[0])
Maho Koshiya7b629582016-02-22 10:59:01 +0900147 return iface
148
Dan Smith8ad1c472013-02-26 13:03:16 -0500149 def _test_show_interface(self, server, ifs):
150 iface = ifs[0]
lkuchlan87b5a2d2016-09-27 15:46:16 +0300151 _iface = self.interfaces_client.show_interface(
ghanshyama2364f12015-08-24 15:45:37 +0900152 server['id'], iface['port_id'])['interfaceAttachment']
venkata anil45375302014-12-30 10:41:43 +0000153 self._check_interface(iface, port_id=_iface['port_id'],
154 network_id=_iface['net_id'],
155 fixed_ip=_iface['fixed_ips'][0]['ip_address'],
156 mac_addr=_iface['mac_addr'])
Dan Smith8ad1c472013-02-26 13:03:16 -0500157
158 def _test_delete_interface(self, server, ifs):
159 # NOTE(danms): delete not the first or last, but one in the middle
160 iface = ifs[1]
lkuchlan87b5a2d2016-09-27 15:46:16 +0300161 self.interfaces_client.delete_interface(server['id'], iface['port_id'])
162 _ifs = (self.interfaces_client.list_interfaces(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900163 ['interfaceAttachments'])
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400164 start = int(time.time())
Dan Smith8ad1c472013-02-26 13:03:16 -0500165
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400166 while len(ifs) == len(_ifs):
167 time.sleep(self.build_interval)
lkuchlan87b5a2d2016-09-27 15:46:16 +0300168 _ifs = (self.interfaces_client.list_interfaces(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900169 ['interfaceAttachments'])
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400170 timed_out = int(time.time()) - start >= self.build_timeout
171 if len(ifs) == len(_ifs) and timed_out:
172 message = ('Failed to delete interface within '
173 'the required time: %s sec.' % self.build_timeout)
guo yunxianebb15f22016-11-01 21:03:35 +0800174 raise lib_exc.TimeoutException(message)
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400175
176 self.assertNotIn(iface['port_id'], [i['port_id'] for i in _ifs])
Dan Smith8ad1c472013-02-26 13:03:16 -0500177 return _ifs
178
179 def _compare_iface_list(self, list1, list2):
180 # NOTE(danms): port_state will likely have changed, so just
181 # confirm the port_ids are the same at least
182 list1 = [x['port_id'] for x in list1]
183 list2 = [x['port_id'] for x in list2]
184
185 self.assertEqual(sorted(list1), sorted(list2))
186
Ken'ichi Ohmichi14b0ae12017-01-27 17:18:52 -0800187 @decorators.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
Matthew Treinish2df97482014-06-13 15:02:26 -0400188 @test.services('network')
Dan Smith8ad1c472013-02-26 13:03:16 -0500189 def test_create_list_show_delete_interfaces(self):
190 server, ifs = self._create_server_get_interfaces()
191 interface_count = len(ifs)
zhufl080dcfb2016-10-21 17:45:38 +0800192 self.assertGreater(interface_count, 0)
Dan Smith8ad1c472013-02-26 13:03:16 -0500193 self._check_interface(ifs[0])
194
Rohan Kanade9ce97df2013-12-10 18:59:35 +0530195 try:
196 iface = self._test_create_interface(server)
197 except lib_exc.BadRequest as e:
198 msg = ('Multiple possible networks found, use a Network ID to be '
199 'more specific.')
200 if not CONF.compute.fixed_network_name and e.message == msg:
201 raise
202 else:
203 ifs.append(iface)
Dan Smith8ad1c472013-02-26 13:03:16 -0500204
205 iface = self._test_create_interface_by_network_id(server, ifs)
206 ifs.append(iface)
207
Maho Koshiya3fc12462015-12-14 19:03:12 +0900208 iface = self._test_create_interface_by_port_id(server, ifs)
209 ifs.append(iface)
210
Maho Koshiya7b629582016-02-22 10:59:01 +0900211 iface = self._test_create_interface_by_fixed_ips(server, ifs)
212 ifs.append(iface)
213
lkuchlan87b5a2d2016-09-27 15:46:16 +0300214 _ifs = (self.interfaces_client.list_interfaces(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900215 ['interfaceAttachments'])
Dan Smith8ad1c472013-02-26 13:03:16 -0500216 self._compare_iface_list(ifs, _ifs)
217
218 self._test_show_interface(server, ifs)
219
220 _ifs = self._test_delete_interface(server, ifs)
221 self.assertEqual(len(ifs) - 1, len(_ifs))
222
Masayuki Igawa750aa922014-03-20 09:46:37 +0900223 @test.attr(type='smoke')
Ken'ichi Ohmichi14b0ae12017-01-27 17:18:52 -0800224 @decorators.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
Matthew Treinish2df97482014-06-13 15:02:26 -0400225 @test.services('network')
Ghanshyam Mann6e855d12014-02-26 13:31:56 +0900226 def test_add_remove_fixed_ip(self):
227 # Add and Remove the fixed IP to server.
228 server, ifs = self._create_server_get_interfaces()
229 interface_count = len(ifs)
zhufl080dcfb2016-10-21 17:45:38 +0800230 self.assertGreater(interface_count, 0)
Ghanshyam Mann6e855d12014-02-26 13:31:56 +0900231 self._check_interface(ifs[0])
232 network_id = ifs[0]['net_id']
ghanshyam4c7d2a02015-09-14 16:05:13 +0900233 self.servers_client.add_fixed_ip(server['id'], networkId=network_id)
Ghanshyam Mann6e855d12014-02-26 13:31:56 +0900234 # Remove the fixed IP from server.
Ken'ichi Ohmichi76800242015-07-03 05:12:31 +0000235 server_detail = self.os.servers_client.show_server(
ghanshyam0f825252015-08-25 16:02:50 +0900236 server['id'])['server']
Ghanshyam Mann6e855d12014-02-26 13:31:56 +0900237 # Get the Fixed IP from server.
238 fixed_ip = None
239 for ip_set in server_detail['addresses']:
240 for ip in server_detail['addresses'][ip_set]:
241 if ip['OS-EXT-IPS:type'] == 'fixed':
242 fixed_ip = ip['addr']
243 break
244 if fixed_ip is not None:
245 break
ghanshyam4c7d2a02015-09-14 16:05:13 +0900246 self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip)
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400247
Matt Riedemann3570c1e2016-07-29 12:15:38 -0400248 @decorators.skip_because(bug='1607714')
Ken'ichi Ohmichi14b0ae12017-01-27 17:18:52 -0800249 @decorators.idempotent_id('2f3a0127-95c7-4977-92d2-bc5aec602fb4')
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400250 def test_reassign_port_between_servers(self):
251 """Tests the following:
252
253 1. Create a port in Neutron.
254 2. Create two servers in Nova.
255 3. Attach the port to the first server.
256 4. Detach the port from the first server.
257 5. Attach the port to the second server.
258 6. Detach the port from the second server.
259 """
260 network = self.get_tenant_network()
261 network_id = network['id']
262 port = self.ports_client.create_port(network_id=network_id)
263 port_id = port['port']['id']
264 self.addCleanup(self.ports_client.delete_port, port_id)
265
266 # create two servers
267 _, servers = compute.create_test_server(
268 self.os, tenant_network=network, wait_until='ACTIVE', min_count=2)
269 # add our cleanups for the servers since we bypassed the base class
270 for server in servers:
zhufl1355d982017-01-05 12:06:20 +0800271 self.addCleanup(self.delete_server, server['id'])
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400272
273 for server in servers:
274 # attach the port to the server
lkuchlan87b5a2d2016-09-27 15:46:16 +0300275 iface = self.interfaces_client.create_interface(
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400276 server['id'], port_id=port_id)['interfaceAttachment']
277 self._check_interface(iface, port_id=port_id)
278
279 # detach the port from the server; this is a cast in the compute
280 # API so we have to poll the port until the device_id is unset.
lkuchlan87b5a2d2016-09-27 15:46:16 +0300281 self.interfaces_client.delete_interface(server['id'], port_id)
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400282 self.wait_for_port_detach(port_id)