blob: c1af6c73d90dfca4cf772b69454eec6222bf1fa8 [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
Slawek Kaplonskib3daeb42019-06-29 23:49:59 +020018from oslo_log import log
junbolibc2ae862017-07-29 15:46:48 +080019import six
20
Sean Dague1937d092013-05-17 16:36:38 -040021from tempest.api.compute import base
Matt Riedemanna8c641a2016-07-12 17:07:33 -040022from tempest.common import compute
Andrea Frittolicd368412017-08-14 21:37:56 +010023from tempest.common import utils
Ryan Tidwell1964a262016-05-04 15:13:23 -070024from tempest.common.utils import net_utils
Matt Riedemanna8c641a2016-07-12 17:07:33 -040025from tempest.common import waiters
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000026from tempest import config
Doug Schveninger24675aa2019-08-16 22:28:39 -050027from tempest.lib.common.utils import data_utils
Lucas Alvares Gomes692422b2018-10-10 10:33:45 +010028from tempest.lib.common.utils.linux import remote_client
Matt Riedemannd4cb10f2018-09-26 13:03:08 -040029from tempest.lib.common.utils import test_utils
Matt Riedemann3570c1e2016-07-29 12:15:38 -040030from tempest.lib import decorators
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050031from tempest.lib import exceptions as lib_exc
Dan Smith8ad1c472013-02-26 13:03:16 -050032
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000033CONF = config.CONF
34
Slawek Kaplonskib3daeb42019-06-29 23:49:59 +020035LOG = log.getLogger(__name__)
36
Dan Smith8ad1c472013-02-26 13:03:16 -050037
zhufl615e63b2018-08-01 17:23:38 +080038class AttachInterfacesTestBase(base.BaseV2ComputeTest):
Dan Smith8ad1c472013-02-26 13:03:16 -050039
40 @classmethod
Emily Hugenbruche7991d92014-12-12 16:53:36 +000041 def skip_checks(cls):
zhufl615e63b2018-08-01 17:23:38 +080042 super(AttachInterfacesTestBase, cls).skip_checks()
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000043 if not CONF.service_available.neutron:
Mark McClainf2982e82013-07-06 17:48:03 -040044 raise cls.skipException("Neutron is required")
Adam Gandelman7186f7a2014-07-23 09:28:56 -040045 if not CONF.compute_feature_enabled.interface_attach:
46 raise cls.skipException("Interface attachment is not available.")
Artom Lifshitzb4775942018-09-05 16:24:01 +030047 if not CONF.validation.run_validation:
48 raise cls.skipException('Validation should be enabled to ensure '
49 'guest OS is running and capable of '
50 'processing ACPI events.')
Emily Hugenbruche7991d92014-12-12 16:53:36 +000051
52 @classmethod
53 def setup_credentials(cls):
Salvatore Orlando5a337242014-01-15 22:49:22 +000054 # This test class requires network and subnet
Artom Lifshitzb4775942018-09-05 16:24:01 +030055 cls.set_network_resources(network=True, subnet=True, router=True,
56 dhcp=True)
zhufl615e63b2018-08-01 17:23:38 +080057 super(AttachInterfacesTestBase, cls).setup_credentials()
Emily Hugenbruche7991d92014-12-12 16:53:36 +000058
59 @classmethod
60 def setup_clients(cls):
zhufl615e63b2018-08-01 17:23:38 +080061 super(AttachInterfacesTestBase, cls).setup_clients()
Jordan Pittier8160d312017-04-18 11:52:23 +020062 cls.subnets_client = cls.os_primary.subnets_client
63 cls.ports_client = cls.os_primary.ports_client
Dan Smith8ad1c472013-02-26 13:03:16 -050064
Artom Lifshitzb4775942018-09-05 16:24:01 +030065 def _wait_for_validation(self, server, validation_resources):
66 linux_client = remote_client.RemoteClient(
67 self.get_server_ip(server, validation_resources),
68 self.image_ssh_user,
69 self.image_ssh_password,
70 validation_resources['keypair']['private_key'],
71 server=server,
72 servers_client=self.servers_client)
73 linux_client.validate_authentication()
74
zhufl615e63b2018-08-01 17:23:38 +080075 def _create_server_get_interfaces(self):
Artom Lifshitzb4775942018-09-05 16:24:01 +030076 validation_resources = self.get_test_validation_resources(
77 self.os_primary)
78 server = self.create_test_server(
79 validatable=True,
80 validation_resources=validation_resources,
81 wait_until='ACTIVE')
Mark Goddardfa30d2f2019-09-02 14:41:02 +010082 # NOTE(mgoddard): Get detailed server to ensure addresses are present
83 # in fixed IP case.
84 server = self.servers_client.show_server(server['id'])['server']
Artom Lifshitzb4775942018-09-05 16:24:01 +030085 # NOTE(artom) self.create_test_server adds cleanups, but this is
86 # apparently not enough? Add cleanup here.
87 self.addCleanup(self.delete_server, server['id'])
88 self._wait_for_validation(server, validation_resources)
David Sedlák61a3c8e2019-10-30 15:38:21 +010089 try:
90 fip = set([validation_resources['floating_ip']['ip']])
91 except KeyError:
92 fip = ()
zhufl615e63b2018-08-01 17:23:38 +080093 ifs = (self.interfaces_client.list_interfaces(server['id'])
94 ['interfaceAttachments'])
95 body = waiters.wait_for_interface_status(
96 self.interfaces_client, server['id'], ifs[0]['port_id'], 'ACTIVE')
97 ifs[0]['port_state'] = body['port_state']
David Sedlák61a3c8e2019-10-30 15:38:21 +010098 return server, ifs, fip
zhufl615e63b2018-08-01 17:23:38 +080099
100
101class AttachInterfacesTestJSON(AttachInterfacesTestBase):
102
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400103 def wait_for_port_detach(self, port_id):
104 """Waits for the port's device_id to be unset.
105
106 :param port_id: The id of the port being detached.
107 :returns: The final port dict from the show_port response.
108 """
109 port = self.ports_client.show_port(port_id)['port']
110 device_id = port['device_id']
111 start = int(time.time())
112
113 # NOTE(mriedem): Nova updates the port's device_id to '' rather than
114 # None, but it's not contractual so handle Falsey either way.
115 while device_id:
116 time.sleep(self.build_interval)
117 port = self.ports_client.show_port(port_id)['port']
118 device_id = port['device_id']
119
120 timed_out = int(time.time()) - start >= self.build_timeout
121
122 if device_id and timed_out:
123 message = ('Port %s failed to detach (device_id %s) within '
124 'the required time (%s s).' %
125 (port_id, device_id, self.build_timeout))
guo yunxianebb15f22016-11-01 21:03:35 +0800126 raise lib_exc.TimeoutException(message)
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400127
128 return port
129
lianghao16353342017-11-28 21:08:12 +0800130 def _check_interface(self, iface, server_id=None, port_id=None,
131 network_id=None, fixed_ip=None, mac_addr=None):
132 if server_id:
133 iface = waiters.wait_for_interface_status(
134 self.interfaces_client, server_id, iface['port_id'], 'ACTIVE')
Dan Smith8ad1c472013-02-26 13:03:16 -0500135 if port_id:
136 self.assertEqual(iface['port_id'], port_id)
137 if network_id:
138 self.assertEqual(iface['net_id'], network_id)
139 if fixed_ip:
140 self.assertEqual(iface['fixed_ips'][0]['ip_address'], fixed_ip)
venkata anil45375302014-12-30 10:41:43 +0000141 if mac_addr:
142 self.assertEqual(iface['mac_addr'], mac_addr)
Dan Smith8ad1c472013-02-26 13:03:16 -0500143
Dan Smith8ad1c472013-02-26 13:03:16 -0500144 def _test_create_interface(self, server):
lkuchlan87b5a2d2016-09-27 15:46:16 +0300145 iface = (self.interfaces_client.create_interface(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900146 ['interfaceAttachment'])
zhufl7b638332016-11-14 10:23:30 +0800147 iface = waiters.wait_for_interface_status(
148 self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
Dan Smith8ad1c472013-02-26 13:03:16 -0500149 return iface
150
151 def _test_create_interface_by_network_id(self, server, ifs):
152 network_id = ifs[0]['net_id']
lkuchlan87b5a2d2016-09-27 15:46:16 +0300153 iface = self.interfaces_client.create_interface(
ghanshyama2364f12015-08-24 15:45:37 +0900154 server['id'], net_id=network_id)['interfaceAttachment']
lianghao16353342017-11-28 21:08:12 +0800155 self._check_interface(iface, server_id=server['id'],
156 network_id=network_id)
Dan Smith8ad1c472013-02-26 13:03:16 -0500157 return iface
158
Maho Koshiya3fc12462015-12-14 19:03:12 +0900159 def _test_create_interface_by_port_id(self, server, ifs):
160 network_id = ifs[0]['net_id']
Doug Schveninger24675aa2019-08-16 22:28:39 -0500161 port = self.ports_client.create_port(
162 network_id=network_id,
163 name=data_utils.rand_name(self.__class__.__name__))
Maho Koshiya3fc12462015-12-14 19:03:12 +0900164 port_id = port['port']['id']
165 self.addCleanup(self.ports_client.delete_port, port_id)
lkuchlan87b5a2d2016-09-27 15:46:16 +0300166 iface = self.interfaces_client.create_interface(
Maho Koshiya3fc12462015-12-14 19:03:12 +0900167 server['id'], port_id=port_id)['interfaceAttachment']
lianghao16353342017-11-28 21:08:12 +0800168 self._check_interface(iface, server_id=server['id'], port_id=port_id,
169 network_id=network_id)
Maho Koshiya3fc12462015-12-14 19:03:12 +0900170 return iface
171
Maho Koshiya7b629582016-02-22 10:59:01 +0900172 def _test_create_interface_by_fixed_ips(self, server, ifs):
173 network_id = ifs[0]['net_id']
Ryan Tidwell1964a262016-05-04 15:13:23 -0700174 subnet_id = ifs[0]['fixed_ips'][0]['subnet_id']
175 ip_list = net_utils.get_unused_ip_addresses(self.ports_client,
176 self.subnets_client,
177 network_id,
178 subnet_id,
179 1)
Maho Koshiya7b629582016-02-22 10:59:01 +0900180
Ryan Tidwell1964a262016-05-04 15:13:23 -0700181 fixed_ips = [{'ip_address': ip_list[0]}]
lkuchlan87b5a2d2016-09-27 15:46:16 +0300182 iface = self.interfaces_client.create_interface(
Maho Koshiya7b629582016-02-22 10:59:01 +0900183 server['id'], net_id=network_id,
184 fixed_ips=fixed_ips)['interfaceAttachment']
Attila Fazekas3588bb32018-11-04 12:40:27 +0100185 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
186 self.ports_client.delete_port,
187 iface['port_id'])
lianghao16353342017-11-28 21:08:12 +0800188 self._check_interface(iface, server_id=server['id'],
189 fixed_ip=ip_list[0])
Maho Koshiya7b629582016-02-22 10:59:01 +0900190 return iface
191
Dan Smith8ad1c472013-02-26 13:03:16 -0500192 def _test_show_interface(self, server, ifs):
193 iface = ifs[0]
lkuchlan87b5a2d2016-09-27 15:46:16 +0300194 _iface = self.interfaces_client.show_interface(
ghanshyama2364f12015-08-24 15:45:37 +0900195 server['id'], iface['port_id'])['interfaceAttachment']
venkata anil45375302014-12-30 10:41:43 +0000196 self._check_interface(iface, port_id=_iface['port_id'],
197 network_id=_iface['net_id'],
198 fixed_ip=_iface['fixed_ips'][0]['ip_address'],
199 mac_addr=_iface['mac_addr'])
Dan Smith8ad1c472013-02-26 13:03:16 -0500200
201 def _test_delete_interface(self, server, ifs):
202 # NOTE(danms): delete not the first or last, but one in the middle
203 iface = ifs[1]
lkuchlan87b5a2d2016-09-27 15:46:16 +0300204 self.interfaces_client.delete_interface(server['id'], iface['port_id'])
205 _ifs = (self.interfaces_client.list_interfaces(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900206 ['interfaceAttachments'])
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400207 start = int(time.time())
Dan Smith8ad1c472013-02-26 13:03:16 -0500208
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400209 while len(ifs) == len(_ifs):
210 time.sleep(self.build_interval)
lkuchlan87b5a2d2016-09-27 15:46:16 +0300211 _ifs = (self.interfaces_client.list_interfaces(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900212 ['interfaceAttachments'])
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400213 timed_out = int(time.time()) - start >= self.build_timeout
214 if len(ifs) == len(_ifs) and timed_out:
215 message = ('Failed to delete interface within '
216 'the required time: %s sec.' % self.build_timeout)
guo yunxianebb15f22016-11-01 21:03:35 +0800217 raise lib_exc.TimeoutException(message)
Oleg Bondarevee50bb12014-01-16 00:01:34 +0400218
219 self.assertNotIn(iface['port_id'], [i['port_id'] for i in _ifs])
Dan Smith8ad1c472013-02-26 13:03:16 -0500220 return _ifs
221
222 def _compare_iface_list(self, list1, list2):
223 # NOTE(danms): port_state will likely have changed, so just
224 # confirm the port_ids are the same at least
225 list1 = [x['port_id'] for x in list1]
226 list2 = [x['port_id'] for x in list2]
227
228 self.assertEqual(sorted(list1), sorted(list2))
229
Ken'ichi Ohmichi14b0ae12017-01-27 17:18:52 -0800230 @decorators.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
Andrea Frittolicd368412017-08-14 21:37:56 +0100231 @utils.services('network')
zhufl607cfbf2017-12-28 14:55:08 +0800232 def test_create_list_show_delete_interfaces_by_network_port(self):
David Sedlák61a3c8e2019-10-30 15:38:21 +0100233 server, ifs, _ = self._create_server_get_interfaces()
Dan Smith8ad1c472013-02-26 13:03:16 -0500234 interface_count = len(ifs)
zhufl080dcfb2016-10-21 17:45:38 +0800235 self.assertGreater(interface_count, 0)
Dan Smith8ad1c472013-02-26 13:03:16 -0500236
Rohan Kanade9ce97df2013-12-10 18:59:35 +0530237 try:
238 iface = self._test_create_interface(server)
239 except lib_exc.BadRequest as e:
240 msg = ('Multiple possible networks found, use a Network ID to be '
241 'more specific.')
junbolibc2ae862017-07-29 15:46:48 +0800242 if not CONF.compute.fixed_network_name and six.text_type(e) == msg:
Rohan Kanade9ce97df2013-12-10 18:59:35 +0530243 raise
244 else:
245 ifs.append(iface)
Dan Smith8ad1c472013-02-26 13:03:16 -0500246
247 iface = self._test_create_interface_by_network_id(server, ifs)
248 ifs.append(iface)
249
Maho Koshiya3fc12462015-12-14 19:03:12 +0900250 iface = self._test_create_interface_by_port_id(server, ifs)
251 ifs.append(iface)
252
zhufl607cfbf2017-12-28 14:55:08 +0800253 _ifs = (self.interfaces_client.list_interfaces(server['id'])
254 ['interfaceAttachments'])
255 self._compare_iface_list(ifs, _ifs)
256
257 self._test_show_interface(server, ifs)
258
259 _ifs = self._test_delete_interface(server, ifs)
260 self.assertEqual(len(ifs) - 1, len(_ifs))
261
262 @decorators.idempotent_id('d290c06c-f5b3-11e7-8ec8-002293781009')
263 @utils.services('network')
264 def test_create_list_show_delete_interfaces_by_fixed_ip(self):
265 # NOTE(zhufl) By default only project that is admin or network owner
266 # or project with role advsvc is authorised to create interfaces with
267 # fixed-ip, so if we don't create network for each project, do not
268 # test _test_create_interface_by_fixed_ips.
269 if not (CONF.auth.use_dynamic_credentials and
270 CONF.auth.create_isolated_networks and
271 not CONF.network.shared_physical_network):
Matt Riedemann91d92422019-01-29 16:19:49 -0500272 raise self.skipException("Only owner network supports "
273 "creating interface by fixed ip.")
zhufl607cfbf2017-12-28 14:55:08 +0800274
David Sedlák61a3c8e2019-10-30 15:38:21 +0100275 server, ifs, _ = self._create_server_get_interfaces()
zhufl607cfbf2017-12-28 14:55:08 +0800276 interface_count = len(ifs)
277 self.assertGreater(interface_count, 0)
278
Maho Koshiya7b629582016-02-22 10:59:01 +0900279 iface = self._test_create_interface_by_fixed_ips(server, ifs)
280 ifs.append(iface)
281
lkuchlan87b5a2d2016-09-27 15:46:16 +0300282 _ifs = (self.interfaces_client.list_interfaces(server['id'])
ghanshyama2364f12015-08-24 15:45:37 +0900283 ['interfaceAttachments'])
Dan Smith8ad1c472013-02-26 13:03:16 -0500284 self._compare_iface_list(ifs, _ifs)
285
286 self._test_show_interface(server, ifs)
287
288 _ifs = self._test_delete_interface(server, ifs)
289 self.assertEqual(len(ifs) - 1, len(_ifs))
290
Ken'ichi Ohmichi14b0ae12017-01-27 17:18:52 -0800291 @decorators.idempotent_id('2f3a0127-95c7-4977-92d2-bc5aec602fb4')
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400292 def test_reassign_port_between_servers(self):
293 """Tests the following:
294
295 1. Create a port in Neutron.
296 2. Create two servers in Nova.
297 3. Attach the port to the first server.
298 4. Detach the port from the first server.
299 5. Attach the port to the second server.
300 6. Detach the port from the second server.
301 """
302 network = self.get_tenant_network()
303 network_id = network['id']
Doug Schveninger24675aa2019-08-16 22:28:39 -0500304 port = self.ports_client.create_port(
305 network_id=network_id,
306 name=data_utils.rand_name(self.__class__.__name__))
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400307 port_id = port['port']['id']
308 self.addCleanup(self.ports_client.delete_port, port_id)
309
Artom Lifshitzb4775942018-09-05 16:24:01 +0300310 # NOTE(artom) We create two servers one at a time because
311 # create_test_server doesn't support multiple validatable servers.
312 validation_resources = self.get_test_validation_resources(
313 self.os_primary)
314
315 def _create_validatable_server():
316 _, servers = compute.create_test_server(
317 self.os_primary, tenant_network=network,
318 wait_until='ACTIVE', validatable=True,
319 validation_resources=validation_resources)
320 return servers[0]
321
322 servers = [_create_validatable_server(), _create_validatable_server()]
323
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400324 # add our cleanups for the servers since we bypassed the base class
325 for server in servers:
zhufl1355d982017-01-05 12:06:20 +0800326 self.addCleanup(self.delete_server, server['id'])
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400327
328 for server in servers:
Mark Goddardfa30d2f2019-09-02 14:41:02 +0100329 # NOTE(mgoddard): Get detailed server to ensure addresses are
330 # present in fixed IP case.
331 server = self.servers_client.show_server(server['id'])['server']
Artom Lifshitzb4775942018-09-05 16:24:01 +0300332 self._wait_for_validation(server, validation_resources)
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400333 # attach the port to the server
lkuchlan87b5a2d2016-09-27 15:46:16 +0300334 iface = self.interfaces_client.create_interface(
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400335 server['id'], port_id=port_id)['interfaceAttachment']
lianghao16353342017-11-28 21:08:12 +0800336 self._check_interface(iface, server_id=server['id'],
337 port_id=port_id)
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400338
339 # detach the port from the server; this is a cast in the compute
340 # API so we have to poll the port until the device_id is unset.
lkuchlan87b5a2d2016-09-27 15:46:16 +0300341 self.interfaces_client.delete_interface(server['id'], port_id)
Matt Riedemanna8c641a2016-07-12 17:07:33 -0400342 self.wait_for_port_detach(port_id)
zhufl615e63b2018-08-01 17:23:38 +0800343
344
345class AttachInterfacesUnderV243Test(AttachInterfacesTestBase):
346 max_microversion = '2.43'
347
348 @decorators.attr(type='smoke')
349 @decorators.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
350 @utils.services('network')
351 def test_add_remove_fixed_ip(self):
Matthew Treinishc68546f2018-10-12 10:53:45 -0400352 # NOTE(zhufl) By default only project that is admin or network owner
353 # or project with role advsvc is authorised to add interfaces with
354 # fixed-ip, so if we don't create network for each project, do not
355 # test
356 if not (CONF.auth.use_dynamic_credentials and
357 CONF.auth.create_isolated_networks and
358 not CONF.network.shared_physical_network):
359 raise self.skipException("Only owner network supports "
360 "creating interface by fixed ip.")
zhufl615e63b2018-08-01 17:23:38 +0800361 # Add and Remove the fixed IP to server.
David Sedlák61a3c8e2019-10-30 15:38:21 +0100362 server, ifs, fip = self._create_server_get_interfaces()
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400363 original_interface_count = len(ifs) # This is the number of ports.
364 self.assertGreater(original_interface_count, 0)
365 # Get the starting list of IPs on the server.
366 addresses = self.os_primary.servers_client.list_addresses(
367 server['id'])['addresses']
368 # There should be one entry for the single network mapped to a list of
369 # addresses, which at this point should have at least one entry.
370 # Note that we could start with two addresses depending on how tempest
371 # is configured for using floating IPs.
372 self.assertEqual(1, len(addresses), addresses) # number of networks
373 # Keep track of the original addresses so we can know which IP is new.
374 original_ips = [addr['addr'] for addr in list(addresses.values())[0]]
David Sedlák61a3c8e2019-10-30 15:38:21 +0100375 # Make sure the floating IP possibly assigned during
376 # server creation is always present in the set of original ips.
377 original_ips = set(original_ips).union(fip)
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400378 original_ip_count = len(original_ips)
379 self.assertGreater(original_ip_count, 0, addresses) # at least 1
zhufl615e63b2018-08-01 17:23:38 +0800380 network_id = ifs[0]['net_id']
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400381 # Add another fixed IP to the server. This should result in another
382 # fixed IP on the same network (and same port since we only have one
383 # port).
zhufl615e63b2018-08-01 17:23:38 +0800384 self.servers_client.add_fixed_ip(server['id'], networkId=network_id)
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400385
David Sedlák61a3c8e2019-10-30 15:38:21 +0100386 def _wait_for_ip_change(expected_count):
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400387 _addresses = self.os_primary.servers_client.list_addresses(
388 server['id'])['addresses']
David Sedlák61a3c8e2019-10-30 15:38:21 +0100389 _ips = set([addr['addr'] for addr in list(_addresses.values())[0]])
390 # Make sure possible floating ip is always present in the set.
391 _ips = _ips.union(fip)
392 LOG.debug("Wait for change of IPs. All IPs still associated to "
Slawek Kaplonskib3daeb42019-06-29 23:49:59 +0200393 "the server %(id)s: %(ips)s",
394 {'id': server['id'], 'ips': _ips})
David Sedlák61a3c8e2019-10-30 15:38:21 +0100395 return len(_ips) == expected_count
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400396
David Sedlák61a3c8e2019-10-30 15:38:21 +0100397 # Wait for the ips count to increase by one.
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400398 if not test_utils.call_until_true(
David Sedlák61a3c8e2019-10-30 15:38:21 +0100399 _wait_for_ip_change, CONF.compute.build_timeout,
400 CONF.compute.build_interval, original_ip_count + 1):
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400401 raise lib_exc.TimeoutException(
402 'Timed out while waiting for IP count to increase.')
403
404 # Remove the fixed IP that we just added.
zhufl615e63b2018-08-01 17:23:38 +0800405 server_detail = self.os_primary.servers_client.show_server(
406 server['id'])['server']
407 # Get the Fixed IP from server.
408 fixed_ip = None
409 for ip_set in server_detail['addresses']:
410 for ip in server_detail['addresses'][ip_set]:
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400411 if (ip['OS-EXT-IPS:type'] == 'fixed' and
412 ip['addr'] not in original_ips):
zhufl615e63b2018-08-01 17:23:38 +0800413 fixed_ip = ip['addr']
414 break
415 if fixed_ip is not None:
416 break
417 self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip)
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400418 # Wait for the interface count to decrease by one.
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400419 if not test_utils.call_until_true(
David Sedlák61a3c8e2019-10-30 15:38:21 +0100420 _wait_for_ip_change, CONF.compute.build_timeout,
421 CONF.compute.build_interval, original_ip_count):
Matt Riedemannd4cb10f2018-09-26 13:03:08 -0400422 raise lib_exc.TimeoutException(
423 'Timed out while waiting for IP count to decrease.')